OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [mw/] [src/] [demos/] [nanox/] [slider.c] - Blame information for rev 673

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/* Copyright (c) 2000 Simon Wood <simon@mungewell.uklinux.net>
2
 *
3
 * This program is licensed under the same terms that Microwindows
4
 * and Nano-X are licensed under.  See the file LICENSE accompanying
5
 * this distribution.
6
 */
7
 
8
#include <stdio.h>
9
#include <stdlib.h>
10
#include <string.h>
11
#include <unistd.h>
12
 
13
#define MWINCLUDECOLORS
14
#include "nano-X.h"
15
 
16
/* set up size of the grid */
17
#define WIDTH_IN_TILES  4
18
#define HEIGHT_IN_TILES 4
19
#define MAX_TILES       (WIDTH_IN_TILES * HEIGHT_IN_TILES)
20
#define USE_IMAGE       1
21
 
22
static  int     value[WIDTH_IN_TILES][HEIGHT_IN_TILES];
23
static  int     calc_width, calc_height;
24
static  int     tile_width = 40;
25
static  int     tile_height = 40;
26
 
27
#if USE_IMAGE
28
static  void *  image_addr;
29
static  int     using_image = 1;
30
static  GR_WINDOW_ID    image;          /* storage area for image */
31
#endif
32
 
33
static  GR_WINDOW_ID    master;         /* id for whole window */
34
static  GR_WINDOW_ID    buttons;        /* id for buttons */
35
static  GR_WINDOW_ID    tiles;          /* id for play area */
36
static  GR_GC_ID        gc1;            /* graphics context for text */
37
 
38
static  int     value[WIDTH_IN_TILES][HEIGHT_IN_TILES];
39
 
40
/* function prototypes */
41
static  void    HandleEvents();
42
static  void    RefreshWindow();
43
static  void    RandomiseTiles();
44
static  void    MoveTile();
45
static  void    DrawTile();
46
 
47
int
48
main(int argc,char **argv)
49
{
50
        if (GrOpen() < 0) {
51
                fprintf(stderr, "cannot open graphics\n");
52
                exit(1);
53
        }
54
 
55
        gc1 = GrNewGC();
56
 
57
#if USE_IMAGE
58
        image = GrNewWindow(GR_ROOT_WINDOW_ID, 300, 0, (WIDTH_IN_TILES * tile_width),
59
                (HEIGHT_IN_TILES * tile_height), 4, BLACK, WHITE);
60
 
61
        if(argc != 2)
62
                /* No image specified, use numered tiles */
63
                using_image = 0;
64
        else {
65
                /* need to find out image size.... */
66
                image_addr = malloc(4 * (WIDTH_IN_TILES * tile_width) *
67
                        (HEIGHT_IN_TILES * tile_height) );
68
 
69
                image = GrNewPixmap((WIDTH_IN_TILES * tile_width),
70
                        (HEIGHT_IN_TILES * tile_height), image_addr);
71
 
72
                GrDrawImageFromFile(image, gc1, 0, 0,
73
                        GR_IMAGE_MAX_SIZE, GR_IMAGE_MAX_SIZE, argv[1], 0);
74
        }
75
#endif
76
 
77
        /* calculate size of tile area */
78
        calc_width = 10 + (WIDTH_IN_TILES * tile_width);
79
        calc_height = 15 + 35 + (HEIGHT_IN_TILES * tile_height);
80
#if 0
81
        /* enforce minimum size */
82
        if (calc_width < 240) calc_width=240;
83
        if (calc_height < 320) calc_height=320;
84
#endif
85
        master = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0, calc_width, calc_height, 1, RED, WHITE);
86
        buttons = GrNewWindow((GR_WINDOW_ID) master, 5, 5, (calc_width - 5), 35, 1, RED, RED);
87
 
88
        tiles = GrNewWindow((GR_WINDOW_ID) master, (calc_width/2) - (WIDTH_IN_TILES * tile_width /2),
89
                45 + ((calc_height - 50)/2) - (HEIGHT_IN_TILES * tile_height /2),
90
                (WIDTH_IN_TILES * tile_width), (HEIGHT_IN_TILES * tile_height), 1, RED, RED);
91
 
92
        GrMapWindow(master);
93
        GrMapWindow(buttons);
94
        GrMapWindow(tiles);
95
 
96
        /* set random seed */
97
        srandom((int) getpid());
98
 
99
        RandomiseTiles();
100
 
101
        GrSelectEvents(master, GR_EVENT_MASK_EXPOSURE|GR_EVENT_MASK_CLOSE_REQ);
102
        GrSelectEvents(buttons, GR_EVENT_MASK_BUTTON_DOWN);
103
        GrSelectEvents(tiles, GR_EVENT_MASK_BUTTON_DOWN);
104
 
105
        RefreshWindow();
106
 
107
        while (GR_TRUE) {
108
                GR_EVENT event;
109
 
110
                GrGetNextEvent(&event);
111
                HandleEvents(&event);
112
        }
113
}
114
 
115
 
116
/*
117
 * Read the next event and handle it.
118
 */
119
void
120
HandleEvents(GR_EVENT *ep)
121
{
122
        switch (ep->type) {
123
                case GR_EVENT_TYPE_BUTTON_DOWN:
124
                        if (ep->button.wid == buttons) {
125
                                if (ep->button.x < (calc_width/2)) {
126
                                        /* 'Again' */
127
                                        RandomiseTiles();
128
                                        RefreshWindow();
129
                                } else {
130
                                        /* 'Quit' */
131
                                        GrClose();
132
#if USE_IMAGE
133
                                        if (using_image)
134
                                                free(image_addr);
135
#endif
136
                                        exit(0);
137
                                }
138
                        }
139
 
140
                        if (ep->button.wid == tiles) {
141
                                /* Try to move selected tile */
142
                                MoveTile( (int)(ep->button.x / tile_width),
143
                                        (int)(ep->button.y / tile_height) );
144
                        }
145
                        break;
146
 
147
                case GR_EVENT_TYPE_EXPOSURE:
148
                        RefreshWindow();
149
                        break;
150
                case GR_EVENT_TYPE_CLOSE_REQ:
151
                        GrClose();
152
                        exit(0);
153
        }
154
 
155
}
156
 
157
void
158
RefreshWindow()
159
{
160
        int xpos, ypos;
161
 
162
        GrSetGCForeground(gc1, WHITE);
163
        GrSetGCBackground(gc1, RED);
164
 
165
        /* draw the buttons */
166
        GrRect(buttons, gc1, 0, 0, (calc_width - 12)/2, 34);
167
        GrRect(buttons, gc1, (calc_width - 8)/2, 0, (calc_width - 12)/2, 34);
168
 
169
#if 0   /* for when center align text works */
170
        GrText(buttons, gc1, (calc_width - 10)/4, 22, "Again", 5, 0);
171
        GrText(buttons, gc1, (calc_width - 10)*3/4, 22, "Quit", 4, 0);
172
#else
173
        GrText(buttons, gc1, 5, 22, "Again", 5, 0);
174
        GrText(buttons, gc1, (calc_width / 2) + 5, 22, "Quit", 4, 0);
175
#endif
176
 
177
        /* draw the tiles */
178
        for (ypos=0; ypos< HEIGHT_IN_TILES; ypos++){
179
                for (xpos=0; xpos< WIDTH_IN_TILES; xpos++){
180
                        DrawTile(xpos, ypos);
181
                }
182
        }
183
}
184
 
185
void
186
RandomiseTiles()
187
{
188
        int count, xpos, ypos;
189
 
190
        /* allocate all the numbers in order  1..MAX_TILES */
191
        for (ypos=0; ypos< HEIGHT_IN_TILES; ypos++){
192
                for (xpos=0; xpos< WIDTH_IN_TILES; xpos++){
193
                        value[xpos][ypos] = 1 + xpos + (WIDTH_IN_TILES * ypos);
194
                }
195
        }
196
 
197
        /* position of 'hole' */
198
        xpos = WIDTH_IN_TILES - 1;
199
        ypos = HEIGHT_IN_TILES - 1;
200
 
201
        /* randomly slide them around, ALL games can therefore solved - so no excusses!! */
202
        for (count=0; count< MAX_TILES * 1000; count++){
203
                switch(random() % 4) {
204
                        case 0:
205
                                if (ypos < HEIGHT_IN_TILES - 1) {
206
                                        value[xpos][ypos] = value[xpos][ypos+1];
207
                                        ypos++;
208
                                        value[xpos][ypos] = MAX_TILES;
209
                                }
210
                                break;
211
                        case 1:
212
                                if (xpos > 0) {
213
                                        value[xpos][ypos] = value[xpos - 1][ypos];
214
                                        xpos--;
215
                                        value[xpos][ypos] = MAX_TILES;
216
                                }
217
                                break;
218
                        case 2:
219
                                if (ypos > 0) {
220
                                        value[xpos][ypos] = value[xpos][ypos - 1];
221
                                        ypos--;
222
                                        value[xpos][ypos] = MAX_TILES;
223
                                }
224
                                break;
225
                        case 3:
226
                                if (xpos < WIDTH_IN_TILES - 1) {
227
                                        value[xpos][ypos] = value[xpos + 1][ypos];
228
                                        xpos++;
229
                                        value[xpos][ypos] = MAX_TILES;
230
                                }
231
                                break;
232
                }
233
        }
234
}
235
 
236
void
237
MoveTile(xpos, ypos)
238
        int xpos, ypos;
239
{
240
        /* check all possible moves to see if there is the blank (N,E,S,W) */
241
        if (ypos > 0 && value[xpos][ypos - 1] == MAX_TILES) {
242
                value[xpos][ypos - 1] = value[xpos][ypos];
243
                value[xpos][ypos] = MAX_TILES;
244
                DrawTile(xpos, ypos - 1);
245
                DrawTile(xpos, ypos);
246
        }
247
 
248
        if (xpos < (WIDTH_IN_TILES - 1) && value[xpos + 1][ypos] == MAX_TILES) {
249
                value[xpos + 1][ypos] = value[xpos][ypos];
250
                value[xpos][ypos] = MAX_TILES;
251
                DrawTile(xpos + 1, ypos);
252
                DrawTile(xpos, ypos);
253
        }
254
 
255
        if (ypos < (HEIGHT_IN_TILES - 1) && value[xpos][ypos + 1] == MAX_TILES) {
256
                value[xpos][ypos + 1] = value[xpos][ypos];
257
                value[xpos][ypos] = MAX_TILES;
258
                DrawTile(xpos, ypos + 1);
259
                DrawTile(xpos, ypos);
260
        }
261
 
262
        if (xpos > 0 && value[xpos - 1][ypos] == MAX_TILES) {
263
                value[xpos - 1][ypos] = value[xpos][ypos];
264
                value[xpos][ypos] = MAX_TILES;
265
                DrawTile(xpos - 1, ypos);
266
                DrawTile(xpos, ypos);
267
        }
268
 
269
        /* check for a winner */
270
        if (value[WIDTH_IN_TILES - 1][HEIGHT_IN_TILES - 1] == MAX_TILES) {
271
                int winner = 0;
272
                for (ypos=0; ypos< HEIGHT_IN_TILES; ypos++){
273
                        for (xpos=0; xpos< WIDTH_IN_TILES; xpos++){
274
                                if (value[xpos][ypos] == winner + 1)
275
                                        winner++;
276
                                else
277
                                        winner=0;
278
                        }
279
                }
280
                if (winner == MAX_TILES) {
281
                        /* Do winning screen */
282
                        int loop = MAX_TILES;
283
                        for(loop=0; loop < MAX_TILES; loop++) {
284
                                for(winner=0; winner < (MAX_TILES - loop) ; winner++) {
285
 
286
                                        /* move tiles around */
287
                                        xpos = winner % WIDTH_IN_TILES;
288
                                        ypos = (int)(winner/WIDTH_IN_TILES);
289
                                        value[xpos][ypos] = loop + winner + 1;
290
                                        DrawTile(winner % WIDTH_IN_TILES, (int)(winner/WIDTH_IN_TILES));
291
                                }
292
                                GrFlush();
293
                                for(winner=0; winner < 10000000 ; winner++);
294
                                        /* delay loop */
295
                        }
296
                        /* Print message */
297
                        GrSetGCForeground(gc1, WHITE);
298
                        GrSetGCBackground(gc1, RED);
299
                        GrText(tiles, gc1, ((WIDTH_IN_TILES * tile_width)/2) - 40, (HEIGHT_IN_TILES * tile_height)/2, "Well Done!!", -1, 0);
300
                }
301
 
302
        }
303
}
304
 
305
 
306
void
307
DrawTile(xpos, ypos)
308
        int xpos, ypos;
309
{
310
        char text[]="00";
311
 
312
        /* blank out old tile */
313
        GrSetGCForeground(gc1, RED);
314
        GrFillRect(tiles, gc1, (xpos* tile_width), (ypos*tile_height), tile_width, tile_height);
315
 
316
        if (value[xpos][ypos] != MAX_TILES ) {
317
                /* re-draw tile and number */
318
                GrSetGCForeground(gc1, WHITE);
319
                GrSetGCBackground(gc1, RED);
320
                GrRect(tiles, gc1, (xpos*tile_width), (ypos*tile_height), tile_width, tile_height);
321
 
322
#if USE_IMAGE
323
                if (using_image) {
324
                        /* copy from image window */
325
                        GrCopyArea(tiles, gc1, 1 + (xpos*tile_width), 1 + (ypos*tile_height),
326
                                tile_width - 2, tile_height - 2, image,
327
                                1 + (((value[xpos][ypos] - 1) % WIDTH_IN_TILES) * tile_width),
328
                                1 + (((int)(value[xpos][ypos] - 1) / WIDTH_IN_TILES) * tile_height), 0);
329
                } else {
330
#endif
331
                        /* label the tile with a number */
332
                        if (value[xpos][ypos] > 9)
333
                                text[0] = 48 + (int)(value[xpos][ypos]/10);
334
                        else
335
                                text[0] = 32;
336
 
337
                        text[1] = 48 + value[xpos][ypos] % 10;
338
 
339
                        GrText(tiles, gc1, (xpos*tile_width) + (tile_width /2) - 5, (ypos*tile_height) + (tile_height/2) + 5, &text, -1, 0);
340
#if USE_IMAGE
341
                }
342
#endif
343
        }
344
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.