sdk-world v2026.11.05
PS2 SDK - world tier (copyleft-allowed, non-essential packages)
Loading...
Searching...
No Matches
aasave.c
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4#include "aalib.h"
5
6#define NORMALPRINTS { "%s", "%s", "%s", "%s", "%s", }
7#define NONE { "", "", "", "", "", }
8
9static char *html_escapes[] =
10{"<", "&lt;", ">", "&gt;", "&", "&amp;", NULL};
11static char *html_alt_escapes[] =
12{"<", "&lt;", ">", "&gt;", "&", "&amp;", "\"", "&quot;", NULL};
13#ifdef VYHEN_SUPPORT
14static char *vyhen_escapes[] =
15{"|", "||","~", "~~", NULL};
16#endif
17
18static char *irc_escapes[] =
19{"@", "@@", NULL};
20
21static char *generate_filename(char *template, char *result, int x, int y, int pages, char *extension);
22
23struct aa_format aa_nhtml_format =
24{
25 79, 36,
26 79, 36,
27 0,
28 AA_NORMAL_MASK | AA_BOLD_MASK | AA_BOLDFONT_MASK | AA_DIM_MASK,
29 &aa_fontcourier,
30 "Nestcapeized html",
31 ".html",
32 "<HTML>\n<HEAD><TITLE>Ascii arted image done using aalib</TITLE>\n</HEAD>\n<BODY BGCOLOR=\"#000000\" TEXT=\"#b2b2b2\" LINK=\"#FFFFFF\">\n<FONT COLOR=#b2b2b2 SIZE=2><PRE>\n",
33 "</PRE></FONT></BODY>\n</HTML>\n",
34 "\n",
35 NORMALPRINTS,
36 {"",
37 "<FONT COLOR=\"686868\">",
38 "<FONT COLOR=\"ffffff\">",
39 "",
40 "<B>"
41 },
42 {"",
43 "</FONT>",
44 "</FONT>",
45 "",
46 "</B>"
47 },
48 html_escapes
49};
50struct aa_format aa_html_format =
51{
52 79, 25,
53 79, 25,
54 0,
55 AA_NORMAL_MASK | AA_BOLD_MASK | AA_BOLDFONT_MASK,
56 NULL,
57 "Pure html",
58 ".html",
59 "<HTML>\n <HEAD> <TITLE>Ascii arted image done using aalib</TITLE>\n</HEAD>\n<BODY><PRE>\n",
60 "</PRE></BODY>\n</HTML>\n",
61 "\n",
62 NORMALPRINTS,
63 {"",
64 "",
65 "<B>",
66 "",
67 "<B>"
68 },
69 {"",
70 "",
71 "</B>",
72 "",
73 "</B>"
74 },
75 html_escapes
76};
77struct aa_format aa_ansi_format =
78{
79 80, 25,
80 80, 25,
81 0,
82 AA_NORMAL_MASK | AA_BOLD_MASK | AA_BOLDFONT_MASK | AA_REVERSE_MASK | AA_DIM_MASK,
83 NULL,
84 "ANSI escape seqences",
85 ".ansi",
86 "",
87 "",
88 "\n",
89 NORMALPRINTS,
90 {"",
91 "\33[8m",
92 "\33[1m",
93 "\33[1m",
94 "\33[7m"
95 },
96 {"",
97 "\33[0;10m",
98 "\33[0;10m",
99 "\33[0;10m",
100 "\33[0;10m",
101 },
102 NULL
103};
104#ifdef VYHEN_SUPPORT
105struct aa_format aa_vyhen_format =
106{
107 80, 30,
108 80, 30,
109 0,
110 AA_NORMAL_MASK | AA_BOLD_MASK | AA_REVERSE_MASK | AA_DIM_MASK | AA_EXTENDED,
111 NULL,
112 "vyhen",
113 ".vyhen",
114 "",
115 "",
116 "\n",
117 NORMALPRINTS,
118 {"|07",
119 "|08",
120 "|15",
121 "||7|00",
122 "||1|15"
123 },
124 {"",
125 "",
126 "",
127 "||9",
128 "||0",
129 },
130 vyhen_escapes
131};
132#endif
133struct aa_format aa_text_format =
134{
135 80, 25,
136 80, 25,
137 0,
138 AA_NORMAL_MASK,
139 NULL,
140 "Text file",
141 ".txt",
142 "",
143 "",
144 "\n",
145 NORMALPRINTS,
146 NONE,
147 NONE,
148 NULL
149};
150struct aa_format aa_more_format =
151{
152 80, 25,
153 80, 25,
154 AA_NORMAL_SPACES,
155 AA_NORMAL_MASK | AA_BOLD_MASK | AA_BOLDFONT_MASK,
156 NULL,
157 "For more/less",
158 ".cat",
159 "",
160 "",
161 "\n",
162 /* Can leave these %c iff there are no conversions to multi-character
163 * thingies. */
164 {"%s", "%s", "%s\10%s", "%s\10%s", "%s"},
165 NONE,
166 NONE,
167 NULL
168};
169struct aa_format aa_hp_format =
170{
171 130 * 2, 64 * 2 - 1,
172 130, 64 * 2 - 1,
173 AA_USE_PAGES,
174 AA_NORMAL_MASK,
175 &aa_fontline,
176 "HP laser jet - A4 small font",
177 ".hp",
178 "\33(10U\33(s0p16.67h8.5v0s0b0T\33%%0A\33&/0U\33&/0Z\33&/24D",
179 "\14",
180 "\r\33=",
181 NORMALPRINTS,
182 NONE,
183 NONE,
184 NULL
185};
186struct aa_format aa_hp2_format =
187{
188 80 * 2, 64 - 1,
189 80, 64 - 1,
190 AA_USE_PAGES,
191 AA_NORMAL_MASK,
192 &aa_font16,
193 "HP laser jet - A4 big font",
194 ".hp",
195 "\33(s7B\33*p0Y@",
196 "\14",
197 "\r\n",
198 NORMALPRINTS,
199 NONE,
200 NONE,
201 NULL
202};
203struct aa_format aa_irc_format =
204{
205 70, 25,
206 70, 25,
207 0,
208 AA_NORMAL_MASK | AA_BOLD_MASK | AA_REVERSE_MASK,
209 &aa_font16,
210 "For catting to an IRC channel",
211 ".irc",
212 "",
213 "",
214 "\n",
215 NORMALPRINTS,
216 {"",
217 "",
218 "␂",
219 "",
220 "␖"
221 },
222 {"",
223 "",
224 "␂",
225 "",
226 "␖"
227 },
228 NULL
229};
230struct aa_format aa_zephyr_format =
231{
232 70, 25,
233 70, 25,
234 0,
235 AA_NORMAL_MASK | AA_DIM_MASK | AA_BOLD_MASK,
236 &aa_font16,
237 "For catting to an IRC channel II",
238 ".irc",
239 "",
240 "",
241 "\n",
242 NORMALPRINTS,
243 {"",
244 "@color(gray50)",
245 "@b(",
246 "",
247 ""
248 },
249 {"",
250 "@color(black)",
251 ")",
252 "",
253 ""
254 },
255 irc_escapes
256};
257struct aa_format aa_roff_format =
258{
259 70, 25,
260 70, 25,
261 0,
262 AA_NORMAL_MASK | AA_BOLD_MASK,
263 &aa_font16,
264 "For including in a man page",
265 ".man",
266 "",
267 "",
268 "\n.br\n",
269 NORMALPRINTS,
270 {"",
271 "",
272 "\n.B ",
273 "",
274 ""
275 },
276 {"",
277 "",
278 "\n",
279 "",
280 ""
281 },
282 irc_escapes
283};
284
285struct aa_format aa_html_alt_format =
286{
287 79, 25,
288 79, 25,
289 0,
290 AA_NORMAL_MASK,
291 NULL,
292 "HTML <IMG ALT= tag",
293 ".html",
294 /* Need that newline, because lynx inserts a space, thus shifting
295 * the first line of our art. */
296 "<PRE><IMG SRC=\"your image here\" ALT=\"\n",
297 "\"></PRE>\n",
298 "\n",
299 NORMALPRINTS,
300 {"",
301 "",
302 "",
303 "",
304 ""
305 },
306 {"",
307 "",
308 "",
309 "",
310 ""
311 },
312 html_alt_escapes
313};
314
315struct aa_format *aa_formats[] =
316{
317#ifdef VYHEN_SUPPORT
318 &aa_vyhen_format,
319#endif
320 &aa_text_format,
321 &aa_html_format,
322 &aa_nhtml_format,
323 &aa_html_alt_format,
324 &aa_more_format,
325 &aa_ansi_format,
326 &aa_hp_format,
327 &aa_hp2_format,
328 &aa_irc_format,
329 &aa_zephyr_format,
330 &aa_roff_format,
331 NULL
332};
333
334struct aa_driver save_d;
335#define FORMAT ((struct aa_savedata *)c->driverdata)->format
336#define DATA ((struct aa_savedata *)c->driverdata)
337
338static char **build_conversions(char **in, char **conv)
339{
340 char c;
341
342 memset(conv, 0, sizeof(char *) * 256);
343
344 if (in != NULL)
345 while (*in != NULL && *(in + 1) != NULL) {
346 c = **in;
347 in++;
348 conv[c] = *in;
349 in++;
350 }
351 return conv;
352}
353
354static int save_init(struct aa_hardware_params *p, void *none,
355 struct aa_hardware_params *dest, void **data)
356{
357 struct aa_savedata *d = (struct aa_savedata *) none;
358 static struct aa_hardware_params def;
359 *data = (void *) malloc(sizeof(struct aa_savedata));
360 memcpy(*data, d, sizeof(struct aa_savedata));
361 *dest = def;
362 if (p->font == NULL)
363 dest->font = d->format->font;
364 dest->width = d->format->width;
365 dest->height = d->format->height;
366 dest->supported = d->format->supported;
367
368
369 return 1;
370}
371static void save_uninit(aa_context * c)
372{
373}
374static void save_getsize(aa_context * c, int *width, int *height)
375{
376}
377static void save_gotoxy(aa_context * c, int x, int y)
378{
379}
380
381static int lastattr;
382static FILE *f;
383static aa_context *c;
384static void stop_tag()
385{
386 if (lastattr != -1)
387 fputs(FORMAT->ends[lastattr], f);
388 lastattr = -1;
389}
390static void start_tag(int attr)
391{
392 if (attr > AA_NATTRS)
393 attr = AA_NATTRS;
394 lastattr = attr;
395 fputs(FORMAT->begin[lastattr], f);
396}
397static void encodechar(unsigned char attr, unsigned char ch, char **conversions)
398{
399 char chr[2];
400 if (FORMAT->flags & AA_NORMAL_SPACES && ch == ' ' && (attr != AA_REVERSE))
401 attr = AA_NORMAL;
402 if (attr != lastattr) {
403 stop_tag();
404 start_tag(attr);
405 }
406 if (conversions[ch] == NULL) {
407 chr[0] = ch;
408 chr[1] = 0;
409 fprintf(f, FORMAT->prints[attr], chr, chr, chr, chr);
410 } else {
411 fprintf(f, FORMAT->prints[attr], conversions[ch], conversions[ch],
412 conversions[ch], conversions[ch]);
413 }
414}
415
416static void savearea(int x1, int y1, int x2, int y2, char **conversions)
417{
418 int x, y;
419 fputs(FORMAT->head, f);
420 lastattr = -1;
421 for (y = y1; y < y2; y++) {
422 for (x = x1; x < x2; x++) {
423 if (x < 0 || x >= aa_scrwidth(c) ||
424 y < 0 || y >= aa_scrheight(c))
425 encodechar(AA_NORMAL, ' ', conversions);
426 else {
427 int pos = x + y * aa_scrwidth(c);
428 encodechar(c->attrbuffer[pos], c->textbuffer[pos], conversions);
429 }
430 }
431 stop_tag();
432 fputs(FORMAT->newline, f);
433 }
434 fputs(FORMAT->end, f);
435 fflush(f);
436}
437
438static void save_flush(aa_context * c1)
439{
440 char fname[4096];
441 char *conversions[256];
442 c = c1;
443 build_conversions(FORMAT->conversions, conversions);
444 if (FORMAT->flags & AA_USE_PAGES) {
445 int xpages = (aa_scrwidth(c1) + FORMAT->pagewidth - 1) /
446 FORMAT->pagewidth;
447 int ypages = (aa_scrheight(c1) + FORMAT->pageheight - 1) /
448 FORMAT->pageheight;
449 int x, y;
450 for (x = 0; x < xpages; x++)
451 for (y = 0; y < ypages; y++) {
452 if (DATA->name != NULL) {
453 generate_filename(DATA->name, fname, x, y, 1, FORMAT->extension);
454 f = fopen(fname, "w");
455 } else
456 f = DATA->file;
457
458 if (f == NULL)
459 return;
460 savearea(x * FORMAT->pagewidth, y * FORMAT->pageheight,
461 (x + 1) * FORMAT->pagewidth,
462 (y + 1) * FORMAT->pageheight, conversions);
463 if (DATA->name != NULL)
464 fclose(f);
465 }
466
467 } else {
468 if (DATA->name != NULL) {
469 generate_filename(DATA->name, fname, 0, 0, 0, FORMAT->extension);
470 f = fopen(fname, "w");
471 } else
472 f = DATA->file;
473 if (f == NULL)
474 return;
475 savearea(0, 0, /*DATA->width, DATA->height */ aa_scrwidth(c1), aa_scrheight(c1), conversions);
476 if (DATA->name != NULL)
477 fclose(f);
478 }
479}
480
481/*
482 * Takes a template of the form blah%xfu%y.extension and will return
483 * either blah<x>fu<y>.extension or blahfu.extension depending on whether
484 * pages is true or not. %x and %y may be flipped, but may appear only once.
485 * If you want a % in the output, you'll have to use %%.
486 * Using %[^%xy] is not defined. The results are also undefined if you don't
487 * include both %x and %y.
488 *
489 * Rewrote by Jan Hubicka to accept unlimited (and zero) number of % stuff
490 * and %e for extension and %c for coordinates in format %x_%y.
491 * You might now add after filename simply %c%e to get filename
492 * blahX_Y.txt or blah.txt
493 * Also avoided memory owerflows.
494 */
495static char *generate_filename(char *template, char *result, int x, int y, int pages, char *extension)
496{
497 char *a;
498 char *b;
499 char *end = result + 4090;
500 b = template - 1, a = result - 1;
501 while ((*++a = *++b)) {
502 if (a >= end)
503 break; /*Too long filename - probably bug in caller,
504 since filenames longer than 4KB are useless :) */
505 if (*b == '%') {
506 switch (b[1]) {
507 case 'x':
508 a--;
509 if (pages) {
510 char text[8];
511 char *e = text - 1;
512 sprintf(text, "%i", x);
513 while ((*++a = *++e))
514 if (a >= end)
515 break;
516 a--;
517 }
518 b++;
519 break;
520 case 'y':
521 a--;
522 if (pages) {
523 char text[8];
524 char *e = text - 1;
525 sprintf(text, "%i", y);
526 while ((*++a = *++e))
527 if (a >= end)
528 break;
529 a--;
530 }
531 b++;
532 break;
533 case 'c':
534 a--;
535 if (pages) {
536 char text[8];
537 char *e = text - 1;
538 sprintf(text, "_%i_%i", x, y);
539 while ((*++a = *++e))
540 if (a >= end)
541 break;
542 a--;
543 }
544 b++;
545 break;
546 case 'e':
547 a--;
548 {
549 char *e = extension - 1;
550 while ((*++a = *++e))
551 if (a >= end)
552 break;
553 a--;
554 }
555 b++;
556 break;
557 case '%':
558 a--;
559 b++;
560 break;
561 }
562 if (!*b)
563 break;
564 }
565 }
566 *a = 0;
567 return result;
568}
569
570struct aa_driver save_d =
571{
572 "save", "Special driver for saving to files",
573 save_init,
574 save_uninit,
575 save_getsize,
576 NULL,
577 NULL,
578 save_gotoxy,
579 save_flush,
580};