1 /*
2    Copyright (c) 1991 - 1994 Heinz W. Werntges.  All rights reserved.
3    Distributed by Free Software Foundation, Inc.
4 
5 This file is part of HP2xx.
6 
7 HP2xx is distributed in the hope that it will be useful, but
8 WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
9 to anyone for the consequences of using it or for whether it serves any
10 particular purpose or works at all, unless he says so in writing.  Refer
11 to the GNU General Public License, Version 2 or later, for full details.
12 
13 Everyone is granted permission to copy, modify and redistribute
14 HP2xx, but only under the conditions described in the GNU General Public
15 License.  A copy of this license is supposed to have been
16 given to you along with HP2xx so you can know your rights and
17 responsibilities.  It should be in a file named COPYING.  Among other
18 things, the copyright notice and this notice must be preserved on all
19 copies.
20 
21 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22 */
23 
24 /** to_pic.c: PIC (ATARI "32k" bitmap) formatter part of project "hp2xx"
25  **
26  ** 91/08/28  V 1.00  HWW  Originating
27  ** 91/09/08  V 1.01  HWW  Bug fixed: Repeated block columns
28  ** 91/10/09  V 1.02  HWW  ANSI-C definitions; new ATARI file name convention
29  ** 91/10/16  V 1.03b HWW  STAD mode (output file packing) added
30  ** 91/10/21  V 1.03d HWW  Plain "pic", packing done by pic2pac; VAX_C active
31  ** 91/03/01  V 1.03e NM   Bug fixed: numbering of files was incorrect
32  ** 91/05/19  V 1.03f HWW  Abort if color mode
33  ** 94/02/14  V 1.10a HWW  Adapted to changes in hp2xx.h
34  **
35  **	      NOTE:   This code is not part of the supported modules
36  **		      of hp2xx. Include it if needed only.
37  **/
38 
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #ifdef	TURBO_C
43 #include <io.h>
44 #endif
45 #include "bresnham.h"
46 #include "hp2xx.h"
47 
48 
49 
50 #define ATARI_XRES	640	/* MUST be multiple of 8        */
51 #define ATARI_YRES	400
52 #define BYTES_PER_LINE	(ATARI_XRES>>3)
53 
54 
55 
56 
57 static int
Init_PIC_files(const char * basename,FILE ** fd,int nb,int nr,int yb)58 Init_PIC_files(const char *basename, FILE ** fd, int nb, int nr, int yb)
59 {
60 #define	FNAME_LEN	80
61 	char fname[FNAME_LEN], ext[8];
62 	int i, n, yb_tot;
63 #ifdef VAX
64 	int hd;
65 #endif
66 
67 
68 	yb_tot = 1 + (nr - 1) / ATARI_YRES;	/* Total # of y blocks */
69 
70 
71 	for (i = 0; nb > 0; i++, nb -= BYTES_PER_LINE) {
72 		if (fd[i]) {
73 			fclose(fd[i]);
74 			fd[i] = NULL;
75 		}
76 
77 		n = yb + i * yb_tot;
78 		if (n > 99) {
79 			Eprintf("ERROR: Too many PIC files per column!\n");
80 			for (; i > -1; i--)
81 				if (fd[i]) {
82 					fclose(fd[i]);
83 					fd[i] = NULL;
84 				}
85 			return ERROR;
86 		}
87 
88 		sprintf(ext, "%02d.pic", n);
89 
90 		strcpy(fname, basename);
91 		strncat(fname, ext, FNAME_LEN - strlen(basename) - 1);
92 
93 #ifdef VAX
94 		if ((fd[i] =
95 		     fopen(fname, WRITE_BIN, "rfm=var",
96 			   "mrs=512")) == NULL) {
97 #else
98 		if ((fd[i] = fopen(fname, WRITE_BIN)) == NULL) {
99 #endif
100 			PError("hp2xx -- opening PIC file(s)");
101 			return ERROR;
102 		}
103 	}
104 	return 0;
105 }
106 
107 
108 
109 
110 static void RowBuf_to_PIC(RowBuf * row, int nb, FILE ** fd)
111 {
112 	int i, j, n_pad = 0, n_wr = BYTES_PER_LINE;
113 
114 /* VAX peculiarity: Writing one big object is faster than many smaller */
115 
116 	if (nb % BYTES_PER_LINE)	/* padding required */
117 		n_pad = (nb / BYTES_PER_LINE + 1) * BYTES_PER_LINE - nb;
118 
119 	for (i = 0; nb > 0; i++, nb -= n_wr)
120 		fwrite((char *) &row->buf[i * BYTES_PER_LINE],
121 		       n_wr = MIN(nb, BYTES_PER_LINE), 1, fd[i]);
122 
123 	for (i--, j = 0; j < n_pad; j++)	/* Fill last block with zero        */
124 		fputc('\0', fd[i]);
125 }
126 
127 
128 
129 
130 
131 int PicBuf_to_PIC(const GEN_PAR * pg, const OUT_PAR * po)
132 {
133 #define	N_BLOCKS 10
134 
135 	FILE *fd[N_BLOCKS];
136 	int row_c, i, nb, nr, yb;
137 	const PicBuf *pb;
138 
139 	if (pg == NULL || po == NULL)
140 		return ERROR;
141 	pb = po->picbuf;
142 	if (pb == NULL)
143 		return ERROR;
144 
145 	if (pb->depth > 1) {
146 		Eprintf
147 		    ("\nPIC mode does not support colors yet -- sorry\n");
148 		return ERROR;
149 	}
150 
151 	if (pb->nb > (ATARI_XRES * N_BLOCKS) / 8) {
152 		Eprintf("hp2xx -- Too many PIC files per row");
153 		return ERROR;
154 	}
155 
156 	if (!pg->quiet)
157 		Eprintf("\nWriting PIC output: %d rows of %d bytes\n",
158 			pb->nr, pb->nb);
159 
160 	for (i = 0, nb = pb->nb; nb > 0; i++, nb -= BYTES_PER_LINE)
161 		fd[i] = NULL;
162 
163 
164 	/* Backward since highest index is lowest line on screen! */
165 
166 	for (yb = nr = 0, row_c = pb->nr - 1; row_c >= 0; nr++, row_c--) {
167 		if (nr % ATARI_YRES == 0) {
168 			if (Init_PIC_files(	/* Default name */
169 						  (*po->outfile !=
170 						   '-') ? po->
171 						  outfile : "bitmap", fd,
172 						  pb->nb, pb->nr, yb))
173 				return ERROR;
174 			yb++;
175 		}
176 		if ((!pg->quiet) && (row_c % 10 == 0))
177 			/* For the impatients among us ...    */
178 			Eprintf(".");
179 		RowBuf_to_PIC(get_RowBuf(pb, row_c), pb->nb, fd);
180 	}
181 
182 	get_RowBuf(pb, 0);	/* Use row 0 for padding */
183 	for (i = 0; i < pb->nb; i++)	/* Clear it          */
184 		pb->row[0].buf[i] = '\0';
185 
186 	while (nr % ATARI_YRES != 0) {
187 		RowBuf_to_PIC(&pb->row[0], pb->nb, fd);
188 		nr++;
189 	}
190 
191 
192 	if (!pg->quiet)
193 		Eprintf("\n");
194 
195 	for (i = 0, nb = pb->nb; nb > 0; i++, nb -= BYTES_PER_LINE) {
196 		fclose(fd[i]);
197 		fd[i] = NULL;
198 	}
199 	return 0;
200 }
201