Commit | Line | Data |
bfd90409 |
1 | #!/usr/bin/env perl |
2 | # |
3 | # testgfxroto.pl |
4 | # |
5 | # Copyright (C) 2005 David J. Goehrig <dgoehrig@cpan.org> |
6 | # |
7 | # ------------------------------------------------------------------------------ |
8 | # |
9 | # This library is free software; you can redistribute it and/or |
10 | # modify it under the terms of the GNU Lesser General Public |
11 | # License as published by the Free Software Foundation; either |
12 | # version 2.1 of the License, or (at your option) any later version. |
13 | # |
14 | # This library is distributed in the hope that it will be useful, |
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | # Lesser General Public License for more details. |
18 | # |
19 | # You should have received a copy of the GNU Lesser General Public |
20 | # License along with this library; if not, write to the Free Software |
21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 | # |
23 | # ------------------------------------------------------------------------------ |
24 | # |
25 | # Please feel free to send questions, suggestions or improvements to: |
26 | # |
27 | # David J. Goehrig |
28 | # dgoehrig@cpan.org |
29 | # |
30 | |
31 | use strict; |
32 | use Getopt::Long; |
33 | use Data::Dumper; |
34 | use MIME::Base64 qw(decode_base64); |
35 | |
36 | use SDL; |
37 | use SDL::App; |
38 | use SDL::Event; |
39 | use SDL::Surface; |
40 | use SDL::Color; |
41 | use SDL::Rect; |
42 | use SDL::Config; |
43 | |
44 | use vars qw/ $app $app_rect $background $event $sprite $sprite_rect $videoflags /; |
45 | |
46 | ## Test for SDL_gfx support |
47 | |
48 | die "Your system was not configured with SDL_gfx support!\n" |
49 | unless SDL::Config->has('SDL_gfx'); |
50 | |
51 | |
52 | ## User tweakable settings (via cmd-line) |
53 | my %settings = ( |
54 | 'numsprites' => 10, |
55 | 'screen_width' => 200, |
56 | 'screen_height' => 200, |
57 | 'video_bpp' => 8, |
58 | 'fast' => 0, |
59 | 'hw' => 0, |
60 | 'flip' => 1, |
61 | 'fullscreen' => 0, |
62 | 'bpp' => undef, |
63 | ); |
64 | |
65 | ## Process commandline arguments |
66 | |
67 | sub get_cmd_args |
68 | { |
69 | GetOptions("width:i" => \$settings{screen_width}, |
70 | "height:i" => \$settings{screen_height}, |
71 | "bpp:i" => \$settings{bpp}, |
72 | "fast!" => \$settings{fast}, |
73 | "hw!" => \$settings{hw}, |
74 | "flip!" => \$settings{flip}, |
75 | "fullscreen!" => \$settings{fullscreen}, |
76 | "numsprites=i" => \$settings{numsprites}, |
77 | ); |
78 | } |
79 | |
80 | ## Initialize application options |
81 | |
82 | sub set_app_args |
83 | { |
84 | $settings{bpp} ||= 8; # default to 8 bits per pix |
85 | |
86 | $videoflags |= SDL_HWACCEL if $settings{hw}; |
87 | $videoflags |= SDL_DOUBLEBUF if $settings{flip}; |
88 | $videoflags |= SDL_FULLSCREEN if $settings{fullscreen}; |
89 | } |
90 | |
91 | ## Setup |
92 | |
93 | sub init_game_context |
94 | { |
95 | $app = new SDL::App ( |
96 | -width => $settings{screen_width}, |
97 | -height=> $settings{screen_height}, |
98 | -title => "testsprite", |
99 | -flags => $videoflags, |
100 | ); |
101 | |
102 | $app_rect= new SDL::Rect( |
103 | -height => $settings{screen_height}, |
104 | -width => $settings{screen_width}, |
105 | ); |
106 | |
107 | $background = $SDL::Color::black; |
108 | |
109 | $sprite = new SDL::Surface -name =>"/tmp/spiral.png"; |
110 | |
111 | $sprite->display_format(); |
112 | |
113 | SDL::SetColorKey($$sprite, SDL_SRCCOLORKEY, SDL::SurfacePixel($$sprite,0,0)); |
114 | |
115 | $sprite_rect = new SDL::Rect(-x => 0, |
116 | -y => 0, |
117 | -width => $sprite->width, |
118 | -height=> $sprite->height, |
119 | ); |
120 | |
121 | $event = new SDL::Event(); |
122 | } |
123 | |
124 | ## Prints diagnostics |
125 | |
126 | sub instruments |
127 | { |
128 | if ( ($app->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { |
129 | printf("Screen is in video memory\n"); |
130 | } else { |
131 | printf("Screen is in system memory\n"); |
132 | } |
133 | |
134 | if ( ($app->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { |
135 | printf("Screen has double-buffering enabled\n"); |
136 | } |
137 | |
138 | if ( ($sprite->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { |
139 | printf("Sprite is in video memory\n"); |
140 | } else { |
141 | printf("Sprite is in system memory\n"); |
142 | } |
143 | |
144 | # Run a sample blit to trigger blit (if posssible) |
145 | # acceleration before the check just after |
146 | put_sprite_rotated($sprite, |
147 | $settings{screen_width}/2, $settings{screen_height}/2, |
148 | 0,0,0); |
149 | |
150 | if ( ($sprite->flags & SDL_HWACCEL) == SDL_HWACCEL ) { |
151 | printf("Sprite blit uses hardware acceleration\n"); |
152 | } |
153 | if ( ($sprite->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { |
154 | printf("Sprite blit uses RLE acceleration\n"); |
155 | } |
156 | |
157 | } |
158 | |
159 | |
160 | |
161 | |
162 | # this can get silly in terms of |
163 | # memory usage, and maybe key lookup. |
164 | # it would be better to 'tie' the hash |
165 | # to an object which can |
166 | # better manage memory usage. |
167 | |
168 | my %rotate_cache =(); |
169 | |
170 | sub generate_sprite_rotated |
171 | { |
172 | my ($surface, $angle, $zoom, $smooth) = @_; |
173 | |
174 | $angle %= 360; |
175 | my $key = "$surface$angle$zoom$smooth"; |
176 | |
177 | if ( $rotate_cache{$key} ) |
178 | { |
179 | return $rotate_cache{$key}; |
180 | } |
181 | else |
182 | { |
183 | my $sur = SDL::GFXRotoZoom($surface, $angle, $zoom, $smooth); |
184 | |
185 | $rotate_cache{$key}= SDL::DisplayFormat($sur); |
186 | } |
187 | return $rotate_cache{$key}; |
188 | } |
189 | |
190 | sub put_sprite_rotated |
191 | { |
192 | my ($surface, $x, $y, $angle, $zoom, $smooth) = @_; |
193 | |
194 | my $roto = generate_sprite_rotated($$surface, $angle, $zoom, $smooth); |
195 | |
196 | die "Failed to create rotozoom surface" unless $roto; |
197 | |
198 | my ($w,$h) = (SDL::SurfaceW($roto),SDL::SurfaceH($roto));; |
199 | |
200 | |
201 | my $dest_rect = new SDL::Rect |
202 | -x => $x - ($w/2), |
203 | -y => $y - ($h/2), |
204 | -width => $w, |
205 | -height => $h; |
206 | |
207 | |
208 | SDL::BlitSurface($roto, 0, $$app, $$dest_rect); |
209 | } |
210 | |
211 | |
212 | sub game_loop |
213 | { |
214 | my $ox=$settings{screen_width}>>1;; |
215 | my $oy=$settings{screen_height}>>1; |
216 | my $sectors = 12; |
217 | my $angleDelta = 360/$sectors;; |
218 | my $zoom = 1; |
219 | my $smooth =1; |
220 | |
221 | my $angle =0; |
222 | my $radius =128; |
223 | |
224 | FRAME: |
225 | while (1) |
226 | { |
227 | # process event queue |
228 | $event->pump; |
229 | if ($event->poll) |
230 | { |
231 | my $etype=$event->type(); |
232 | |
233 | # handle quit events |
234 | last FRAME if ($etype == SDL_QUIT() ); |
235 | last FRAME if (SDL::GetKeyState(SDLK_ESCAPE)); |
236 | } |
237 | |
238 | # needed for HW surface locking |
239 | #$app->lock() if $app->lockp(); |
240 | #$app->unlock(); |
241 | $app->flip if $settings{flip}; |
242 | |
243 | ################################################ |
244 | # do some drawing |
245 | |
246 | $app->fill($app_rect, $background); |
247 | |
248 | $angle += 16; |
249 | |
250 | put_sprite_rotated($sprite, |
251 | $settings{screen_width}/2, $settings{screen_height}/2, |
252 | $angle, $zoom, $smooth); |
253 | |
254 | } |
255 | print "Cache entries: " . scalar(keys %rotate_cache) . "\n"; |
256 | } |
257 | |
258 | |
259 | |
260 | ## Main program loop |
261 | |
262 | write_spiral(); |
263 | get_cmd_args(); |
264 | set_app_args(); |
265 | init_game_context(); |
266 | instruments(); |
267 | game_loop(); |
268 | exit(0); |
269 | |
270 | sub write_spiral { |
271 | my $png = decode_base64 <<EOF; |
272 | iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABHNCSVQICAgIfAhkiAAAABl0RVh0 |
273 | U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABpHSURBVHic7V15dFRVmv+92hNSy7v3vaqs |
274 | hCgEEggQFmVTQFnsoAiiTHc7R3GbhnZsmsGenkb0tHYPzTACikRRaDcQaVxaZRja1sbGsVtAyEIM |
275 | CS2ETZYktWSpLLXe+SPBQ9NUUlXv1hLgd853Doe677u/73tf7rvv3vu+T2CM4RquXqgSTeAaEotr |
276 | AXCV41oAXOW4FgBXOa4FwFWOawFwlUOTaAKxgCAIOgC5AAYIgpAny/IwnU6XJwhCCgAdY0zLGNMx |
277 | xnSCIHSqVKqGQCBwrq2t7dvm5uZvATQAOAzgGLvC35OFvm6fIAhqAMO1Wu0kWZZLPB5PscFg0OXm |
278 | 5gby8/O1Q4YMSbvuuuvU2dnZMBgM0Ol00Gq10Ol00Ol06OjogN1uR2NjI+x2O+rr6wOnTp1qP3Dg |
279 | gLeurk6tVqvtarW6vLGx8XOfz/cXABVXUlD0yQAQBEHW6/X3WCyWhwOBQO6IESMCM2bMsEyaNEk7 |
280 | evRo6PV6bn3V19ejsrIS5eXlgZ07dzZ9/fXX0Ov1n58/f/4tAJ8wxlq4dZYA9JkAEARB0mq1dxNC |
281 | /iUlJaX//fffn/rDH/4wJT8/P648PB4P9uzZg9///vetO3bs8Pt8vtMOh2N1IBB4hzHWEVcyPMAY |
282 | S2oBcIMsy5/m5OQ4li9f3lZTU8OSCdXV1WzhwoUthBAnpfRVAEUsCfwWriScQEhiwG2yLFeMHj3a |
283 | 8Yc//CHiGxNvdHZ2si1btgRHjhzpkCSpRqVSfY8lgR97k4QTuFR0Ot3dkiQdnzVrluvAgQNR3YxE |
284 | o6qqik2fPt0lSVIVgJtYEvg1lCScwHdEgAJK6VclJSWuurq6qJ2fTNi/fz+78cYbnbIs7wUwmiWB |
285 | ny+VxBMAjJTSlwYMGOD805/+pMjhyYrdu3ezwsJClyRJmwGksSS48RckoZ3r9fo7KKUNq1at6vT5 |
286 | fEr9nNQIBoNszZo1nZTSsyqVajpLgpvPEhUAADSU0tKRI0e6Tp8+zcG9fQdHjx5lo0aNckmS9DsA |
287 | Jna1BQCAHEpp1dKlS91+v5+PV/sYgsEgW7t2rYcQch7AWHa1BIBer7/DarU27tq1K8jLmX0ZNTU1 |
288 | rH///s5+/fotYFd6ABiNxqVDhw51nTlzhp8HrwA4nU42fvx4FyHkRQAqdiUGgCiK/zVp0qSmtrY2 |
289 | rs67UuD3+9nChQtbCSF/AWBhV0oAABAopa/Onj272ev18vbbFYeNGzd6RFE8CoCyvh4A3TP9Dx96 |
290 | 6KGWQCDA31tXKLZu3eoTRfFvAETWlwNAkqTtS5cuvTbmR4E333zTK4pibTweBzFRSghZcffddzfH |
291 | xDtXCX772996RFGsjvVaAffzACaT6YEhQ4as/eKLL8w6nY6r7mjR1taGyspK2O12qNVqqNVqaDSa |
292 | 7/6tVquh1WoxZMgQmEymRNP9Di+//LL3F7/4xRGXyzWBMeaORR9cA0CtVk/Nzc19v6yszGKxWLjp |
293 | jQQOhwPl5eU4ePCg/4svvmipqKgQPB5Pm8FgOOT3+08LgqC5IAC0ADTdx8pSOjs7Cw0GQ78JEyZg |
294 | 6tSplvHjxwtDhw6FWq1OiC0A8Pzzz3ueeeaZfU6ncwrj/dcK8HsEAMi3Wq2OROzk1dfXs6effroz |
295 | MzPTabVaj2dmZr6r1+sfBXADAEOEdqQBmGo0Gn+ZmZn5hSiK9hEjRjT++te/bnc4HHG3jTHG7r33 |
296 | 3haLxbIiEjvCFV43X0sprd27d28s/fAP+PLLL9ncuXObJEk6YzKZfo4YTZoA5KalpS0jhJy77777 |
297 | mg4fPhxXOzs7O1lBQUGTRqPhfsiEixJCyHPLly93x9QL3Whvb2ebNm0K5OfnOzMyMv4KYCa6H2Wx |
298 | FgBqlUp1jyzL1ePGjXPs2rWLBYPxWdU+ceIEkyTJAWAAV5sUKwBuKioqcsRjY+ftt98OWK1Wp9Vq |
299 | LeXtiCjsHmOz2Xb279/fuXHjxrjsZe/atStICPlbpI+1Hu1QdDFgkiTpzNGjR2NqeFNTE5s3b16L |
300 | 1WrdA0DmZTwPAZApy/IHN910U/P58+dj6gfGGHvyySc7JEl6mxt/JRdLkvTWSy+9FNM13j//+c8s |
301 | KyvLabFYfszL6FhISkrK961Wq+PDDz+M6TMhGAyyoqKiJgBTePBWEvlFgwcPdsTqGejxeNhPf/pT |
302 | tyzL1QCu42FsrAVAtiRJBxcsWNAay42vyspKJoriaXR95paYAJAkaf+ePXtiYmBtbS3Lz893Ukr/ |
303 | E4BaqZHxFACCKIpPDBgwwFlWVhYT/zDG2OLFi9t4vBpGdZFKpbp9+vTpzlgYVldXx9LT050Axik1 |
304 | LpECYASl9PimTZti8oh0u90sPT29CcAgRTyjMExDCDn1zTffcDfq3LlzLCcnx6VWqycrMSpZBICJ |
305 | EPL1hg0bPLx9xRhjH374YZBSekARx0gv0Gg0Dz7yyCPcN3pcLhcbNGiQKyUl5U4lBiWbADASQipe |
306 | fPHFTs4uY4wxNnPmzGaNRjMvan6RXkApPX7y5EmuRrS3t7ORI0c2GY3GB6I1JJkFQD9CyMEXX3yx |
307 | g6vjGGPHjh1jkiTVRbsYFqkh00pKSrg++30+H5s8eXKTKIr/Ho0BfUUApBJCaj/++GPur03z5s1r |
308 | UqlUUY2cETW22Wx79+3bx5X8XXfd1UwI+e9oyPc1AZAlSdJ53l8419bWMlmW/xYVpwjIFwwfPpzr |
309 | dti2bdv8siz/TzTE+6oAGNO/f3+n3W7n5MUu3H777S6VSlUSMZ9wG1qt1jfeeecdbsOX2+1mGRkZ |
310 | jQCskZLu69KvX78HZ82a1cTHk12oqqpisizXRMol3KhVUUobOzv5TWR/8pOftJrN5scjJXylCKW0 |
311 | nPfHsNOnT3dFukQcbgDcMmfOHG6Tv8OHDzNJko4mYpUPgAEAAZAN4Hoey6lR8hiWm5vr4nlc/tNP |
312 | P2VZWVk7I+IRTiObzbZtx44d3IiOGTPGAWBiJESjke7TPTMIIWttNtthQkhz//79nYMGDbIXFRU1 |
313 | jhkzpjErK8spSdLZrKyszyVJWg1gQqx5XRBK6SsrV67kNqwGAoELq6hhf4IejhM1hBCHx8NnMWvr |
314 | 1q0+WZY/CJdgNAIgR5KkVzMzM+3333+/66233mInTpwIyamzs5OVl5ezzZs3s+nTpzslSfrWbDY/ |
315 | BSAjxjxNhJCGs2fPKvLpxVi6dGm7wWB4KGwOYZDkNvwHg0GWlZXlAGALl2AkAuB6WZbfzcvLs2/Z |
316 | ssUf7SGVxsZGtmbNGk9eXp6DUro1VkfNGGMwGAz3z5kzh9vKam1tLbPZbIfC7b/XBikpKU+WlpZy |
317 | +bTn888/Zzab7Q/hkotEDAbDPZmZmfYPPvggyGuLOhgMshdeeMFDKa3XarX/FAvejDFQSg/x3Fkt |
318 | KCiwh3tiqtcGGRkZu3kt/syfP98J4LZwiIUrANSU0hfGjRvn4v1ufQFnz55lJSUlTkmSdgNI5cm/ |
319 | 24bh1113nYvXsbr169f7zGbzf4bVd28NCCH1HR3Kl7Db2toYIaSB58wfgIFSum/JkiWt8fj+8JVX |
320 | XumklJZHMskKV6xW64e7du3iwtPhcDBJkk6F029vDrYMGDCAy+rfG2+8ESCEvBgOqXBFkqT3V65c |
321 | 2c6DX7h47bXXPISQQ+D8yRaAW3m+aufn59vDWWTrjdQt8+fP50Jq1KhRdnDMommxWH7Gc/IUCTZv |
322 | 3uwhhFTznBwCUBFCGnkdJVuyZIkbQK/zlh5/TE1NXbZ+/XrFY+vJkycZpbSuNzLhikqlmpqfn+9K |
323 | ZMKJbdu2eUVRrAKgCYdzOCJJ0stbtmzhMoP94x//yNLT03/XW589/piZmflHHl/7bNq0KZiamvqr |
324 | 3siEIwBSRFFsTIZkkosXL242mUxPMX6jwKiJEydymcm2t7czSZLO9tpnTz9SSs/xmAA+8sgjLgB3 |
325 | 9EYmHDEajT9fsmRJUuQd6OjoYNnZ2Q4A+YxTEBBCvm1oaODCb/jw4Q0AcnrqL2TJGEEQTEajUWcw |
326 | GEI1CRv79+/3ATikVI8gCKlarfbx5cuXpyomxQEGgwGbN28WKaXbBUEQeOj0+/2vv/322z4euu68 |
327 | 885+giDc0lObnmoGjRw7diwXo06fPq1mjJ1UqsdgMDzw8MMPpxJCeNDigilTpgglJSV5RqPxX3no |
328 | a2lpeXXDhg1cilBMnDgxNT09fUZPbXoKgILi4mKjUhLnzp2DRqM5r1QPAFgslgUPPvhgUvz1X4zn |
329 | n3/epNfrl/EYBRhjdXa73XHypOK/FwwePBgAhvXUpqcA0BsMBsWZEQ4dOgRBEMqU6hEEwajRaPK6 |
330 | jUoqiKKIm2++2QBgGg99KpXqrxUVFYr15ObmwuPxZPbYV6gftFqtQa/XK47osrIyb0NDw/8p1QNg |
331 | 5ty5c5Mj58xlsHjxYkt6evp/8NDV2Ni4t6qqyq9UjyAIMJlMgiAIIUfyngJAzyPHT2VlpZsxdlSp |
332 | HovFMmHixImKH0mxws033wyNRlMsCIJNqa5gMFhdVlbWyoNXYWEhAzAk1O89jgBarVYxAa/XCwCK |
333 | ozklJaUgLy9PMZ9YYtGiRf2MRuMjHFQdrqqq4pIPaNSoUamIJgA0Go2BxwjAuhY4FBsTCATyeAdA |
334 | ZWXlBX5ccO+99+rS0tLmKNXDGHM6nU4u3IqKilLNZnNxqN9DBoBarebyCOAVAH6/3yLLsmI+F2Pt |
335 | 2rWt2dnZDatXr14M4DEAqwG8B6AMgDNSfbm5ufD7/f15cNPr9ee+/fZbxXqysrKQmpoacuYcsnSs |
336 | SqXiNQIwcAgAlUrl83q94Jl78PXXXzcePnzYOG3atCcff/zxGYyx9Zc0MQEY0C15l/m3+VKd2dnZ |
337 | TBCEbMaYorunUqmqampqhubk5ChRg7S0NAiCEDL5YU8BwGUECAaDAIcA0Gg0bS0tLZAkSTGni1FY |
338 | WIht27ZJ8+bNewnAuEt+bkHXCmaoVUwRlwTFwIEDb7JarXMBvA4g6omc0+ncW11dPX/GjBmKCnyb |
339 | TCYwxkJOnkMGgCAIumR6BKjVandzczP3AAC6ZvDZ2dn5giCMYYwdiOBSV7eUX/iPd99994fLli17 |
340 | FcA6AA4AJ3qQkNk/Ozo6aqqrq93oGoWihtFoRCAQSAv1e08BwGUEUKvVAvhMAmtra2tHX3/99Yo5 |
341 | XQ4rV64UFyxYsAJAj0unvYExVldTU9MGQA+AdsvoEM1DBkhOTo6OxyTQZDIhEAiEXD0NObx0bXYp |
342 | L4VbVFTUD8B1SvWcP3/+fz777LN2xYRCYNKkSQgEAjyWGf2BQCDctheCYx6ApQBeALADQNUrr7yy |
343 | Y/fu3TsBjAVwD4CfASgFsBNANYC2cDrQ6XRgjIV8nw85AjgcjoNHjhz5p2nTpilaDSwuLtbbbLaJ |
344 | ALYq0QPgL5988kkHgJjsBfTr1w/BYDCFg6qA3+/n8dYDt9vdCuBAt1wOEv5+cnqppAKAWq0O/bof |
345 | 6ofOzs6vy8vLW3CZmW4kKCoqgkajGaNEBwAwxk5LkuRpaGiA1WpVqu6y0Gg0PLJCByIYAULC5/Mh |
346 | GAz2toBm75avQvwuAxgwduzYkP7vaYZ5pLKyUvG+9MCBA+HxeAYo1QMAHo9nzbp162JSoj0QCMDr |
347 | 9SqacV9QxWsEYIwp9X8jgK927tz5UqgGPRl88tSpU4r/IlQqFcxms7qnd9Fw4Xa7X964cWN79/Iy |
348 | Vxw4cAAGg6GKgyqhWxShewTgcjCkJ/Q0CQwGAoH29nbl867i4mIAKFKqhzHmDgaDW5999tlOxaQu |
349 | wa5du7wOh+MdDqquLygo0CtV4vf7ExsAAKDX648eOXJEcSc33nijSafT3aBYEQC73f7z1atXn923 |
350 | bx8PdQC6Fqu2bNnS5vV6dyrVZTKZRhYXF4d87w4X3QGgeBOtN/QYAJ2dnWU8AmD27Nlas9n8I8WK |
351 | 0PV66nQ6Z82bN8/Z1NTEQyXWr1/f2dzc/B5jrE6pLqPReGNhYaFiTh6PBz6fL6xXPSXoMQCcTmd5 |
352 | VVWV4klXfn4+ZFmWBUHIV6oLABhjta2trYsnTJjgOnv2rCJdNTU1ePrpp112u/3feHDz+XxDCgoK |
353 | FOspLy9v8Xq9ig/S9oqejgwDuOG2225r5HFEubS01C+K4tqe+otUtFrtjMzMTHt5eXlUnCoqKpjV |
354 | aq0HMJIHHwAqq9XK5Vz/sGHDGgGk8+DVI+deDDLn5uZy+TbQ5XIxURQbwLk+LoACQsiZBx54oKWq |
355 | qiosLl6vl61ataqzu3r3UI5cbrn99tsV+ysYDDJJkhp58eqRc28NJEk61dzM5xO8kpISJ4Bp3I0A |
356 | 9Gq1+p9lWa4eMWKEY9u2bcHL5d6pqqpiv/zlLzuys7MdhJBScP7A02q1/u6jjz5S7KdvvvmGZWZm |
357 | KsoBHLbvemtAKX1p+/btio1ijLGdO3cyq9W6I6YGAUWSJL0piuI5URTPXyzp6elfdVcT4576BV2F |
358 | s7ik0tm+fTuTZXldLP30He8wDJs8d+5cLo8Bv9/PMjIyXAD6x8O4eAqAWT/4wQ9cPPy0dOnSNgD3 |
359 | xIV3GIZpKKUOXgkY3nvvvaAsy3+Oh3HxFJvN9r+88v6NGzeuEcDAePDude2bMebX6XTle/fu5fHS |
360 | gbvuuksYOnToSK1WO5uLwiSAIAhDUlNTx02ZMoWLvmPHjqkBHOOirBeEtfnR0NCwccuWLdxq1772 |
361 | 2mtms9n8siAISfeZVzSQJOm3GzZssKhUyveSTpw4AZVKdZ4xxr9M7OUQzjABQGu1Wht4por91a9+ |
362 | 1UEpjctEJ5YC4LbJkydzS+3y1FNPdaSmpv4sbvzDbWi1Wks3b97MLROT1+tleXl5TgAF8TKWu/O6 |
363 | kmieOHLkCBefBIPBC5NkGjcbIjD2+hEjRnDNw7Znzx5GCDkKwBwvg3lKWlrasoULF7bw8sfu3buZ |
364 | zWb7JJ42RNQ4IyOjjHexg02bNvkIIV8jBqnXYikGg2FuYWGhy+3mVzL5zjvvdAGYEU87Imqs0Wjm |
365 | ff/73+eemWvdunUeSulBcKyJG0sBMC4nJ8fJK5ULY13lcSml9eC8VN6rLREaLlBKj/N65l2MFStW |
366 | dFBK/4IEpW+PwAeDbDZbA++yeaWlpT5CyH/F3Z5IL9BoNHPuuOMOrtUuLuCJJ55olyTpUyRptVAA |
367 | Vkrpt7zrJjHG2ODBgx1IwAppVBdJkvS3yspK7k5grKskqiRJnyTbxBBAAaX0+I4dO7jnpD106BDL |
368 | yMiIy+bPP9gVzUUqleq2qVOnxmQUYIyx9evXeyml9RqN5nuJcMqlYjKZHs3Oznbu378/Jvbecsst |
369 | TRqN5vZE2Bb1hbIs749lqfRjx46x4uLiJkrpNgDGeDuGsa5cyZIkfTJ79uwmXlvil+L9998PyrK8 |
370 | JxH2MSUBAGBAenq6K1aOYayrBMqqVas6RVE8H/fXI2AmIeTcxo0bY1L8mTHGWltbL5R46TGZY0zt |
371 | VHKx2Wxeet9997XGxDsXoba2lk2ePNlBKT2q0+keAZDC0wkXBIBeo9E8RCmtmz59up33mselWLRo |
372 | kdtisfwiFraEbbOii7teC6s+++yzGLjnH1FXV8cee+yxVkqpgxCyAZy2TAFYzWbzSkJI449//OOW |
373 | 48ePx9yWgwcPMkppQiqn/Z3tihUA+Tk5OY7W1pgPBN+hvb2dbdy40T9o0CCHLMt1GRkZ21Uq1UIA |
374 | Y3pbR0DXVzuDAPwgIyPj1YyMjJrc3Fz7mjVrPC0t3FZ1e0QgEGAFBQUuAGN74hoPERhTvutoNBof |
375 | Gz9+/DMff/yxhVPK3LDR1NSEsrIy7N+/37tnz56WyspKlc/na1Wr1e5uLt8l8GSMabxerzU/Pz8w |
376 | derUfhMnTjTccMMN4J17qDc899xz3hUrVrzd0NCwIK4dXwZcAgAAKKVbfvSjH81ZsWJFPy4KFaC1 |
377 | tRVtbf/4TYVKpYrZl8Xh4syZMxg5cmSj3W6/njHGJRegIvAaSgBoRVGseOedd/hUProC0d7ezgoL |
378 | C116vT7iIs+xEr7KABsh5FxFRQVXx10JCAaDbObMmU1ms/nfWRLc+AvCXyEwQpIke6yWivsqFi9e |
379 | 3EoIeZMlwU2/WGKjFBglSZLj2kjQhfXr13tEUfwSHOsL8ZLYKe4Ogmi/27tS8Oyzz3aIolgJzl8h |
380 | 8ZLYKgdGUUodsdg+7QtYtmxZmyiKf0UMqo3ykth3AAwjhJx54403fDyc2hcQDAbZokWLWgkhHyPZ |
381 | D7jEpRNApJTuffTRR1t51cdNVrhcLjZt2rQmSulbSNKDLRdL/DoC1ISQl8aPHx+zIs+JxsGDB1l2 |
382 | drYzLS3tYZYENzcciXuHKSkp98qy3Lht27Yr6pFQWlrqIYScBsfyuPGQxHQK2CRJ+njatGnOs2fP |
383 | Ru/1JEBtbS0bP368y2q17kjWmX5PktDOdTrdXKvVeu43v/lNRywPlsQCbrebLVmyxE0pPQlgCkuC |
384 | mxmNJJ4AYDSbzU/Isnxu0aJFLSdOnIjmfsQNLpeLrV692muz2Zxms/kpAFqWBDcyWkk4ge+IABq9 |
385 | Xn+fJEnHZs2a5YjVAcxosW/fPjZ//vwmQkiDxWJZiRhkGUmEJJzAZUkBt1qt1n3Dhw+3f/DBB0Fe |
386 | ySkihdvtZhs2bPAPHDjQYbPZ9gKY3Rde7SIRbucBYgFBEIZJkvSMTqebPGfOHPWtt95qnjBhAtLT |
387 | 02PWJ2MMlZWVWLduXetHH33kYYy95XQ6n2OMnYhZpwlEUgfABQiCIAO4iRAyTaPR3CIIgjxmzJjg |
388 | jBkzxEmTJqmHDx8OjSZk5vuQaG9vR1VVFSoqKoJffvll81dffRWor68XdDrd0YaGhjWBQOD3THnG |
389 | 7qRGnwiASyEIgg7AKIPBcBMh5HudnZ3DcnJyhNzcXEGv118sKr1eLxgMBpVer1cbDAaV2+327du3 |
390 | r626ulrt8Xg6dDpdVVNT0/91dHQcBFDJGKtPtH3xRJ8MgMtBEIQcAFYAul7EC+BrAIcZY57EsE0e |
391 | XDEBcA3RgUeFjGvow7gWAFc5rgXAVY5rAXCV41oAXOX4f6hNaqv7twhpAAAAAElFTkSuQmCC |
392 | EOF |
393 | open FP, "> /tmp/spiral.png"; |
394 | print FP $png; |
395 | close FP; |
396 | } |