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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [services/] [gfx/] [mw/] [v2_0/] [src/] [demos/] [nanox/] [world.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
/*
2
 * Draw a crude map of the world using mini-X graphics on MINIX.
3
 * Converted from an Amiga program by Mike Groshart and Bob Dufford.
4
 * Author: David I. Bell
5
 *
6
 * ported to 16 bit systems by Greg Haerr
7
 */
8
#include <stdio.h>
9
#include <string.h>
10
#define MWINCLUDECOLORS
11
#include "nano-X.h"
12
 
13
#if defined(MSDOS) || defined(__ECOS)
14
#include <fcntl.h>
15
#endif
16
 
17
#if LINUX | DOS_DJGPP
18
#include <sys/types.h>
19
#include <sys/stat.h>
20
#include <fcntl.h>
21
#include <unistd.h>
22
#endif
23
 
24
#ifndef O_BINARY
25
#define O_BINARY        0
26
#endif
27
 
28
#if defined(DOS_DJGPP) || defined(__ECOS)
29
#define MAPFILE "world.map"
30
#else
31
#define MAPFILE "demos/nanox/world.map"         /* was /usr/lib*/
32
#endif
33
 
34
#define SELECTBUTTON    GR_BUTTON_L
35
#define COORDBUTTON     GR_BUTTON_R
36
 
37
 
38
/*
39
 * Definitions to use fixed point in place of true floating point.
40
 */
41
typedef long    FLOAT;
42
 
43
#define SCALE   100             /* fixed point scaling factor */
44
 
45
#define FFMUL(a,b)      (((FLOAT)(a) * (b) + (SCALE / 2)) / SCALE)
46
#define FFDIV(a,b)      (((FLOAT)(a) * SCALE) / (b))
47
#define FIMUL(a,b)      ((FLOAT)(a) * (b))
48
#define FIDIV(a,b)      ((FLOAT)(a) / (b))
49
#define ITOF(a)         ((FLOAT)(a) * SCALE)
50
#define FTOI(a)         (((FLOAT)(a) + (SCALE / 2)) / SCALE)
51
 
52
 
53
#define QSPAN   (90L*60*SCALE)  /* equator to pole (90 degrees) */
54
#define HSPAN   (QSPAN*2)       /* pole to pole (180 degrees) */
55
#define WSPAN   (QSPAN*4)       /* around equator (360 degrees) */
56
 
57
#define ABS(n)  (((n) < 0) ? -(n) : (n))
58
 
59
 
60
/*
61
 * Structure of a point in the database file.
62
 */
63
typedef struct {
64
        short   Code;           /* type of point (see code_colors below) */
65
        short   Lat;            /* latitude in minutes */
66
        short   Lon;            /* longitude in minutes */
67
} MWPACKED DBPOINT;
68
 
69
#if BIGENDIAN
70
#define SHORT_SWAP(p) (p = ((p & 0xff) << 8) | ((p >> 8) & 0xff))
71
#define DBPOINT_CONVERT(p) (SHORT_SWAP(p->Code),SHORT_SWAP(p->Lat),SHORT_SWAP(p->Lon))
72
#else
73
#define DBPOINT_CONVERT(p)      ((void)p)
74
#endif
75
 
76
#define POINTSize       sizeof(DBPOINT)
77
#define PCount          128             /* number of points to read at once */
78
 
79
 
80
/*
81
 * The following variables are the scaling factors to be used when drawing
82
 * points.  However, they are larger than the true value by a factor of 60.
83
 * This is done because without real floating point, their true values are
84
 * too small to be accurate enough.  I cannot just increase the fixed point
85
 * precision because that causes overflows.  What a pain!
86
 */
87
static  FLOAT           X_Scale;
88
static  FLOAT           Y_Scale;
89
 
90
/*
91
 * Other variables.
92
 */
93
static  FLOAT           Latitude, Longitude;    /* current center of view */
94
static  FLOAT           zoom;           /* current zoom scaling factor */
95
 
96
static  FLOAT           latradius;      /* half of view of latitide */
97
static  FLOAT           longradius;     /* half of view of longitude */
98
static  FLOAT           viewlong;       /* amount of longitide in view */
99
static  FLOAT           viewlat;        /* amount of latitude in view */
100
 
101
static  GR_SIZE         mapwidth;       /* width of map in pixels */
102
static  GR_SIZE         mapheight;      /* height of map in pixels */
103
static  GR_COORD        mapxorig;       /* one half of map width */
104
static  GR_COORD        mapyorig;       /* one half of map height */
105
static  GR_COORD        selectx;        /* x position of current selection */
106
static  GR_COORD        selecty;        /* y position of current selection */
107
static  GR_COORD        selectptrx;     /* x position of pointer in selection */
108
static  GR_COORD        selectptry;     /* y position of pointer in selection */
109
static  GR_SIZE         selectwidth;    /* width of current selection */
110
static  GR_SIZE         selectheight;   /* height of current selection */
111
static  int             selectmode;     /* selection mode */
112
static  GR_BOOL         selectvisible;  /* TRUE if selection is visible on screen */
113
static  GR_SIZE         selectxscale;   /* x scaling factor for selection rectangle */
114
static  GR_SIZE         selectyscale;   /* y scaling factor for selection rectangle */
115
static  GR_BOOL         coordvisible;   /* TRUE if coordinates are visible on screen */
116
static  GR_BOOL         coordenabled;   /* TRUE if coordinate display is enabled */
117
static  GR_COORD        coordx;         /* x position of coordinates */
118
static  GR_COORD        coordy;         /* y position of coordinates */
119
static  GR_COORD        ptrx;           /* latest x position of pointer */
120
static  GR_COORD        ptry;           /* latest y position of pointer */
121
static  char            coordstring[32];        /* coordinate string */
122
 
123
static  GR_WINDOW_ID    mainwid;        /* main window id */
124
static  GR_WINDOW_ID    mapwid;         /* window id for map */
125
static  GR_GC_ID        mapgc;          /* GC used for drawing map */
126
static  GR_GC_ID        xorgc;          /* GC used for rubber banding */
127
static  GR_SIZE         COLS, ROWS;
128
 
129
 
130
/*
131
 * Current selection mode
132
 */
133
#define SELECT_NONE     0
134
#define SELECT_SCALE    1
135
#define SELECT_MOVE     2
136
 
137
/*
138
 * Order of color table (indexed by type of point):
139
 *      unused
140
 *      continents
141
 *      countries
142
 *      unused
143
 *      USA states
144
 *      islands
145
 *      lakes
146
 *      rivers
147
 */
148
static  GR_COLOR        code_colors[] = {
149
        BLACK, GREEN, RED, BLACK, BROWN, GREEN, BLUE, BLUE
150
};
151
 
152
 
153
static  void    load();
154
static  void    setzoom();
155
static  void    checkevent();
156
static  void    doexposure();
157
static  void    dobuttondown();
158
static  void    dobuttonup();
159
static  void    doposition();
160
static  void    dokeydown();
161
static  void    showselection();
162
static  void    showcoords();
163
static  void    mintostr();
164
 
165
 
166
#ifdef __ECOS
167
int
168
world_main(int argc, char **argv)
169
#else
170
int
171
main(int argc, char **argv)
172
#endif
173
{
174
        GR_SCREEN_INFO  si;
175
        GR_WM_PROPERTIES props;
176
 
177
        if (GrOpen() < 0) {
178
                fprintf(stderr, "Cannot open graphics\n");
179
                exit(1);
180
        }
181
 
182
        GrReqShmCmds(65536); /* Test by Morten Rolland for shm support */
183
 
184
        GrGetScreenInfo(&si);
185
#ifdef __ECOS
186
/* 240x320 screen*/
187
COLS = si.cols - 10;
188
ROWS = si.rows - 40;
189
#else
190
COLS = si.cols - 40;
191
ROWS = si.rows - 80;
192
#endif
193
 
194
        mainwid = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0, COLS, ROWS,
195
                0, BLACK, BLACK);
196
 
197
        /* set title */
198
        props.flags = GR_WM_FLAGS_TITLE | GR_WM_FLAGS_PROPS;
199
        props.props = GR_WM_PROPS_BORDER | GR_WM_PROPS_CAPTION;
200
        props.title = "NanoX World Map";
201
        GrSetWMProperties(mainwid, &props);
202
 
203
        mapwidth = COLS - 2;
204
        mapheight = ROWS - 2;
205
        mapxorig = mapwidth / 2;
206
        mapyorig = mapheight / 2;
207
        selectxscale = 4;
208
        selectyscale = 3;
209
        coordx = 0;
210
        coordy = ROWS - 1;
211
        mapwid = GrNewWindow(mainwid, 1, 1, mapwidth, mapheight,
212
#if 0
213
                1, BLACK, WHITE);
214
#else
215
                1, LTGRAY, BLACK);
216
#endif
217
        GrSelectEvents(mainwid, GR_EVENT_MASK_CLOSE_REQ);
218
        GrSelectEvents(mapwid, GR_EVENT_MASK_EXPOSURE |
219
                GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP |
220
                GR_EVENT_MASK_MOUSE_POSITION | GR_EVENT_MASK_KEY_DOWN);
221
 
222
        GrMapWindow(mainwid);
223
        GrMapWindow(mapwid);
224
 
225
        mapgc = GrNewGC();
226
        xorgc = GrNewGC();
227
        GrSetGCMode(xorgc, GR_MODE_XOR);
228
 
229
        Longitude = ITOF(0);
230
        Latitude = ITOF(0);
231
        setzoom(ITOF(1));
232
 
233
        while (1)
234
                checkevent();
235
}
236
 
237
 
238
static void
239
checkevent()
240
{
241
        GR_EVENT        event;
242
 
243
        GrGetNextEvent(&event);
244
        switch (event.type) {
245
                case GR_EVENT_TYPE_EXPOSURE:
246
                        doexposure(&event.exposure);
247
                        break;
248
                case GR_EVENT_TYPE_BUTTON_DOWN:
249
                        dobuttondown(&event.button);
250
                        break;
251
                case GR_EVENT_TYPE_BUTTON_UP:
252
                        dobuttonup(&event.button);
253
                        break;
254
                case GR_EVENT_TYPE_MOUSE_POSITION:
255
                        doposition(&event.mouse);
256
                        break;
257
                case GR_EVENT_TYPE_KEY_DOWN:
258
                        dokeydown(&event.keystroke);
259
                        break;
260
                case GR_EVENT_TYPE_CLOSE_REQ:
261
                        GrClose();
262
                        exit(0);
263
        }
264
}
265
 
266
 
267
static void
268
doexposure(ep)
269
        GR_EVENT_EXPOSURE       *ep;
270
{
271
        if (ep->wid != mapwid)
272
                return;
273
 
274
        /* removed: helps with blink with nanowm*/
275
        /*GrClearWindow(mapwid, GR_FALSE);*/
276
        selectvisible = GR_FALSE;
277
        coordvisible = GR_FALSE;
278
        load(MAPFILE);
279
        showselection(GR_TRUE);
280
        showcoords(GR_TRUE);
281
}
282
 
283
 
284
static void
285
dobuttondown(bp)
286
        GR_EVENT_BUTTON *bp;
287
{
288
        if (bp->wid != mapwid)
289
                return;
290
 
291
        if (bp->changebuttons & SELECTBUTTON) {
292
                showselection(GR_FALSE);
293
                selectx = bp->x;
294
                selecty = bp->y;
295
                selectptrx = bp->x;
296
                selectptry = bp->y;
297
                selectwidth = 0;
298
                selectheight = 0;
299
                selectmode = SELECT_SCALE;
300
                showselection(GR_TRUE);
301
        }
302
 
303
        if (bp->changebuttons & COORDBUTTON) {
304
                showcoords(GR_FALSE);
305
                ptrx = bp->x;
306
                ptry = bp->y;
307
                coordenabled = GR_TRUE;
308
                showcoords(GR_TRUE);
309
        }
310
}
311
 
312
 
313
static void
314
dobuttonup(bp)
315
        GR_EVENT_BUTTON *bp;
316
{
317
        if (bp->wid != mapwid)
318
                return;
319
 
320
        if (bp->changebuttons & COORDBUTTON) {
321
                showcoords(GR_FALSE);
322
                coordenabled = GR_FALSE;
323
        }
324
 
325
        if (bp->changebuttons & SELECTBUTTON) {
326
                showselection(GR_FALSE);
327
                if (selectmode == SELECT_NONE)
328
                        return;
329
                selectmode = SELECT_NONE;
330
                if (selectwidth <= 0)
331
                        return;
332
                Longitude +=
333
                        FIDIV(FIMUL(viewlong, selectx - mapxorig), mapwidth);
334
                Latitude -=
335
                        FIDIV(FIMUL(viewlat, selecty - mapyorig), mapheight);
336
                setzoom(FIDIV(FIMUL(zoom, mapwidth), selectwidth));
337
                GrClearWindow(mapwid, GR_TRUE);
338
        }
339
}
340
 
341
 
342
static void
343
doposition(mp)
344
        GR_EVENT_MOUSE  *mp;
345
{
346
        GR_SIZE temp;
347
 
348
        if (mp->wid != mapwid)
349
                return;
350
 
351
        if (coordenabled) {
352
                showcoords(GR_FALSE);
353
                ptrx = mp->x;
354
                ptry = mp->y;
355
                showcoords(GR_TRUE);
356
        }
357
 
358
        showselection(GR_FALSE);
359
        switch (selectmode) {
360
                case SELECT_SCALE:
361
                        selectwidth = ABS(mp->x - selectx) * 2 + 1;
362
                        selectheight = ABS(mp->y - selecty) * 2 + 1;
363
                        temp = ((long) selectwidth) * selectyscale
364
                                / selectxscale;
365
                        if (selectheight < temp)
366
                                selectheight = temp;
367
                        temp = ((long) selectheight) * selectxscale
368
                                / selectyscale;
369
                        if (selectwidth < temp)
370
                                selectwidth = temp;
371
                        break;
372
 
373
                case SELECT_MOVE:
374
                        selectx += (mp->x - selectptrx);
375
                        selecty += (mp->y - selectptry);
376
                        break;
377
        }
378
 
379
        selectptrx = mp->x;
380
        selectptry = mp->y;
381
        showselection(GR_TRUE);
382
}
383
 
384
 
385
static void
386
dokeydown(kp)
387
        GR_EVENT_KEYSTROKE      *kp;
388
{
389
        if (kp->wid != mapwid)
390
                return;
391
 
392
        if (selectmode != SELECT_NONE) {
393
                switch (kp->ch) {
394
                        case 's':       /* scale selection */
395
                                selectmode = SELECT_SCALE;
396
                                break;
397
 
398
                        case 'm':       /* move selection */
399
                                selectmode = SELECT_MOVE;
400
                                break;
401
 
402
                        case '\033':    /* cancel selection */
403
                                showselection(GR_FALSE);
404
                                selectmode = SELECT_NONE;
405
                                break;
406
                }
407
                return;
408
        }
409
 
410
        switch (kp->ch) {
411
                case 'q':               /* quit */
412
                case 'Q':
413
                        GrClose();
414
                        exit(0);
415
 
416
                case 't':               /* redraw total map */
417
                        Longitude = ITOF(0);
418
                        Latitude = ITOF(0);
419
                        setzoom(ITOF(1));
420
                        GrClearWindow(mapwid, GR_TRUE);
421
        }
422
}
423
 
424
 
425
/*
426
 * Draw or erase the current selection if any is defined.
427
 * The selection is a rectangle centered on a specified point, and with a
428
 * specified width and height.  Drawing and erasing the selection are the
429
 * same drawing operation because of the XOR operation.
430
 */
431
static void
432
showselection(show)
433
        GR_BOOL show;           /* TRUE if show the selection */
434
{
435
        if ((show == 0) == (selectvisible == 0))
436
                return;
437
        if (selectmode == SELECT_NONE)
438
                return;
439
        GrRect(mapwid, xorgc, selectx - selectwidth / 2,
440
                selecty - selectheight / 2, selectwidth, selectheight);
441
        selectvisible = show;
442
}
443
 
444
 
445
/*
446
 * Draw or erase the coordinate string of the current pointer position.
447
 * Both of these are the same operation because of the XOR operation.
448
 */
449
static void
450
showcoords(show)
451
        GR_BOOL show;           /* TRUE if show the coordinates */
452
{
453
        long    curlong;
454
        long    curlat;
455
        FLOAT   ptrlat;
456
        FLOAT   ptrlong;
457
 
458
        if (((show == 0) == (coordvisible == 0)) || !coordenabled)
459
                return;
460
 
461
        if (show) {
462
                ptrlat = FIDIV(FIMUL(viewlat, ptry), mapheight - 1);
463
                ptrlong = FIDIV(FIMUL(viewlong, ptrx), mapwidth - 1);
464
 
465
                curlat = FTOI(Latitude + latradius - ptrlat);
466
                curlong = FTOI(Longitude - longradius + ptrlong);
467
 
468
                if (curlong > 180*60)
469
                        curlong -= 360*60;
470
                if (curlong < -180*60)
471
                        curlong += 360*60;
472
 
473
                mintostr(coordstring, curlong);
474
                strcat(coordstring, "  ");
475
                mintostr(coordstring + strlen(coordstring), curlat);
476
        }
477
 
478
        GrText(mapwid, xorgc, coordx, coordy, coordstring, -1, GR_TFBOTTOM);
479
        coordvisible = show;
480
}
481
 
482
 
483
/*
484
 * Convert minutes to a string of the form "ddd'mm" and store it
485
 * into the indicated buffer.
486
 */
487
static void
488
mintostr(buf, minutes)
489
        char    *buf;
490
        long    minutes;
491
{
492
        if (minutes < 0) {
493
                minutes = -minutes;
494
                *buf++ = '-';
495
        }
496
        sprintf(buf, "%ld'%02ld", (long)(minutes / 60), (long)(minutes % 60));
497
}
498
 
499
 
500
#if 0
501
/*
502
 * Convert "ddd'mm" to mins
503
 */
504
static long
505
degtomin(s)
506
        char    *s;
507
{
508
        int     deg, minutes;
509
        char    str[10],*strchr(),*cp;
510
 
511
        strcpy(str,s);
512
        if (cp = strchr(str,'\047')) {
513
                *cp = '\0';
514
                minutes = atoi(++cp);
515
        } else
516
                minutes = 0;
517
        if ((deg = atoi(str)) < 0)
518
                minutes = -minutes;
519
        return(deg * 60 + minutes);
520
}
521
#endif
522
 
523
 
524
/*
525
 * Set the scale factors for the given zoom factor.
526
 * The factors 3 and 4 are here to compensate for the screen aspect ratio.
527
 */
528
static void
529
setzoom(newzoom)
530
        FLOAT   newzoom;
531
{
532
        zoom = newzoom;
533
 
534
        Y_Scale = FIDIV(FIMUL(zoom, mapheight * 3), 180 * 4);
535
        X_Scale = FIDIV(FIMUL(zoom, mapwidth), 360);
536
 
537
        viewlong = FFDIV(WSPAN, zoom);
538
        viewlat = FFDIV(HSPAN * 4 / 3, zoom);
539
        longradius = FIDIV(viewlong, 2);
540
        latradius = FIDIV(viewlat, 2);
541
}
542
 
543
 
544
/*
545
 * Read the database file and draw the world.
546
 */
547
static void
548
load(fn)
549
        char    *fn;
550
{
551
        register DBPOINT        *pp;
552
        DBPOINT         *pend;
553
        FLOAT           x, y, LonPrv, LatPrv;
554
        long            oldlong = 0L;
555
        GR_COORD        xnew, ynew;
556
        GR_COORD        xold = 0, yold = 0;
557
        GR_BOOL         is_out;
558
        GR_BOOL         was_out;
559
        GR_BOOL         newseg = GR_FALSE;
560
        GR_COLOR        oldcolor;
561
        GR_COLOR        newcolor;
562
        int             n;
563
        int             fh;
564
        DBPOINT         p[PCount];
565
 
566
        LonPrv = ITOF(0);
567
        LatPrv = ITOF(0);
568
        oldcolor = -1;
569
        is_out = GR_FALSE;
570
        was_out = GR_FALSE;
571
 
572
        fh = open(fn, O_BINARY | O_RDONLY);
573
        if (fh < 0) {
574
                GrClose();
575
                fprintf(stderr, "Cannot open %s\n", fn);
576
                exit(1);
577
        }
578
 
579
        while ((n = read(fh, p, PCount * POINTSize)) > 0) {
580
                for (pp = p,pend = p + n/POINTSize; pp < pend; pp++)
581
                {
582
                        DBPOINT_CONVERT(pp);
583
                        /* do displacement */
584
                        x = ITOF(pp->Lon) - Longitude;
585
                        y = ITOF(pp->Lat) - Latitude;
586
 
587
                        /* wrap around for East-West */
588
                        if (x < -HSPAN)
589
                                x += WSPAN;
590
                        if (x > HSPAN)
591
                                x -= WSPAN;
592
 
593
                        if (pp->Code > 5) {
594
                                newcolor = code_colors[pp->Code / 1000];
595
                                if (newcolor != oldcolor) {
596
                                        oldcolor = newcolor;
597
                                        GrSetGCForeground(mapgc, oldcolor);
598
                                }
599
                                newseg = GR_TRUE;
600
                        }
601
 
602
                        if (oldcolor == BLACK)
603
                                goto go_on;
604
 
605
                        /* ignore points outside magnified area */
606
                        if ((x < -longradius || x > longradius ||
607
                                y < -latradius || y > latradius))
608
                        {
609
                                is_out = 1;
610
                                if (was_out) {          /* out to out */
611
                                        LonPrv = x;
612
                                        LatPrv = y;
613
                                        goto go_on;
614
                                }
615
 
616
                                /* in to out */
617
                                xold = mapxorig + FTOI(FFMUL(LonPrv, X_Scale)) / 60;
618
                                yold = mapyorig - FTOI(FFMUL(LatPrv, Y_Scale)) / 60;
619
                        } else {                        /* out to in */
620
                                is_out = 0;
621
                                if (was_out) {
622
                                        xold = mapxorig +
623
                                                FTOI(FFMUL(LonPrv, X_Scale)) / 60;
624
                                        yold = mapyorig -
625
                                                FTOI(FFMUL(LatPrv, Y_Scale)) / 60;
626
                                }
627
                                /* in to in */
628
                        }
629
                        LonPrv = x;
630
                        LatPrv = y;
631
 
632
                        /* scale points w/in area to interlace screen */
633
                        xnew = mapxorig + FTOI(FFMUL(x, X_Scale)) / 60;
634
                        ynew = mapyorig - FTOI(FFMUL(y, Y_Scale)) / 60;
635
 
636
                        /* if new segment, move to place */
637
                        if (newseg || ABS(oldlong - pp->Lon) > 180*60) {
638
                                xold = xnew;
639
                                yold = ynew;
640
                        }
641
                        oldlong = pp->Lon;
642
 
643
                        GrLine(mapwid, mapgc, xold, yold, xnew, ynew);
644
                        xold = xnew;
645
                        yold = ynew;
646
go_on:
647
                        was_out = is_out;
648
                        newseg = GR_FALSE;
649
                }
650
        }
651
        close(fh);
652
}
653
 
654
/* END CODE */

powered by: WebSVN 2.1.0

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