OSDN Git Service

Initial Import
[nethackexpress/trunk.git] / sys / amiga / amirip.c
1 /*      SCCS Id: @(#)amirip.c   3.2     96/02/04        */
2 /* Copyright (c) Kenneth Lorber, Bethesda, Maryland 1991,1992,1993,1995,1996. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 #include "hack.h"
6 #include <exec/types.h>
7 #include <exec/io.h>
8 #include <exec/alerts.h>
9 #include <exec/devices.h>
10 #include <devices/console.h>
11 #include <devices/conunit.h>
12 #include <graphics/gfxbase.h>
13 #include <graphics/gfxmacros.h>
14 #include <intuition/intuition.h>
15 #include <libraries/dosextens.h>
16 #include <ctype.h>
17 #include <string.h>
18 #include "winami.h"
19 #include "windefs.h"
20 #include "winext.h"
21 #include "winproto.h"
22
23 static struct RastPort *rp;
24
25 #ifdef AMII_GRAPHICS
26
27 #undef  NULL
28 #define NULL    0
29
30 #ifdef AZTEC_C
31 # include <functions.h>
32 #else
33 # ifdef _DCC
34 #  include <clib/dos_protos.h>
35 #  include <clib/exec_protos.h>
36 #  include <clib/console_protos.h>
37 #  include <clib/diskfont_protos.h>
38 # else
39 #  include <proto/dos.h>
40 #  include <proto/exec.h>
41 #  include <proto/console.h>
42 #  include <proto/diskfont.h>
43 # endif
44
45 static char *load_list[]={"tomb.iff",0};
46 static BitMapHeader tomb_bmhd;
47 static struct BitMap *tbmp[ 1 ] = {0};
48
49 static int cols[2]={154,319};           /* X location of center of columns */
50 static int cno = 0;                     /* current column */
51 #define TEXT_TOP (65+yoff)
52
53 static xoff, yoff;                      /* image centering */
54
55 /* terrible kludge */
56 /* this is why prototypes should have ONLY types in them! */
57 # undef red
58 # undef green
59 # undef blue
60 # undef index
61 # ifdef _DCC
62 #  include <clib/graphics_protos.h>
63 #  include <clib/intuition_protos.h>
64 # else
65 #  include <proto/graphics.h>
66 #  include <proto/intuition.h>
67 # endif
68 #endif /* AZTEC_C */
69
70 extern char *killed_by_prefix[];
71 static struct Window *ripwin=0;
72 static void tomb_text(char*);
73 static void dofade(int,int,int);
74 static int search_cmap(int,int,int);
75
76 #define STONE_LINE_LEN 13   /* # chars that fit on one line
77                              * (note 1 ' ' border) */
78
79 #define DEATH_LINE  10
80 #define YEAR_LINE   15
81
82 static unsigned short tomb_line;
83
84 extern struct amii_DisplayDesc *amiIDisplay;
85 extern struct Screen *HackScreen;
86 extern int havelace;
87
88 static unsigned short transpalette[ AMII_MAXCOLORS ] = { 0x0000,  };
89
90 static struct NewWindow newwin =
91 {
92     0,0,640,200,1,0,
93     MOUSEBUTTONS|VANILLAKEY|NOCAREREFRESH,
94     BORDERLESS|ACTIVATE|SMART_REFRESH,
95     NULL,NULL,(UBYTE*)NULL,NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN
96 };
97
98 int wh; /* was local in outrip, but needed for SCALE macro */
99
100 int cmap_white, cmap_black;
101
102 void
103 amii_outrip( tmpwin, how )
104 winid tmpwin;
105 int how;
106 {
107     int just_return = 0;
108     int done, rtxth;
109     struct IntuiMessage *imsg;
110     int i;
111     register char *dpx;
112     char buf[ 200 ];
113     int line, tw, ww;
114     char *errstr = NULL;
115
116     if(!WINVERS_AMIV || HackScreen->RastPort.BitMap->Depth < 4)goto cleanup;
117
118     /* Use the users display size */
119     newwin.Height = amiIDisplay->ypix - newwin.TopEdge;
120     newwin.Width = amiIDisplay->xpix;
121     newwin.Screen = HackScreen;
122
123     for( i = 0; i < amii_numcolors; ++i )
124         flags.amii_curmap[i] = GetRGB4( HackScreen->ViewPort.ColorMap, i );
125
126     ripwin = OpenWindow( (void *)&newwin );
127     if( !ripwin ) goto cleanup;
128
129     LoadRGB4( &HackScreen->ViewPort, transpalette, amii_numcolors );
130
131     rp= ripwin->RPort;
132     wh = ripwin->Height;
133     ww = ripwin->Width;
134
135 #ifdef HACKFONT
136     if (HackFont)
137         SetFont(rp, HackFont);
138 #endif
139
140     tomb_bmhd = ReadImageFiles(load_list, tbmp, &errstr );
141     if(errstr)goto cleanup;
142     if(tomb_bmhd.w > ww || tomb_bmhd.h > wh)goto cleanup;
143
144 #define GENOFF(full,used) ((((full)-(used))/2) & ~7)
145     xoff = GENOFF(ww,tomb_bmhd.w);
146     yoff = GENOFF(wh,tomb_bmhd.h);
147     for(i=0;i<SIZE(cols);i++)cols[i]+=xoff;
148
149     cmap_white = search_cmap(0,0,0);
150     cmap_black = search_cmap(15,15,15);
151
152     BltBitMap(*tbmp, 0, 0, rp->BitMap, xoff, yoff, tomb_bmhd.w, tomb_bmhd.h, 0xc0, 0xff, NULL);
153
154     /* Put together death description */
155     switch (killer_format) {
156     default:
157         impossible("bad killer format?");
158     case KILLED_BY_AN:
159         Strcpy(buf, killed_by_prefix[how]);
160         Strcat(buf, an(killer));
161         break;
162     case KILLED_BY:
163         Strcpy(buf, killed_by_prefix[how]);
164         Strcat(buf, killer);
165         break;
166     case NO_KILLER_PREFIX:
167         Strcpy(buf, killer);
168         break;
169     }
170
171     tw = TextLength(rp,buf,STONE_LINE_LEN) + 40;
172
173     {
174         char *p=buf;
175         int x, tmp;
176         for(x=STONE_LINE_LEN;x;x--)*p++='W';
177         *p='\0';
178         tmp = TextLength(rp,buf,STONE_LINE_LEN) + 40;
179         tw = max( tw, tmp);
180     }
181
182     /* There are 5 lines of text on the stone. */
183     rtxth = ripwin->RPort->TxHeight * 5;
184
185     SetAfPt( rp, (UWORD *)NULL, 0 );
186     SetDrPt( rp, 0xFFFF );
187
188     tomb_line=TEXT_TOP;
189
190     SetDrMd(rp,JAM1);
191
192     /* Put name on stone */
193     Sprintf(buf, "%s", plname);
194     buf[STONE_LINE_LEN] = 0;
195     tomb_text(buf);
196
197     /* Put $ on stone */
198     Sprintf(buf, "%ld Au",
199 #ifndef GOLDOBJ
200                 u.ugold);
201 #else
202                 done_money);
203 #endif
204     buf[STONE_LINE_LEN] = 0; /* It could be a *lot* of gold :-) */
205     tomb_text(buf);
206
207     /* Put together death description */
208     switch (killer_format) {
209     default:
210         impossible("bad killer format?");
211     case KILLED_BY_AN:
212         Strcpy(buf, killed_by_prefix[how]);
213         Strcat(buf, an(killer));
214         break;
215     case KILLED_BY:
216         Strcpy(buf, killed_by_prefix[how]);
217         Strcat(buf, killer);
218         break;
219     case NO_KILLER_PREFIX:
220         Strcpy(buf, killer);
221         break;
222     }
223
224     /* Put death type on stone */
225     for (line=DEATH_LINE, dpx = buf; line<YEAR_LINE; line++)
226     {
227         register int i,i0;
228         char tmpchar;
229
230         if ( (i0=strlen(dpx)) > STONE_LINE_LEN)
231         {
232             for(i=STONE_LINE_LEN;((i0 > STONE_LINE_LEN) && i); i--)
233             {
234                 if(dpx[i] == ' ')
235                     i0 = i;
236             }
237             if(!i)
238                 i0 = STONE_LINE_LEN;
239         }
240
241         tmpchar = dpx[i0];
242         dpx[i0] = 0;
243         tomb_text(dpx);
244
245         if (tmpchar != ' ')
246         {
247             dpx[i0] = tmpchar;
248             dpx= &dpx[i0];
249         }
250         else
251         {
252             dpx= &dpx[i0+1];
253         }
254     }
255
256     /* Put year on stone */
257     Sprintf(buf, "%4d", getyear());
258     tomb_text(buf);
259
260 #ifdef NH320_DEDICATION
261     /* dedication */
262     cno = 1;
263     tomb_line=TEXT_TOP;
264     tomb_text("This release");
265     tomb_text("of NetHack");
266     tomb_text("is dedicated");
267     tomb_text("to the");
268     tomb_text("memory of");
269     tomb_text("");
270     tomb_text("Izchak");
271     tomb_text(" Miller");
272     tomb_text("");
273     tomb_text("1935-1994");
274     tomb_text("");
275     tomb_text("Ascended");
276 #endif
277     /* Fade from black to full color */
278     dofade(0,16,1);
279
280     /* Flush all messages to avoid typeahead */
281     while( imsg = (struct IntuiMessage *)GetMsg( ripwin->UserPort ) )
282         ReplyMsg( (struct Message *) imsg );
283     done = 0;
284     while( !done )
285     {
286         WaitPort( ripwin->UserPort );
287         while( imsg = (struct IntuiMessage *)GetMsg(ripwin->UserPort) )
288         {
289             switch( imsg->Class )
290             {
291                 case MOUSEBUTTONS:
292                 case VANILLAKEY:
293                     done = 1;
294                     break;
295             }
296             ReplyMsg( (struct Message *)imsg );
297         }
298     }
299
300     /* Fade out */
301     dofade(16,0,-1);
302     just_return = 1;
303
304 cleanup:
305         /* free everything */
306     if(ripwin){
307         Forbid();
308         while( imsg = (struct IntuiMessage *)GetMsg( ripwin->UserPort ) )
309             ReplyMsg( (struct Message *)imsg );
310         CloseWindow( ripwin );
311         Permit();
312     }
313     LoadRGB4( &HackScreen->ViewPort, flags.amii_curmap, amii_numcolors );
314
315     if(tbmp[0])FreeImageFiles(load_list, tbmp);
316     if(just_return) return;
317         /* fall back to the straight-ASCII version */
318     genl_outrip(tmpwin, how);
319 }
320
321 static void tomb_text(p)
322 char *p;
323 {
324     char buf[STONE_LINE_LEN*2];
325     int l;
326
327     tomb_line += rp->TxHeight;
328
329     if( !*p )
330         return;
331     sprintf(buf," %s ",p);
332     l=TextLength(rp,buf,strlen(buf));
333
334     SetAPen(rp,cmap_white);
335     Move(rp,cols[cno]-(l/2)-1, tomb_line);
336     Text(rp,buf,strlen(buf));
337
338     SetAPen(rp,cmap_white);
339     Move(rp,cols[cno]-(l/2)+1, tomb_line);
340     Text(rp,buf,strlen(buf));
341
342     SetAPen(rp,cmap_white);
343     Move(rp,cols[cno]-(l/2), tomb_line-1);
344     Text(rp,buf,strlen(buf));
345
346     SetAPen(rp,cmap_white);
347     Move(rp,cols[cno]-(l/2), tomb_line+1);
348     Text(rp,buf,strlen(buf));
349
350     SetAPen(rp,cmap_black);
351     Move(rp,cols[cno]-(l/2), tomb_line);
352     Text(rp,buf,strlen(buf));
353 }
354
355 /* search colormap for best match to given color */
356 static int
357 search_cmap(int r0, int g0, int b0){
358     int best = 0;
359     int bdiff = 0x0fffffff;
360     int x;
361     for(x=0;x<amii_numcolors; x++){
362         int r = r0- ((amiv_init_map[x] >> 8) & 15);
363         int g = g0-((amiv_init_map[x] >> 4) & 15);
364         int b = b0-((amiv_init_map[x] ) & 15);
365         int diff = (r*r) + (g*g) + (b*b);
366         if(diff<bdiff){
367             bdiff = diff;
368             best = x;
369         }
370     }
371     return best;
372 }
373
374 /* caution: this is NOT general! */
375 static void
376 dofade(int start, int stop, int inc){
377     int i,j;
378     for( i = start; (i*inc) <= stop; i+=inc )
379     {
380         for( j = 0; j < amii_numcolors; ++j )
381         {
382             int r, g, b;
383
384             r = ( amiv_init_map[ j ] & 0xf00 ) >> 8;
385             g = ( amiv_init_map[ j ] & 0xf0 ) >> 4;
386             b = ( amiv_init_map[ j ] & 0xf );
387             r = ( r * i ) / 16;
388             g = ( g * i ) / 16;
389             b = ( b * i ) / 16;
390             transpalette[ j ] = ((r<<8)|(g<<4)|b);
391         }
392         LoadRGB4( &HackScreen->ViewPort, transpalette, amii_numcolors );
393         Delay( 1 );
394     }
395 }
396
397
398
399 #endif /* AMII_GRAPHICS */
400
401 /*
402 TODO:
403         memory leaks
404         fix ReadImageFiles to return error instead of panic on error
405 */