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