Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

main_Acorn.i

Go to the documentation of this file.
00001 /*
00002  * main_Acorn.i
00003  *
00004  * RISC OS specific stuff
00005  * Frodo (C) 1994-1997 Christian Bauer
00006  * Acorn port by Andreas Dehmel, 1997
00007  *
00008  */
00009 
00010 
00011 #include "ROlib.h"
00012 #include "AcornGUI.h"
00013 
00014 
00015 
00016 
00017 
00018 // Shared, system-specific data
00019 // The application
00020 Frodo *the_app;
00021 
00022 // My task handle
00023 unsigned int TaskHandle;
00024 
00025 int WimpMessages[] = {
00026   Message_DataSave, Message_DataSaveAck, Message_DataLoad, Message_DataLoadAck,
00027   Message_DataOpen, Message_PaletteChange, Message_ModeChange, Message_MenuWarning, 0
00028 };
00029 
00030 
00031 
00032 
00033 // RORes member-functions - very simple reading of screen res and eigen
00034 RORes::RORes(void)
00035 {
00036   resx = OS_ReadModeVariable(-1,11); resy = OS_ReadModeVariable(-1,12);
00037   eigx = OS_ReadModeVariable(-1,4) ; eigy = OS_ReadModeVariable(-1,5);
00038   resx = (resx+1)<<eigx; resy = (resy+1)<<eigy;
00039 }
00040 
00041 RORes::~RORes(void) {;}
00042 
00043 
00044 
00045 
00046 
00047 // ROScreen member-functions - handle currently selected screenmode
00048 ROScreen::ROScreen(void)
00049 {
00050   if (ReadMode() != 0)
00051   {
00052     ModeError.errnum = 0x0; strcpy((char*)&ModeError.errmess,"Can't read mode data!");
00053     Wimp_ReportError(&ModeError,1,TASKNAME);
00054   }
00055 }
00056 
00057 
00058 ROScreen::~ROScreen(void) {;}
00059 
00060 
00061 // read data for current screenmode, returns 0 if OK, > 0 if error
00062 int ROScreen::ReadMode(void)
00063 {
00064   register int h=0;
00065 
00066   if ((resx = OS_ReadModeVariable(-1,11)) < 0) h++;
00067   if ((resy = OS_ReadModeVariable(-1,12)) < 0) h++;
00068   if ((eigx = OS_ReadModeVariable(-1,4))  < 0) h++;
00069   if ((eigy = OS_ReadModeVariable(-1,5))  < 0) h++;
00070   resx = (resx+1)<<eigx; resy = (resy+1)<<eigy;
00071   if ((ldbpp = OS_ReadModeVariable(-1,9)) < 0) h++;
00072   if ((ladd  = OS_ReadModeVariable(-1,6)) < 0) h++;
00073   scrbase = (char*)OS_ReadDynamicArea(2);
00074   if (eigx > eigy)
00075   {
00076     ModeError.errnum = 0x0;
00077     sprintf((char*)ModeError.errmess,"Can't handle screen modes with eigen_x > eigen_y!");
00078     Wimp_ReportError(&ModeError,1,TASKNAME);
00079   }
00080   return(h);
00081 }
00082 
00083 
00084 
00085 
00086 // Window member-functions - handle all things concerned with windows
00087 // WDesc is a pointer to a complete window descriptor (incl. Handle at pos 0!)
00088 Window::Window(const int *WDesc, const char *Title)
00089 {
00090   register int h;
00091 
00092   wind = (RO_Window *)WDesc;
00093   if (Title != NULL)
00094   {
00095     if ((wind->tflags & IFlg_Indir) != 0)
00096     {
00097       strcpy((char*)(wind->dat.ind.tit),Title);         // indirected
00098     }
00099     else {strncpy((char *)&wind->dat,Title,12);}
00100   }
00101   if ((wind->Handle = Wimp_CreateWindow((int*)&wind->vminx)) == 0)
00102   {
00103     _kernel_oserror WindError;
00104 
00105     WindError.errnum = 0x0; strcpy((char*)WindError.errmess,"Can't create window!");
00106     Wimp_ReportError(&WindError,1,TASKNAME);
00107   }
00108   // Isopen is unreliable. Works only if the window is never opened/closed by other
00109   // means than calling the member-functions. For 100% accuracy use OpenStatus().
00110   isopen = false;
00111 }
00112 
00113 
00114 Window::~Window(void)
00115 {
00116   Wimp_DeleteWindow((int*)wind);
00117 }
00118 
00119 
00120 int  Window::MyHandle(void)
00121 {
00122   return(wind->Handle);
00123 }
00124 
00125 
00126 void  Window::GetWorkArea(int *Dest)
00127 {
00128   Dest[0] = wind->wminx; Dest[1] = wind->wminy;
00129   Dest[2] = wind->wmaxx; Dest[3] = wind->wmaxy;
00130 }
00131 
00132 
00133 void Window::open(void) {isopen = true; Wimp_OpenWindow((int*)wind);}
00134 
00135 
00136 void Window::open(int *Block) {isopen = true; Wimp_OpenWindow(Block);}
00137 
00138 
00139 void Window::close(void) {isopen = false; Wimp_CloseWindow((int*)wind);}
00140 
00141 
00142 void Window::forceredraw(int minx, int miny, int maxx, int maxy)
00143 {
00144   Wimp_ForceRedraw(wind->Handle,minx,miny,maxx,maxy);
00145 }
00146 
00147 
00148 void Window::redraw(int *Block, uint8 *Bitmap, C64Display *Disp)
00149 {
00150   int more;
00151 
00152   more = Wimp_RedrawWindow(Block);
00153   while (more != 0)
00154   {
00155     RedrawAWindow(Block,Bitmap,Disp);
00156     more = Wimp_GetRectangle(Block);
00157   }
00158 }
00159 
00160 
00161 // Block contains the coordinates to update, the handle is entered by this
00162 // memberfunction
00163 void Window::update(int *Block, uint8 *Bitmap, C64Display *Disp)
00164 {
00165   int more;
00166 
00167   Block[0] = wind->Handle;
00168   more = Wimp_UpdateWindow(Block);
00169   while (more != 0)
00170   {
00171     RedrawAWindow(Block,Bitmap,Disp);
00172     more = Wimp_GetRectangle(Block);
00173   }
00174 }
00175 
00176 
00177 // This updated the entire window
00178 void Window::update(uint8 *Bitmap, C64Display *Disp)
00179 {
00180   int more;
00181   int Block[11];
00182 
00183   Block[0] = wind->Handle;
00184   GetWorkArea(Block+1);
00185   more = Wimp_UpdateWindow(Block);
00186   while (more != 0)
00187   {
00188     RedrawAWindow(Block,Bitmap,Disp);
00189     more = Wimp_GetRectangle(Block);
00190   }
00191 }
00192 
00193 
00194 void Window::extent(int minx, int miny, int maxx, int maxy)
00195 {
00196   int extent[4];
00197 
00198   extent[0] = minx; extent[1] = miny; extent[2] = maxx; extent[3] = maxy;
00199   Wimp_SetExtent(wind->Handle,(int*)extent);
00200   // update internal window info as well
00201   wind->wminx = minx; wind->wminy = miny;
00202   wind->wmaxx = maxx; wind->wmaxy = maxy;
00203 }
00204 
00205 
00206 void Window::getstate(void) {Wimp_GetWindowState((int*)wind);}
00207 
00208 
00209 void Window::getstate(int *dest)
00210 {
00211   dest[0] = wind->Handle;
00212   Wimp_GetWindowState(dest);
00213 }
00214 
00215 
00216 // The actual redrawing: if the bitmap pointer is not NULL the bitmap is
00217 // painted into the window.
00218 void Window::RedrawAWindow(int *Block, uint8 *Bitmap, C64Display *Disp)
00219 {
00220   if (Bitmap != NULL)
00221   {
00222     // Plot the bitmap into the window
00223     graph_env ge;
00224     unsigned int *ct;
00225 
00226     // Coordinates are TOP left of rectangle (not bottom, like in RO)
00227     ge.x = Block[RedrawB_VMinX] - Block[RedrawB_ScrollX];
00228     ge.y = Block[RedrawB_VMaxY] - Block[RedrawB_ScrollY];
00229     ge.dimx = DISPLAY_X; ge.dimy = DISPLAY_Y;
00230     ct = Disp->GetColourTable();
00231 
00232     if (Disp->TheC64->TheWIMP->ReadEmuWindowSize() == 1)
00233     {
00234       PlotZoom1(&ge,&Block[RedrawB_CMinX],Bitmap,ct);
00235     }
00236     else
00237     {
00238       PlotZoom2(&ge,&Block[RedrawB_CMinX],Bitmap,ct);
00239     }
00240   }
00241 }
00242 
00243 
00244 // Returns a pointer to a window's icon (or NULL of invalid number)
00245 RO_Icon *Window::GetIcon(unsigned int number)
00246 {
00247   if (number > wind->icon_no) {return(NULL);}
00248   return((RO_Icon*)(((int*)wind) + RO_WINDOW_WORDS + RO_ICON_WORDS*number));
00249 }
00250 
00251 
00252 void Window::SetIconState(unsigned int number, unsigned int eor, unsigned int clear)
00253 {
00254   int Block[4];
00255 
00256   Block[0] = wind->Handle; Block[1] = number; Block[2] = eor; Block[3] = clear;
00257   Wimp_SetIconState((int*)Block);
00258 }
00259 
00260 
00261 void Window::GetIconState(unsigned int number, int *Block)
00262 {
00263   Block[0] = wind->Handle; Block[1] = number;
00264   Wimp_GetIconState(Block);
00265 }
00266 
00267 
00268 // Returns true if this window has the input focus
00269 bool Window::HaveInput(void)
00270 {
00271   RO_Caret Store;
00272 
00273   Wimp_GetCaretPosition(&Store);
00274   return(Store.WHandle == wind->Handle);
00275 }
00276 
00277 
00278 // Writes text into an indirected icon
00279 void Window::WriteIconText(unsigned int number, const char *text)
00280 {
00281   RO_Icon *ic;
00282 
00283   if ((ic = GetIcon(number)) != NULL)
00284   {
00285     // This only makes sense for indirected icons!
00286     if ((ic->iflags & IFlg_Indir) != 0)
00287     {
00288       strncpy((char*)ic->dat.ind.tit,text,ic->dat.ind.len);
00289       ForceIconRedraw(number);
00290     }
00291   }
00292 }
00293 
00294 
00295 // The same but update the window (i.e. immediate result)
00296 void Window::WriteIconTextU(unsigned int number, const char *text)
00297 {
00298   RO_Icon *ic;
00299 
00300   if ((ic = GetIcon(number)) != NULL)
00301   {
00302     if ((ic->iflags & IFlg_Indir) != 0)
00303     {
00304       strncpy((char*)ic->dat.ind.tit,text,ic->dat.ind.len);
00305       UpdateIcon(number);
00306     }
00307   }
00308 }
00309 
00310 
00311 // Writes the value as a decimal string into the indirected icon
00312 void Window::WriteIconNumber(unsigned int number, int value)
00313 {
00314   RO_Icon *ic;
00315 
00316   if ((ic = GetIcon(number)) != NULL)
00317   {
00318     if ((ic->iflags & IFlg_Indir) != 0)
00319     {
00320       ConvertInteger4(value,(char*)ic->dat.ind.tit,ic->dat.ind.len);
00321       ForceIconRedraw(number);
00322     }
00323   }
00324 }
00325 
00326 
00327 // The same but update the window
00328 void Window::WriteIconNumberU(unsigned int number, int value)
00329 {
00330   RO_Icon *ic;
00331 
00332   if ((ic = GetIcon(number)) != NULL)
00333   {
00334     if ((ic->iflags & IFlg_Indir) != 0)
00335     {
00336       ConvertInteger4(value,(char*)ic->dat.ind.tit,ic->dat.ind.len);
00337       UpdateIcon(number);
00338     }
00339   }
00340 }
00341 
00342 
00343 // Returns a pointer to the text in the icon
00344 char *Window::ReadIconText(unsigned int number)
00345 {
00346   RO_Icon *ic;
00347 
00348   if ((ic = GetIcon(number)) != NULL)
00349   {
00350     // only indirected icons!
00351     if ((ic->iflags & IFlg_Indir) != 0) {return((char*)ic->dat.ind.tit);}
00352   }
00353   return(NULL);
00354 }
00355 
00356 
00357 // Reads the number in an indirected icon.
00358 int Window::ReadIconNumber(unsigned int number)
00359 {
00360   RO_Icon *ic;
00361 
00362   if ((ic = GetIcon(number)) != NULL)
00363   {
00364     if ((ic->iflags & IFlg_Indir) != 0)
00365     {
00366       return(atoi((char*)ic->dat.ind.tit));
00367     }
00368   }
00369   return(-1);   // rather arbitrary, but we only have positive numbers here...
00370 }
00371 
00372 
00373 void Window::WriteTitle(const char *title)
00374 {
00375   // only indirected window titles, must contain text
00376   if ((wind->tflags & (IFlg_Indir | IFlg_Text)) == (IFlg_Indir | IFlg_Text))
00377   {
00378     strcpy((char*)wind->dat.ind.tit,title);
00379     UpdateTitle();
00380   }
00381 }
00382 
00383 
00384 char *Window::ReadTitle(void)
00385 {
00386   if ((wind->tflags & (IFlg_Indir | IFlg_Text)) == (IFlg_Indir | IFlg_Text))
00387   {
00388     return((char*)wind->dat.ind.tit);
00389   }
00390   else {return(NULL);}
00391 }
00392 
00393 
00394 // Forces a redraw of the window title
00395 void Window::UpdateTitle(void)
00396 {
00397   getstate();
00398   // Force global redraw (in screen-coordinates)
00399   Wimp_ForceRedraw(-1, wind->vminx, wind->vmaxy, wind->vmaxx, wind->vmaxy + TitleBarHeight);
00400 }
00401 
00402 
00403 RO_Window *Window::Descriptor(void) {return(wind);}
00404 
00405 
00406 // Force a redraw on an icon (visible after the next Poll)
00407 void Window::ForceIconRedraw(unsigned int number)
00408 {
00409   if (number <= wind->icon_no)
00410   {
00411     register RO_Icon *ic;
00412 
00413     ic = GetIcon(number);
00414     forceredraw(ic->minx, ic->miny, ic->maxx, ic->maxy);
00415   }
00416 }
00417 
00418 
00419 // Update an icon (visible immediately -- works only on purely WIMP-drawn icons!)
00420 void Window::UpdateIcon(unsigned int number)
00421 {
00422   if (number <= wind->icon_no)
00423   {
00424     register RO_Icon *ic;
00425     int Block[11];      // redraw block
00426     int more;
00427 
00428     ic = GetIcon(number);
00429     Block[RedrawB_Handle] = wind->Handle;
00430     Block[RedrawB_VMinX] = ic->minx; Block[RedrawB_VMinY] = ic->miny;
00431     Block[RedrawB_VMaxX] = ic->maxx; Block[RedrawB_VMaxY] = ic->maxy;
00432     more = Wimp_UpdateWindow(Block);    // standard redraw loop
00433     while (more != 0)
00434     {
00435       more = Wimp_GetRectangle(Block);
00436     }
00437   }
00438 }
00439 
00440 
00441 // returns the current open-state of the window (true if open)
00442 bool Window::OpenStatus(void)
00443 {
00444   getstate();
00445   return(((wind->wflags & (1<<16)) == 0) ? false : true);
00446 }
00447 
00448 
00449 // Same as above, but reads the current state to Block
00450 bool Window::OpenStatus(int *Block)
00451 {
00452   getstate(Block);
00453   return(((Block[8] & (1<<16)) == 0) ? false : true);
00454 }
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 // Icon member-functions - handle all things concerned with icons
00463 Icon::Icon(int Priority, const RO_IconDesc *IDesc)
00464 {
00465   memcpy((char*)&icon,(char*)IDesc,sizeof(RO_IconDesc));
00466   IHandle = Wimp_CreateIcon(Priority,IDesc);
00467 }
00468 
00469 
00470 Icon::~Icon(void)
00471 {
00472   int blk[2];
00473 
00474   blk[0] = icon.WindowHandle; blk[1] = IHandle;
00475   Wimp_DeleteIcon((int*)blk);
00476 }
00477 
00478 
00479 void Icon::setstate(unsigned int eor, unsigned int clear)
00480 {
00481   int blk[4];
00482 
00483   blk[0] = icon.WindowHandle; blk[1] = IHandle; blk[2] = eor; blk[3] = clear;
00484   Wimp_SetIconState((int*)blk);
00485 }
00486 
00487 
00488 void Icon::getstate(void)
00489 {
00490   int blk[10];
00491 
00492   blk[0] = icon.WindowHandle; blk[1] = IHandle;
00493   Wimp_GetIconState((int*)blk);
00494   memcpy((char*)&icon,(int*)&blk[2],sizeof(RO_Icon));
00495 }
00496 
00497 
00498 
00499 
00500 // Frodo member functions
00501 Frodo::Frodo(void) {TheC64 = NULL;}
00502 
00503 
00504 Frodo::~Frodo(void)
00505 {
00506   if (TheC64 != NULL) {delete TheC64;}
00507 }
00508 
00509 
00510 void Frodo::ReadyToRun(void)
00511 {
00512   ThePrefs.Load(DEFAULT_PREFS);
00513   TheC64 = new C64;
00514   if (load_rom_files())
00515   {
00516     TheC64->Run();
00517   }
00518   delete TheC64; TheC64 = NULL;
00519 }
00520 
00521 
00522 
00523 
00524 
00525 extern void (*__new_handler)(void);
00526 
00527 // Out of memory
00528 void OutOfMemory(void)
00529 {
00530   _kernel_oserror err;
00531 
00532 
00533   err.errnum = 0; sprintf(err.errmess,"Out of memory error! Aborting.");
00534   Wimp_ReportError(&err,1,TASKNAME);
00535   delete the_app;
00536   Wimp_CloseDown(TaskHandle,TASK_WORD);
00537   exit(1);
00538 }
00539 
00540 
00541 
00542 
00543 // Frodo main
00544 int main(int argc, char *argv[])
00545 {
00546 #ifdef __GNUG__
00547   // Switch off filename conversions in UnixLib:
00548   //__uname_control = __UNAME_NO_PROCESS;
00549 #endif
00550 
00551 #ifdef FRODO_SC
00552   TaskHandle = Wimp_Initialise(310,TASK_WORD,"FrodoSC",(int*)WimpMessages);
00553 #else
00554 # ifdef FRODO_PC
00555   TaskHandle = Wimp_Initialise(310,TASK_WORD,"FrodoPC",(int*)WimpMessages);
00556 # else
00557   TaskHandle = Wimp_Initialise(310,TASK_WORD,"Frodo",(int*)WimpMessages);
00558 # endif
00559 #endif
00560 
00561   // Install handler for failed new
00562   __new_handler = OutOfMemory;
00563 
00564   the_app = new Frodo();
00565   the_app->ReadyToRun();
00566   // Clean up directory scrap file
00567   DeleteFile(RO_TEMPFILE);
00568   delete the_app;
00569   Wimp_CloseDown(TaskHandle,TASK_WORD);
00570   return(0);
00571 }

Generated on Tue Feb 8 04:07:57 2005 for E32frodo by doxygen 1.3.3