1 /*
2     TiMidity++ -- MIDI to WAVE converter and player
3     Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4     Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 
20 	Macintosh interface for TiMidity
21 	by T.Nogami	<t-nogami@happy.email.ne.jp>
22 
23     mac_mag.c
24     Macintosh mag loader
25 */
26 
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif /* HAVE_CONFIG_H */
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include "timidity.h"
35 #include "common.h"
36 #include "wrd.h"
37 #include "mac_wrdwindow.h"
38 #include "mac_mag.h"
39 
40 #pragma mark ==mag_header
41 
42 typedef struct {
43 	uint8	header;
44 	uint8	machine_code;
45 	uint8	machine_depend_flag;
46 	uint8	screen_mode;
47 	uint16	x1,y1,x2,y2;
48 	uint32	offset_flagA;
49 	uint32	offset_flagB;
50 	uint32	size_flagB;
51 	uint32	offset_pixel;
52 	uint32	size_pixel;
53 
54 	char	filename[256];
55 	int		width, hight;
56 	long	header_pos;
57 	uint8	flag[1280]; //for safty
58 	uint8	*flagA_work, *flagB_work;
59 	int		flagA_pos, flagB_pos, pixel_pos;
60 	Ptr		bitMap;
61 	int		rowBytes;
62 } Mag_Header;
63 
read_flagA_setup(Mag_Header * mh,struct timidity_file * tf)64 static void read_flagA_setup(Mag_Header * mh, struct timidity_file *tf )
65 {
66 	int	 readbytes;
67 
68 	readbytes=mh->offset_flagB - mh->offset_flagA;
69 	mh->flagA_work=(uint8*)safe_malloc( readbytes );
70 	tf_seek(tf, mh->header_pos + mh->offset_flagA, SEEK_SET);
71 	tf_read(mh->flagA_work, 1, readbytes, tf);
72 	mh->flagA_pos=0;
73 }
74 
read_flagB_setup(Mag_Header * mh,struct timidity_file * tf)75 static void read_flagB_setup(Mag_Header * mh, struct timidity_file *tf )
76 {
77 	mh->flagB_work=(uint8*)safe_malloc( mh->size_flagB );
78 	tf_seek(tf, mh->header_pos + mh->offset_flagB, SEEK_SET);
79 	tf_read(mh->flagB_work, 1, mh->size_flagB, tf);
80 	mh->flagB_pos=0;
81 }
82 
read_flag_1line(Mag_Header * mh)83 static void read_flag_1line(Mag_Header * mh )
84 {
85 	int		x, flagA,flagB;
86 
87 	for( x=mh->x1; x<=mh->x2; ){
88 		flagA= mh->flagA_work[mh->flagA_pos/8] & (0x80 >> (mh->flagA_pos & 0x07) );
89 		mh->flagA_pos++;
90 		if( flagA ){
91 			flagB= mh->flagB_work[mh->flagB_pos++];
92 		}else{
93 			flagB= 0;
94 		}
95 		mh->flag[x] ^= flagB>>4;	 x+=4;
96 		mh->flag[x] ^= flagB & 0x0F; x+=4;
97 	}
98 }
99 
load_pixel(Mag_Header * mh,struct timidity_file * tf)100 static void load_pixel(Mag_Header * mh, struct timidity_file *tf )
101 {
102 	int 		fpos,x,y,i, dx,dy;
103 	uint16		pixels;
104 	const int	DX[]={0,-4,-8,-16,  0,-4,  0,-4,-8,  0,-4,-8,  0,-4,-8, 0},
105 				DY[]={0, 0, 0,  0, -1,-1, -2,-2,-2, -4,-4,-4, -8,-8,-8, -16};
106 #define OUT_OF_DISP (x>=640 || y>=400)
107 
108 	read_flagA_setup(mh, tf );
109 	read_flagB_setup(mh, tf );
110 	fpos= mh->header_pos + mh->offset_pixel;
111 	tf_seek(tf, fpos, SEEK_SET);
112 	for( y=mh->y1; y<=mh->y2; y++ ){
113 		read_flag_1line( mh );
114 		for( x=mh->x1; x<=mh->x2; x+=4 ){
115 			if( mh->flag[x]==0 ){
116 				tf_read(&pixels, 1, 2, tf);
117 				if( OUT_OF_DISP ) continue;
118 				for( i=3; i>=0; i-- ){
119 					*(uint8*)(&mh->bitMap[y*mh->rowBytes+x+i])= (pixels & 0x000F);
120 					pixels >>= 4;
121 				}
122 			} else {
123 				if( OUT_OF_DISP ) continue;
124 				dx=DX[mh->flag[x]];
125 				dy=DY[mh->flag[x]];
126 				 //*(uint32*)(&mh->bitMap[y*mh->rowBytes+x]) =  //copy 4bytes, danger?
127 				 //		 *(uint32*)(&mh->bitMap[(y+dy)*mh->rowBytes+ x+dx]);
128 				 mh->bitMap[y*mh->rowBytes+x  ]= mh->bitMap[(y+dy)*mh->rowBytes+ x+dx  ];
129 				 mh->bitMap[y*mh->rowBytes+x+1]= mh->bitMap[(y+dy)*mh->rowBytes+ x+dx+1];
130 				 mh->bitMap[y*mh->rowBytes+x+2]= mh->bitMap[(y+dy)*mh->rowBytes+ x+dx+2];
131 				 mh->bitMap[y*mh->rowBytes+x+3]= mh->bitMap[(y+dy)*mh->rowBytes+ x+dx+3];
132 			}
133 		}
134 	}
135 }
136 
mac_mag_load(const char * fn,int dx,int dy,PixMapHandle pixmap,int mode,Rect * imageRect)137 int mac_mag_load(const char* fn, int dx, int dy, PixMapHandle pixmap,
138 							int mode, Rect *imageRect)
139 {										// pixmap must be locked by caller
140 										// store imagerect in this function
141 										// no err -> return 0; else return 1;
142 	uint8	buf[80];
143 	int		ret,i, err=0;
144 	struct timidity_file	*tf;
145 	static Mag_Header mag_header;
146 	RGBColor	color;
147 
148 //	if( strcmp( mag_header.filename, fn)==0 ){
149 //		SetRect(imageRect, mag_header.x1, mag_header.y1, mag_header.x2+1, mag_header.y2+1);
150 //		return; //nothing to do
151 //	}
152 
153 	if( (tf=wrd_open_file((char *)fn))==0 )
154 		return 1;
155 
156 	// initialize table
157 	memset(&mag_header, 0, sizeof(Mag_Header) );
158 	strcpy( mag_header.filename, fn );
159 	mag_header.bitMap = GetPixBaseAddr(pixmap);
160 	mag_header.rowBytes= (**pixmap).rowBytes & 0x1FFF;
161 
162 	// magic string check
163 	ret=tf_read(buf, 1, 8,tf);
164 	if( ret!=8 || memcmp(buf, "MAKI02  ",8)!=0 ){
165 		err=1;
166 		goto mac_mag_load_exit;
167 	}
168 
169 
170 	while( tf_getc(tf) != 0x1A ) //skip machine code,user name, comment
171 		/*nothing*/;
172 
173 	mag_header.header_pos=tf_tell(tf); //get header position
174 
175 	// read header
176 	ret=tf_read(&mag_header, 1, 32, tf);
177 	if( ret!=32 ) goto mac_mag_load_exit; //unexpected end of file
178 
179 	//transrate endian
180 	mag_header.x1=LE_SHORT(mag_header.x1);
181 	mag_header.y1=LE_SHORT(mag_header.y1);
182 	mag_header.x2=LE_SHORT(mag_header.x2);
183 	mag_header.y2=LE_SHORT(mag_header.y2);
184 	mag_header.offset_flagA=LE_LONG(mag_header.offset_flagA);
185 	mag_header.offset_flagB=LE_LONG(mag_header.offset_flagB);
186 	mag_header.size_flagB=LE_LONG(mag_header.size_flagB);
187 	mag_header.offset_pixel=LE_LONG(mag_header.offset_pixel);
188 	mag_header.size_pixel=LE_LONG(mag_header.size_pixel);
189 
190 	mag_header.x1 &= ~0x7;
191 	mag_header.x2 |= 0x7;
192 
193 	if( dx!=WRD_NOARG ){
194 		int width= mag_header.x2-mag_header.x1;
195 		mag_header.x1= dx;
196 		mag_header.x2= mag_header.x1+width;
197 	}
198 
199 	if( dy!=WRD_NOARG ){
200 		int hight= mag_header.y2-mag_header.y1;
201 		mag_header.y1= dy;
202 		mag_header.y2= mag_header.y1+hight;
203 	}
204 
205 
206 
207 	mag_header.width=mag_header.x2-mag_header.x1+1;
208 	mag_header.hight=mag_header.y2-mag_header.y1+1;
209 	SetRect(imageRect, mag_header.x1, mag_header.y1, mag_header.x2+1, mag_header.y2+1);
210 
211 	if( mag_header.screen_mode != 0 ){
212 		goto mac_mag_load_exit; //not support mode
213 	}
214 
215 	//read pallet
216 	for( i=0; i<16; i++){
217 		ret=tf_read(buf, 1, 3, tf);
218 		if( ret!=3 ) goto mac_mag_load_exit; //unexpected end of file
219 		color.green=buf[0]*256;
220 		color.red=buf[1]*256;
221 		color.blue=buf[2]*256;
222 		dev_palette[17][i]=color; //(buf[1]>>4)*0x100 + (buf[0]>>4)*0x10 + (buf[2]>>4);
223 	}
224 
225 	//ActivatePalette(qd.thePort);
226 	if( mode==0 || mode==1 )
227 		load_pixel(&mag_header, tf );
228 
229  mac_mag_load_exit:
230 	free(mag_header.flagA_work);
231 	free(mag_header.flagB_work);
232 	close_file(tf);
233 	return err;
234 }
235 
236 // **********************************************************************
237 #pragma mark -
mac_pho_load(const char * fn,PixMapHandle pm)238 int mac_pho_load(const char* fn, PixMapHandle pm)
239 {
240 										// pixmap must be locked by caller
241 	uint8	buf[80];
242 	int		ret,i,j,x,y,rowBytes;
243 	struct timidity_file	*tf;
244 	Ptr		bitMap;
245 
246 	SET_G_COLOR(0,graphicWorld[activeGraphics]);
247 	PaintRect(&portRect);
248 
249 	if( (tf=wrd_open_file((char *)fn))==0 )
250 		return 1;
251 	rowBytes= (**pm).rowBytes & 0x1FFF;
252 	bitMap = GetPixBaseAddr(pm);
253 
254 	for( j=0; j<=3; j++){
255 		for( y=0; y<400; y++){
256 			for( x=0; x<640;  ){
257 				ret=tf_read(buf, 1, 1, tf);
258 				if( ret!=1 ) goto mac_mag_load_exit; //unexpected end of file
259 				//bitMap[y*rowBytes+x] &= 0x1F;
260 				for( i=7; i>=0; i--){
261 					bitMap[y*rowBytes+x+i] |= ((buf[0] & 0x01)<<j);
262 					buf[0]>>=1;
263 				}
264 				x+=8;
265 			}
266 		}
267 	}
268 
269  mac_mag_load_exit:
270 	close_file(tf);
271 	return 0;
272 }
273 
274 
275