home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 Mobile / Chip_Mobile_2001.iso / palm / business / cube3d / cube3D.exe / cube3D / src / graphics.c < prev    next >
C/C++ Source or Header  |  2000-12-26  |  7KB  |  297 lines

  1. /*
  2.  * @(#)graphics.c
  3.  *
  4.  * Copyright 1999-2000, Aaron Ardiri (mailto:aaron@ardiri.com)
  5.  * All rights reserved.
  6.  *
  7.  * The  source code  outlines a number of basic Palm Computing Programming
  8.  * principles and you  should be able to take the core structure and write 
  9.  * a large complex program. It is distributed WITHOUT ANY WARRANTY; use it
  10.  * "AS IS" and at your own risk.
  11.  *
  12.  * The code presented is Copyright 1999-2000 by Aaron Ardiri. It should be
  13.  * used for  educational purposes only.  You  shall not modify  the Cube3D 
  14.  * source code in any way and  re-distribute it as your  own,  however you
  15.  * are free to use  the code as  a guide for  developing  programs  on the 
  16.  * Palm Computing Platform.
  17.  */
  18.  
  19. #include "palm.h"
  20.  
  21. // interface
  22. static void GraphicsClear_asm();
  23. static void GraphicsRepaint_asm();
  24. static void GraphicsClear_api();
  25. static void GraphicsRepaint_api();
  26.  
  27. // global variable structure
  28. typedef struct
  29. {
  30.   UInt32    scrDepth;
  31.   Boolean   scr160x160;
  32.   WinHandle drawWindow;
  33.  
  34.   void      (*fnClear)(void);
  35.   void      (*fnRepaint)(void);
  36. } GraphicsGlobals;
  37.  
  38. /**
  39.  * Initialize the Graphics engine.
  40.  *
  41.  * @return true if the graphics initialization was successful, false otherwise
  42.  */  
  43. Boolean   
  44. GraphicsInitialize()
  45. {
  46.   GraphicsGlobals *globals;
  47.   Boolean         result = true;
  48.   UInt16          err;
  49.  
  50.   // create the globals object, and register it
  51.   globals = (GraphicsGlobals *)MemPtrNew(sizeof(GraphicsGlobals));
  52.   MemSet(globals, sizeof(GraphicsGlobals), 0);
  53.   FtrSet(appCreator, ftrGraphicsGlobals, (UInt32)globals);
  54.  
  55.   // determine the screen depth
  56.   globals->scrDepth   = 1;
  57.   if (DeviceSupportsVersion(romVersion3)) {
  58.     WinScreenMode(winScreenModeGet,NULL,NULL,&globals->scrDepth,NULL);
  59.   }
  60.  
  61.   // determine screen size (only >= 3.5)
  62.   globals->scr160x160 = true;
  63.   if (DeviceSupportsVersion(romVersion3_5)) {
  64.  
  65.     UInt32 width, height;
  66.     UInt32 cpuID;
  67.  
  68.     // determine the current display mode
  69.     WinScreenMode(winScreenModeGetDefaults,&width,&height,NULL,NULL);
  70.     globals->scr160x160 &= ((width == 160) && (height == 160));
  71.  
  72.     // lets make sure we are running on a "m68k chip" :) - asm routines work
  73.     FtrGet(sysFtrCreator, sysFtrNumProcessorID, &cpuID);
  74.     globals->scr160x160 &= ((cpuID == sysFtrNumProcessor328) ||
  75.                             (cpuID == sysFtrNumProcessorEZ)  ||
  76.                             (cpuID == sysFtrNumProcessorVZ));
  77.   }
  78.  
  79.   // create the offscreen window
  80.   globals->drawWindow = 
  81.     WinCreateOffscreenWindow(SCREEN_WIDTH, SCREEN_HEIGHT, screenFormat, &err);
  82.   err |= (globals->drawWindow == NULL);
  83.  
  84.   // something went wrong, display error and exit
  85.   if (err != errNone) {
  86.  
  87.     ApplicationDisplayDialog(xmemForm);
  88.     result = false;
  89.   }
  90.  
  91.   // no probs, configure pointers
  92.   else {
  93.     globals->fnClear    = (globals->scr160x160) 
  94.                           ? (void *)GraphicsClear_asm
  95.               : (void *)GraphicsClear_api; 
  96.     globals->fnRepaint  = (globals->scr160x160) 
  97.                           ? (void *)GraphicsRepaint_asm 
  98.               : (void *)GraphicsRepaint_api; 
  99.   }
  100.  
  101.   return result;
  102. }
  103.  
  104. /**
  105.  * Get the draw window.
  106.  *
  107.  * @return the draw window.
  108.  */
  109. WinHandle
  110. GraphicsGetDrawWindow()
  111. {
  112.   GraphicsGlobals *globals;
  113.   
  114.   // get a globals reference
  115.   FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
  116.  
  117.   return globals->drawWindow;
  118. }
  119.  
  120. /**
  121.  * Clear the offscreen image.
  122.  */
  123. void
  124. GraphicsClear()
  125. {
  126.   GraphicsGlobals *globals;
  127.   
  128.   // get a globals reference
  129.   FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
  130.  
  131.   // execute the appropriate function
  132.   globals->fnClear();
  133. }
  134.  
  135. /**
  136.  * Blit the offscreen image to the screen.
  137.  */
  138. void
  139. GraphicsRepaint()
  140. {
  141.   GraphicsGlobals *globals;
  142.   
  143.   // get a globals reference
  144.   FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
  145.  
  146.   // execute the appropriate function
  147.   globals->fnRepaint();
  148. }
  149.  
  150. /**
  151.  * Terminate the Graphics engine.
  152.  */
  153. void   
  154. GraphicsTerminate()
  155. {
  156.   GraphicsGlobals *globals;
  157.  
  158.   // get a globals reference
  159.   FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
  160.  
  161.   // clean up windows/memory
  162.   if (globals->drawWindow != NULL) 
  163.     WinDeleteWindow(globals->drawWindow, false);
  164.   MemPtrFree(globals);
  165.  
  166.   // unregister global data
  167.   FtrUnregister(appCreator, ftrGraphicsGlobals);
  168. }
  169.  
  170. // 
  171. // 160x160 direct screen display routines [speed on 160x160 devices]
  172. //
  173. // -- Aaron Ardiri, 2000
  174. //
  175.  
  176. /**
  177.  * Clear the offscreen image.
  178.  */
  179. static void
  180. GraphicsClear_asm()
  181. {
  182.   GraphicsGlobals *globals;
  183.   
  184.   // get a globals reference
  185.   FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
  186.  
  187.   // clear the buffer
  188.   {
  189.     UInt16 ptrSize;
  190.     
  191.     // how much memory is being used?
  192.     ptrSize = ((SCREEN_WIDTH * SCREEN_HEIGHT) / (8 / globals->scrDepth));
  193.     
  194.     // clear the memory
  195.     MemSet(DeviceWindowGetPointer(globals->drawWindow), ptrSize, 0);
  196.   }
  197. }
  198.  
  199. /**
  200.  * Blit the offscreen image to the screen.
  201.  */
  202. static void
  203. GraphicsRepaint_asm()
  204. {
  205.   GraphicsGlobals *globals;
  206.   
  207.   // get a globals reference
  208.   FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
  209.  
  210.   // blit the buffer to the real screen
  211.   {
  212.     UInt8 *ptrLCDScreen, *ptrScreen;
  213.     Int16 loop;
  214.  
  215.     ptrLCDScreen = DeviceWindowGetPointer(WinGetDisplayWindow());
  216.     ptrLCDScreen += ((SCREEN_WIDTH*16) / (8 / globals->scrDepth)); 
  217.                                                              // 160x16 @ depth
  218.     ptrScreen    = DeviceWindowGetPointer(globals->drawWindow);
  219.  
  220.     // determine how many "160" byte blits we need :))
  221.     loop = ((SCREEN_WIDTH * SCREEN_HEIGHT) / (8 / globals->scrDepth) / 160);
  222.  
  223.     // push all registers (except a7) on stack
  224.     asm("movem.l %%d0-%%d7/%%a0-%%a6, -(%%sp)" : : );
  225.  
  226.     // copy inner 160x144 from back buffer to screen
  227.     asm("move.l  %0, %%a0" : : "g" (ptrScreen));
  228.     asm("move.l  %0, %%a1" : : "g" (ptrLCDScreen));
  229.     asm("move.l  %0, %%d0" : : "g" (loop-1));
  230.     asm("
  231. ScrLoop2:
  232.          movem.l (%%a0)+, %%d1-%%d7/%%a2-%%a4
  233.          movem.l %%d1-%%d7/%%a2-%%a4, (%%a1)
  234.  
  235.          movem.l (%%a0)+, %%d1-%%d7/%%a2-%%a4
  236.          movem.l %%d1-%%d7/%%a2-%%a4, 40(%%a1)
  237.  
  238.          movem.l (%%a0)+, %%d1-%%d7/%%a2-%%a4
  239.          movem.l %%d1-%%d7/%%a2-%%a4, 80(%%a1)
  240.  
  241.          movem.l (%%a0)+, %%d1-%%d7/%%a2-%%a4
  242.          movem.l %%d1-%%d7/%%a2-%%a4, 120(%%a1)
  243.  
  244.          adda.l  #160, %%a1                      | blit 160 bytes!!
  245.  
  246.          dbra    %%d0, ScrLoop2
  247.     " : :);
  248.  
  249.     // pop all registers (except a7) off stack
  250.     asm("movem.l (%%sp)+, %%d0-%%d7/%%a0-%%a6" : : );
  251.   }
  252. }
  253.  
  254. // 
  255. // 160x160 API call display routines [for future compatability]
  256. //
  257. // -- Aaron Ardiri, 2000
  258. //
  259.  
  260. /**
  261.  * Clear the offscreen image.
  262.  */
  263. static void
  264. GraphicsClear_api()
  265. {
  266.   const CustomPatternType erase = {0,0,0,0,0,0,0,0};
  267.   const RectangleType     rect  = {{0,0},{SCREEN_WIDTH,SCREEN_HEIGHT}};
  268.   GraphicsGlobals *globals;
  269.   WinHandle       currWindow;
  270.   
  271.   // get a globals reference
  272.   FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
  273.  
  274.   // clear the buffer
  275.   currWindow = WinSetDrawWindow(globals->drawWindow);
  276.   WinSetPattern(&erase);
  277.   WinFillRectangle(&rect, 0);
  278.   WinSetDrawWindow(currWindow);
  279. }
  280.  
  281. /**
  282.  * Blit the offscreen image to the screen.
  283.  */
  284. static void
  285. GraphicsRepaint_api()
  286. {
  287.   const RectangleType rect = {{0,0},{SCREEN_WIDTH,SCREEN_HEIGHT}};
  288.   GraphicsGlobals *globals;
  289.   
  290.   // get a globals reference
  291.   FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
  292.  
  293.   // copy the backbuffer to the screen
  294.   WinCopyRectangle(globals->drawWindow, WinGetDisplayWindow(),
  295.                    &rect, 0, 16, winPaint);
  296. }
  297.