1 /* This program was written by Alexander Siegel in September of 1989   */
2 /* at Cornell University.  It may may copied freely for private use or */
3 /* public dispersion provided that this comment is not removed.  This  */
4 /* program, any portion of this program, or any derivative of this     */
5 /* program may not be sold or traded for financial gain.               */
6 
7 /* Modified by Josh Siegel to work with NeWS/X11                       */
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <X11/Xlib.h>
12 #include <X11/keysym.h>
13 #include <X11/Xutil.h>
14 #include <golddig.h>
15 
16 #define EVMASK KeyPressMask | ExposureMask | ButtonMotionMask | ButtonPressMask
17 
18 int lives = STARTLIVES;
19 int angelleft = 0;
20 
21 /* Plug into original block type definitions in shared.c */
22 extern struct symbs_s symbs[];
23 
24 /* Current drawing character */
25 static char curchar = ' ';
26 
27 /* Redraw the entire level */
redrawall()28 void redrawall()
29 {
30   draw_level();
31   XFlush(disp);
32 }
33 
34 /* Set the score to be equal to the number of gold pieces */
count_gold()35 void count_gold()
36 {
37   register int i,levsize;
38 
39   levsize = xsize*ysize;
40   score = 0;
41   for(i=0;i<levsize;++i)
42     if(fast_lookup[level[i]].code & TREASURE)
43       score ++;
44 }
45 
46 /* Main routine for editing levels */
main(argc,argv)47 int main(argc,argv)
48 int argc;
49 char **argv;
50 {
51   register int i;
52   static XEvent xev;
53   KeySym keyhit;
54   int keycount;
55   char buf[50];
56 
57   /* Set up default values for describing world */
58   worldname = DEFWORLD;
59   levelnum = -1;
60   goldleft = 0;
61   score = 0;
62   speed = 0;
63   /* Use size of default level as default level size */
64   xsize = -1;
65   ysize = -1;
66 
67   /* Read in command line options */
68   for(i=1;i<argc;++i) {
69     if(argv[i][0] == '-') {
70       /* -w sets the level width */
71       if(argv[i][1] == 'w') {
72         if(argv[i][2] == '\0' && i+1 < argc) {
73           sscanf(argv[i+1],"%d",&xsize);
74           i++;
75         }
76         else
77           sscanf(argv[i]+2,"%d",&xsize);
78       }
79       /* -h sets the level height */
80       else if(argv[i][1] == 'h') {
81         if(argv[i][2] == '\0' && i+1 < argc) {
82           sscanf(argv[i+1],"%d",&ysize);
83           i++;
84         }
85         else
86           sscanf(argv[i]+2,"%d",&ysize);
87       }
88       /* -l sets the level number */
89       else if(argv[i][1] == 'l') {
90         if(argv[i][2] == '\0' && i+1 < argc) {
91           sscanf(argv[i+1],"%d",&levelnum);
92           i++;
93         }
94         else
95           sscanf(argv[i]+2,"%d",&levelnum);
96       }
97       /* Look for geometry description */
98       else if (argv[i][1] == 'g') {
99         geom = argv[i + 1];
100         i++;
101       }
102       else {
103         printf("usage: gdedit [-h <height>] [-w <width>] -l <level> [<world name>]\n");
104         exit(1);
105       }
106     }
107     /* If it doesn't start with a dash, it must be the world name */
108     else {
109       worldname = argv[i];
110       break;
111     }
112   }
113   /* Make sure some value was chosen for the level number.  This */
114   /* discourages everybody editing the same level all the time. */
115   if(levelnum == -1) {
116     printf("usage: gdedit [-h <height>] [-w <width>] -l <level> [<world name>]\n");
117     exit(1);
118   }
119 
120   /* Load in level data from file. */
121   load_level();
122 
123   printf("Welcome.  Type h for help.\n");
124 
125   /* Start up X windows and create all graphics cursors */
126   xstart(EVMASK, argc, argv);
127   /* Set the name of the output window */
128   XStoreName(disp,wind,"Gold Digger 3.0 Level Generator");
129   XSetIconName(disp,wind,"GD 3.0 Generator");
130 
131   /* Main event loop */
132   do {
133     /* Get the next X window event */
134     XWindowEvent(disp,wind,EVMASK,&xev);
135     /* If it was an expose event, redraw everything */
136     if(xev.type == Expose) {
137       /* Count the number of gold pieces in level */
138       count_gold();
139       /* Redraw the level */
140       redrawall();
141     }
142     else if(xev.type == KeyPress) {
143       keycount = XLookupString((XKeyEvent *) &xev, buf, 50, &keyhit,
144 			       (XComposeStatus *) NULL);
145       /* If the 'h', '?' or '/' key was hit, print out the text */
146       /* descriptions of each block type */
147       if(keyhit == XK_H || keyhit == XK_h || keyhit == XK_question ||
148          keyhit == XK_slash) {
149         for(i=0;symbs[i].symb != '\0';++i)
150           if(! (symbs[i].code & NODRAW))
151             printf("%c - draw %ss\n",symbs[i].symb,symbs[i].name);
152         puts("Type ^W to finish editing and save the level.");
153         puts("Type ^C to quit editing.");
154         puts("Type ^E to erase level.");
155         puts("Use the left mouse button to paint blocks.");
156         puts("Use the right mouse button to erase blocks.");
157         putchar('\n');
158       }
159       /* A ^E erases the entire level */
160       else if((keyhit == XK_E || keyhit == XK_e) &&
161               (xev.xkey.state & ControlMask)) {
162         /* Replice level contents with space */
163         for(i=0;i<xsize*ysize;++i)
164           level[i] = SPACE;
165         /* There is no gold now */
166         score = 0;
167         /* Redraw empty level */
168         redrawall();
169       }
170       else {
171         /* Search through the block descriptions for one which has a */
172         /* key code which matches the key code of the key which was */
173         /* hit. */
174         for(i=0;symbs[i].symb != '\0';++i)
175           if(! (symbs[i].code & NODRAW))
176             if(keyhit == symbs[i].xkey1 || keyhit == symbs[i].xkey2) {
177               /* Change the current drawing character to the symbol */
178               /* which was found. */
179               curchar = symbs[i].symb;
180               /* Count and display the number of gold pieces in level */
181               count_gold();
182               draw_score();
183               break;
184             }
185       }
186     }
187     /* If the mouse moves with the button pressed, or the button is */
188     /* pressed, draw the current block at that position */
189     else if(xev.type == MotionNotify) {
190       if(xev.xmotion.state & Button3Mask)
191         setchar(xev.xmotion.x >> 4,xev.xmotion.y >> 4,SPACE);
192       else
193         setchar(xev.xmotion.x >> 4,xev.xmotion.y >> 4,curchar);
194     }
195     else if(xev.type == ButtonPress) {
196       if(xev.xbutton.button == Button3)
197         setchar(xev.xbutton.x >> 4,xev.xbutton.y >> 4,SPACE);
198       else
199         setchar(xev.xbutton.x >> 4,xev.xbutton.y >> 4,curchar);
200     }
201     /* Flush the graphics commands out to the server */
202     XFlush(disp);
203   /* Loop until a control key is pressed */
204   } while(xev.type != KeyPress ||
205           (keyhit != XK_C && keyhit != XK_c &&
206            keyhit != XK_W && keyhit != XK_w) ||
207           ! (xev.xkey.state & ControlMask));
208 
209   /* Terminated X windows connection */
210   xend();
211   /* Save level to data file */
212   if(keyhit == XK_W || keyhit == XK_w)
213     save_level();
214   exit(0);
215 }
216 
217