ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/main_Acorn.h
Revision: 1.5
Committed: 2005-06-27T19:55:48Z (19 years, 4 months ago) by cebix
Content type: text/plain
Branch: MAIN
CVS Tags: VERSION_4_2, HEAD
Changes since 1.4: +1 -1 lines
Log Message:
updated copyright dates

File Contents

# Content
1 /*
2 * main_Acorn.h - Main program, RISC OS specific stuff
3 *
4 * Frodo (C) 1994-1997,2002-2005 Christian Bauer
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "ROlib.h"
22 #include "AcornGUI.h"
23
24
25 // Shared, system-specific data
26 // The application
27 Frodo *the_app;
28
29 // My task handle
30 unsigned int TaskHandle;
31
32 int WimpMessages[] = {
33 Message_DataSave, Message_DataSaveAck, Message_DataLoad, Message_DataLoadAck,
34 Message_DataOpen, Message_PaletteChange, Message_ModeChange, Message_MenuWarning, 0
35 };
36
37
38
39
40 // RORes member-functions - very simple reading of screen res and eigen
41 RORes::RORes(void)
42 {
43 resx = OS_ReadModeVariable(-1,11); resy = OS_ReadModeVariable(-1,12);
44 eigx = OS_ReadModeVariable(-1,4) ; eigy = OS_ReadModeVariable(-1,5);
45 resx = (resx+1)<<eigx; resy = (resy+1)<<eigy;
46 }
47
48 RORes::~RORes(void) {;}
49
50
51
52
53
54 // ROScreen member-functions - handle currently selected screenmode
55 ROScreen::ROScreen(void)
56 {
57 if (ReadMode() != 0)
58 {
59 ModeError.errnum = 0x0; strcpy((char*)&ModeError.errmess,"Can't read mode data!");
60 Wimp_ReportError(&ModeError,1,TASKNAME);
61 }
62 }
63
64
65 ROScreen::~ROScreen(void) {;}
66
67
68 // read data for current screenmode, returns 0 if OK, > 0 if error
69 int ROScreen::ReadMode(void)
70 {
71 register int h=0;
72
73 if ((resx = OS_ReadModeVariable(-1,11)) < 0) h++;
74 if ((resy = OS_ReadModeVariable(-1,12)) < 0) h++;
75 if ((eigx = OS_ReadModeVariable(-1,4)) < 0) h++;
76 if ((eigy = OS_ReadModeVariable(-1,5)) < 0) h++;
77 resx = (resx+1)<<eigx; resy = (resy+1)<<eigy;
78 if ((ldbpp = OS_ReadModeVariable(-1,9)) < 0) h++;
79 if ((ladd = OS_ReadModeVariable(-1,6)) < 0) h++;
80 scrbase = (char*)OS_ReadDynamicArea(2);
81 if (eigx > eigy)
82 {
83 ModeError.errnum = 0x0;
84 sprintf((char*)ModeError.errmess,"Can't handle screen modes with eigen_x > eigen_y!");
85 Wimp_ReportError(&ModeError,1,TASKNAME);
86 }
87 return(h);
88 }
89
90
91
92
93 // Window member-functions - handle all things concerned with windows
94 // WDesc is a pointer to a complete window descriptor (incl. Handle at pos 0!)
95 Window::Window(const int *WDesc, const char *Title)
96 {
97 register int h;
98
99 wind = (RO_Window *)WDesc;
100 if (Title != NULL)
101 {
102 if ((wind->tflags & IFlg_Indir) != 0)
103 {
104 strcpy((char*)(wind->dat.ind.tit),Title); // indirected
105 }
106 else {strncpy((char *)&wind->dat,Title,12);}
107 }
108 if ((wind->Handle = Wimp_CreateWindow((int*)&wind->vminx)) == 0)
109 {
110 _kernel_oserror WindError;
111
112 WindError.errnum = 0x0; strcpy((char*)WindError.errmess,"Can't create window!");
113 Wimp_ReportError(&WindError,1,TASKNAME);
114 }
115 // Isopen is unreliable. Works only if the window is never opened/closed by other
116 // means than calling the member-functions. For 100% accuracy use OpenStatus().
117 isopen = false;
118 }
119
120
121 Window::~Window(void)
122 {
123 Wimp_DeleteWindow((int*)wind);
124 }
125
126
127 int Window::MyHandle(void)
128 {
129 return(wind->Handle);
130 }
131
132
133 void Window::GetWorkArea(int *Dest)
134 {
135 Dest[0] = wind->wminx; Dest[1] = wind->wminy;
136 Dest[2] = wind->wmaxx; Dest[3] = wind->wmaxy;
137 }
138
139
140 void Window::open(void) {isopen = true; Wimp_OpenWindow((int*)wind);}
141
142
143 void Window::open(int *Block) {isopen = true; Wimp_OpenWindow(Block);}
144
145
146 void Window::close(void) {isopen = false; Wimp_CloseWindow((int*)wind);}
147
148
149 void Window::forceredraw(int minx, int miny, int maxx, int maxy)
150 {
151 Wimp_ForceRedraw(wind->Handle,minx,miny,maxx,maxy);
152 }
153
154
155 void Window::redraw(int *Block, uint8 *Bitmap, C64Display *Disp)
156 {
157 int more;
158
159 more = Wimp_RedrawWindow(Block);
160 while (more != 0)
161 {
162 RedrawAWindow(Block,Bitmap,Disp);
163 more = Wimp_GetRectangle(Block);
164 }
165 }
166
167
168 // Block contains the coordinates to update, the handle is entered by this
169 // memberfunction
170 void Window::update(int *Block, uint8 *Bitmap, C64Display *Disp)
171 {
172 int more;
173
174 Block[0] = wind->Handle;
175 more = Wimp_UpdateWindow(Block);
176 while (more != 0)
177 {
178 RedrawAWindow(Block,Bitmap,Disp);
179 more = Wimp_GetRectangle(Block);
180 }
181 }
182
183
184 // This updated the entire window
185 void Window::update(uint8 *Bitmap, C64Display *Disp)
186 {
187 int more;
188 int Block[11];
189
190 Block[0] = wind->Handle;
191 GetWorkArea(Block+1);
192 more = Wimp_UpdateWindow(Block);
193 while (more != 0)
194 {
195 RedrawAWindow(Block,Bitmap,Disp);
196 more = Wimp_GetRectangle(Block);
197 }
198 }
199
200
201 void Window::extent(int minx, int miny, int maxx, int maxy)
202 {
203 int extent[4];
204
205 extent[0] = minx; extent[1] = miny; extent[2] = maxx; extent[3] = maxy;
206 Wimp_SetExtent(wind->Handle,(int*)extent);
207 // update internal window info as well
208 wind->wminx = minx; wind->wminy = miny;
209 wind->wmaxx = maxx; wind->wmaxy = maxy;
210 }
211
212
213 void Window::getstate(void) {Wimp_GetWindowState((int*)wind);}
214
215
216 void Window::getstate(int *dest)
217 {
218 dest[0] = wind->Handle;
219 Wimp_GetWindowState(dest);
220 }
221
222
223 // The actual redrawing: if the bitmap pointer is not NULL the bitmap is
224 // painted into the window.
225 void Window::RedrawAWindow(int *Block, uint8 *Bitmap, C64Display *Disp)
226 {
227 if (Bitmap != NULL)
228 {
229 // Plot the bitmap into the window
230 graph_env ge;
231 unsigned int *ct;
232
233 // Coordinates are TOP left of rectangle (not bottom, like in RO)
234 ge.x = Block[RedrawB_VMinX] - Block[RedrawB_ScrollX];
235 ge.y = Block[RedrawB_VMaxY] - Block[RedrawB_ScrollY];
236 ge.dimx = DISPLAY_X; ge.dimy = DISPLAY_Y;
237 ct = Disp->GetColourTable();
238
239 if (Disp->TheC64->TheWIMP->ReadEmuWindowSize() == 1)
240 {
241 PlotZoom1(&ge,&Block[RedrawB_CMinX],Bitmap,ct);
242 }
243 else
244 {
245 PlotZoom2(&ge,&Block[RedrawB_CMinX],Bitmap,ct);
246 }
247 }
248 }
249
250
251 // Returns a pointer to a window's icon (or NULL of invalid number)
252 RO_Icon *Window::GetIcon(unsigned int number)
253 {
254 if (number > wind->icon_no) {return(NULL);}
255 return((RO_Icon*)(((int*)wind) + RO_WINDOW_WORDS + RO_ICON_WORDS*number));
256 }
257
258
259 void Window::SetIconState(unsigned int number, unsigned int eor, unsigned int clear)
260 {
261 int Block[4];
262
263 Block[0] = wind->Handle; Block[1] = number; Block[2] = eor; Block[3] = clear;
264 Wimp_SetIconState((int*)Block);
265 }
266
267
268 void Window::GetIconState(unsigned int number, int *Block)
269 {
270 Block[0] = wind->Handle; Block[1] = number;
271 Wimp_GetIconState(Block);
272 }
273
274
275 // Returns true if this window has the input focus
276 bool Window::HaveInput(void)
277 {
278 RO_Caret Store;
279
280 Wimp_GetCaretPosition(&Store);
281 return(Store.WHandle == wind->Handle);
282 }
283
284
285 // Writes text into an indirected icon
286 void Window::WriteIconText(unsigned int number, const char *text)
287 {
288 RO_Icon *ic;
289
290 if ((ic = GetIcon(number)) != NULL)
291 {
292 // This only makes sense for indirected icons!
293 if ((ic->iflags & IFlg_Indir) != 0)
294 {
295 strncpy((char*)ic->dat.ind.tit,text,ic->dat.ind.len);
296 ForceIconRedraw(number);
297 }
298 }
299 }
300
301
302 // The same but update the window (i.e. immediate result)
303 void Window::WriteIconTextU(unsigned int number, const char *text)
304 {
305 RO_Icon *ic;
306
307 if ((ic = GetIcon(number)) != NULL)
308 {
309 if ((ic->iflags & IFlg_Indir) != 0)
310 {
311 strncpy((char*)ic->dat.ind.tit,text,ic->dat.ind.len);
312 UpdateIcon(number);
313 }
314 }
315 }
316
317
318 // Writes the value as a decimal string into the indirected icon
319 void Window::WriteIconNumber(unsigned int number, int value)
320 {
321 RO_Icon *ic;
322
323 if ((ic = GetIcon(number)) != NULL)
324 {
325 if ((ic->iflags & IFlg_Indir) != 0)
326 {
327 ConvertInteger4(value,(char*)ic->dat.ind.tit,ic->dat.ind.len);
328 ForceIconRedraw(number);
329 }
330 }
331 }
332
333
334 // The same but update the window
335 void Window::WriteIconNumberU(unsigned int number, int value)
336 {
337 RO_Icon *ic;
338
339 if ((ic = GetIcon(number)) != NULL)
340 {
341 if ((ic->iflags & IFlg_Indir) != 0)
342 {
343 ConvertInteger4(value,(char*)ic->dat.ind.tit,ic->dat.ind.len);
344 UpdateIcon(number);
345 }
346 }
347 }
348
349
350 // Returns a pointer to the text in the icon
351 char *Window::ReadIconText(unsigned int number)
352 {
353 RO_Icon *ic;
354
355 if ((ic = GetIcon(number)) != NULL)
356 {
357 // only indirected icons!
358 if ((ic->iflags & IFlg_Indir) != 0) {return((char*)ic->dat.ind.tit);}
359 }
360 return(NULL);
361 }
362
363
364 // Reads the number in an indirected icon.
365 int Window::ReadIconNumber(unsigned int number)
366 {
367 RO_Icon *ic;
368
369 if ((ic = GetIcon(number)) != NULL)
370 {
371 if ((ic->iflags & IFlg_Indir) != 0)
372 {
373 return(atoi((char*)ic->dat.ind.tit));
374 }
375 }
376 return(-1); // rather arbitrary, but we only have positive numbers here...
377 }
378
379
380 void Window::WriteTitle(const char *title)
381 {
382 // only indirected window titles, must contain text
383 if ((wind->tflags & (IFlg_Indir | IFlg_Text)) == (IFlg_Indir | IFlg_Text))
384 {
385 strcpy((char*)wind->dat.ind.tit,title);
386 UpdateTitle();
387 }
388 }
389
390
391 char *Window::ReadTitle(void)
392 {
393 if ((wind->tflags & (IFlg_Indir | IFlg_Text)) == (IFlg_Indir | IFlg_Text))
394 {
395 return((char*)wind->dat.ind.tit);
396 }
397 else {return(NULL);}
398 }
399
400
401 // Forces a redraw of the window title
402 void Window::UpdateTitle(void)
403 {
404 getstate();
405 // Force global redraw (in screen-coordinates)
406 Wimp_ForceRedraw(-1, wind->vminx, wind->vmaxy, wind->vmaxx, wind->vmaxy + TitleBarHeight);
407 }
408
409
410 RO_Window *Window::Descriptor(void) {return(wind);}
411
412
413 // Force a redraw on an icon (visible after the next Poll)
414 void Window::ForceIconRedraw(unsigned int number)
415 {
416 if (number <= wind->icon_no)
417 {
418 register RO_Icon *ic;
419
420 ic = GetIcon(number);
421 forceredraw(ic->minx, ic->miny, ic->maxx, ic->maxy);
422 }
423 }
424
425
426 // Update an icon (visible immediately -- works only on purely WIMP-drawn icons!)
427 void Window::UpdateIcon(unsigned int number)
428 {
429 if (number <= wind->icon_no)
430 {
431 register RO_Icon *ic;
432 int Block[11]; // redraw block
433 int more;
434
435 ic = GetIcon(number);
436 Block[RedrawB_Handle] = wind->Handle;
437 Block[RedrawB_VMinX] = ic->minx; Block[RedrawB_VMinY] = ic->miny;
438 Block[RedrawB_VMaxX] = ic->maxx; Block[RedrawB_VMaxY] = ic->maxy;
439 more = Wimp_UpdateWindow(Block); // standard redraw loop
440 while (more != 0)
441 {
442 more = Wimp_GetRectangle(Block);
443 }
444 }
445 }
446
447
448 // returns the current open-state of the window (true if open)
449 bool Window::OpenStatus(void)
450 {
451 getstate();
452 return(((wind->wflags & (1<<16)) == 0) ? false : true);
453 }
454
455
456 // Same as above, but reads the current state to Block
457 bool Window::OpenStatus(int *Block)
458 {
459 getstate(Block);
460 return(((Block[8] & (1<<16)) == 0) ? false : true);
461 }
462
463
464
465
466
467
468
469 // Icon member-functions - handle all things concerned with icons
470 Icon::Icon(int Priority, const RO_IconDesc *IDesc)
471 {
472 memcpy((char*)&icon,(char*)IDesc,sizeof(RO_IconDesc));
473 IHandle = Wimp_CreateIcon(Priority,IDesc);
474 }
475
476
477 Icon::~Icon(void)
478 {
479 int blk[2];
480
481 blk[0] = icon.WindowHandle; blk[1] = IHandle;
482 Wimp_DeleteIcon((int*)blk);
483 }
484
485
486 void Icon::setstate(unsigned int eor, unsigned int clear)
487 {
488 int blk[4];
489
490 blk[0] = icon.WindowHandle; blk[1] = IHandle; blk[2] = eor; blk[3] = clear;
491 Wimp_SetIconState((int*)blk);
492 }
493
494
495 void Icon::getstate(void)
496 {
497 int blk[10];
498
499 blk[0] = icon.WindowHandle; blk[1] = IHandle;
500 Wimp_GetIconState((int*)blk);
501 memcpy((char*)&icon,(int*)&blk[2],sizeof(RO_Icon));
502 }
503
504
505
506
507 // Frodo member functions
508 Frodo::Frodo(void) {TheC64 = NULL;}
509
510
511 Frodo::~Frodo(void)
512 {
513 if (TheC64 != NULL) {delete TheC64;}
514 }
515
516
517 void Frodo::ReadyToRun(void)
518 {
519 ThePrefs.Load(DEFAULT_PREFS);
520 TheC64 = new C64;
521 load_rom_files();
522 TheC64->Run();
523 delete TheC64; TheC64 = NULL;
524 }
525
526
527
528
529
530 extern void (*__new_handler)(void);
531
532 // Out of memory
533 void OutOfMemory(void)
534 {
535 _kernel_oserror err;
536
537
538 err.errnum = 0; sprintf(err.errmess,"Out of memory error! Aborting.");
539 Wimp_ReportError(&err,1,TASKNAME);
540 delete the_app;
541 Wimp_CloseDown(TaskHandle,TASK_WORD);
542 exit(1);
543 }
544
545
546
547
548 // Frodo main
549 int main(int argc, char *argv[])
550 {
551 #ifdef __GNUG__
552 // Switch off filename conversions in UnixLib:
553 //__uname_control = __UNAME_NO_PROCESS;
554 #endif
555
556 #ifdef FRODO_SC
557 TaskHandle = Wimp_Initialise(310,TASK_WORD,"FrodoSC",(int*)WimpMessages);
558 #else
559 # ifdef FRODO_PC
560 TaskHandle = Wimp_Initialise(310,TASK_WORD,"FrodoPC",(int*)WimpMessages);
561 # else
562 TaskHandle = Wimp_Initialise(310,TASK_WORD,"Frodo",(int*)WimpMessages);
563 # endif
564 #endif
565
566 // Install handler for failed new
567 __new_handler = OutOfMemory;
568
569 the_app = new Frodo();
570 the_app->ReadyToRun();
571 // Clean up directory scrap file
572 DeleteFile(RO_TEMPFILE);
573 delete the_app;
574 Wimp_CloseDown(TaskHandle,TASK_WORD);
575 return(0);
576 }