ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/main_Acorn.h
Revision: 1.2
Committed: 2003-07-01T17:51:17Z (20 years, 9 months ago) by cebix
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
updated copyright date

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * main_Acorn.h - Main program, RISC OS specific stuff
3     *
4 cebix 1.2 * Frodo (C) 1994-1997,2002-2003 Christian Bauer
5 cebix 1.1 *
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     if (load_rom_files())
522     {
523     TheC64->Run();
524     }
525     delete TheC64; TheC64 = NULL;
526     }
527    
528    
529    
530    
531    
532     extern void (*__new_handler)(void);
533    
534     // Out of memory
535     void OutOfMemory(void)
536     {
537     _kernel_oserror err;
538    
539    
540     err.errnum = 0; sprintf(err.errmess,"Out of memory error! Aborting.");
541     Wimp_ReportError(&err,1,TASKNAME);
542     delete the_app;
543     Wimp_CloseDown(TaskHandle,TASK_WORD);
544     exit(1);
545     }
546    
547    
548    
549    
550     // Frodo main
551     int main(int argc, char *argv[])
552     {
553     #ifdef __GNUG__
554     // Switch off filename conversions in UnixLib:
555     //__uname_control = __UNAME_NO_PROCESS;
556     #endif
557    
558     #ifdef FRODO_SC
559     TaskHandle = Wimp_Initialise(310,TASK_WORD,"FrodoSC",(int*)WimpMessages);
560     #else
561     # ifdef FRODO_PC
562     TaskHandle = Wimp_Initialise(310,TASK_WORD,"FrodoPC",(int*)WimpMessages);
563     # else
564     TaskHandle = Wimp_Initialise(310,TASK_WORD,"Frodo",(int*)WimpMessages);
565     # endif
566     #endif
567    
568     // Install handler for failed new
569     __new_handler = OutOfMemory;
570    
571     the_app = new Frodo();
572     the_app->ReadyToRun();
573     // Clean up directory scrap file
574     DeleteFile(RO_TEMPFILE);
575     delete the_app;
576     Wimp_CloseDown(TaskHandle,TASK_WORD);
577     return(0);
578     }