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