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 >
Wrap
C/C++ Source or Header
|
2000-12-26
|
7KB
|
297 lines
/*
* @(#)graphics.c
*
* Copyright 1999-2000, Aaron Ardiri (mailto:aaron@ardiri.com)
* All rights reserved.
*
* The source code outlines a number of basic Palm Computing Programming
* principles and you should be able to take the core structure and write
* a large complex program. It is distributed WITHOUT ANY WARRANTY; use it
* "AS IS" and at your own risk.
*
* The code presented is Copyright 1999-2000 by Aaron Ardiri. It should be
* used for educational purposes only. You shall not modify the Cube3D
* source code in any way and re-distribute it as your own, however you
* are free to use the code as a guide for developing programs on the
* Palm Computing Platform.
*/
#include "palm.h"
// interface
static void GraphicsClear_asm();
static void GraphicsRepaint_asm();
static void GraphicsClear_api();
static void GraphicsRepaint_api();
// global variable structure
typedef struct
{
UInt32 scrDepth;
Boolean scr160x160;
WinHandle drawWindow;
void (*fnClear)(void);
void (*fnRepaint)(void);
} GraphicsGlobals;
/**
* Initialize the Graphics engine.
*
* @return true if the graphics initialization was successful, false otherwise
*/
Boolean
GraphicsInitialize()
{
GraphicsGlobals *globals;
Boolean result = true;
UInt16 err;
// create the globals object, and register it
globals = (GraphicsGlobals *)MemPtrNew(sizeof(GraphicsGlobals));
MemSet(globals, sizeof(GraphicsGlobals), 0);
FtrSet(appCreator, ftrGraphicsGlobals, (UInt32)globals);
// determine the screen depth
globals->scrDepth = 1;
if (DeviceSupportsVersion(romVersion3)) {
WinScreenMode(winScreenModeGet,NULL,NULL,&globals->scrDepth,NULL);
}
// determine screen size (only >= 3.5)
globals->scr160x160 = true;
if (DeviceSupportsVersion(romVersion3_5)) {
UInt32 width, height;
UInt32 cpuID;
// determine the current display mode
WinScreenMode(winScreenModeGetDefaults,&width,&height,NULL,NULL);
globals->scr160x160 &= ((width == 160) && (height == 160));
// lets make sure we are running on a "m68k chip" :) - asm routines work
FtrGet(sysFtrCreator, sysFtrNumProcessorID, &cpuID);
globals->scr160x160 &= ((cpuID == sysFtrNumProcessor328) ||
(cpuID == sysFtrNumProcessorEZ) ||
(cpuID == sysFtrNumProcessorVZ));
}
// create the offscreen window
globals->drawWindow =
WinCreateOffscreenWindow(SCREEN_WIDTH, SCREEN_HEIGHT, screenFormat, &err);
err |= (globals->drawWindow == NULL);
// something went wrong, display error and exit
if (err != errNone) {
ApplicationDisplayDialog(xmemForm);
result = false;
}
// no probs, configure pointers
else {
globals->fnClear = (globals->scr160x160)
? (void *)GraphicsClear_asm
: (void *)GraphicsClear_api;
globals->fnRepaint = (globals->scr160x160)
? (void *)GraphicsRepaint_asm
: (void *)GraphicsRepaint_api;
}
return result;
}
/**
* Get the draw window.
*
* @return the draw window.
*/
WinHandle
GraphicsGetDrawWindow()
{
GraphicsGlobals *globals;
// get a globals reference
FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
return globals->drawWindow;
}
/**
* Clear the offscreen image.
*/
void
GraphicsClear()
{
GraphicsGlobals *globals;
// get a globals reference
FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
// execute the appropriate function
globals->fnClear();
}
/**
* Blit the offscreen image to the screen.
*/
void
GraphicsRepaint()
{
GraphicsGlobals *globals;
// get a globals reference
FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
// execute the appropriate function
globals->fnRepaint();
}
/**
* Terminate the Graphics engine.
*/
void
GraphicsTerminate()
{
GraphicsGlobals *globals;
// get a globals reference
FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
// clean up windows/memory
if (globals->drawWindow != NULL)
WinDeleteWindow(globals->drawWindow, false);
MemPtrFree(globals);
// unregister global data
FtrUnregister(appCreator, ftrGraphicsGlobals);
}
//
// 160x160 direct screen display routines [speed on 160x160 devices]
//
// -- Aaron Ardiri, 2000
//
/**
* Clear the offscreen image.
*/
static void
GraphicsClear_asm()
{
GraphicsGlobals *globals;
// get a globals reference
FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
// clear the buffer
{
UInt16 ptrSize;
// how much memory is being used?
ptrSize = ((SCREEN_WIDTH * SCREEN_HEIGHT) / (8 / globals->scrDepth));
// clear the memory
MemSet(DeviceWindowGetPointer(globals->drawWindow), ptrSize, 0);
}
}
/**
* Blit the offscreen image to the screen.
*/
static void
GraphicsRepaint_asm()
{
GraphicsGlobals *globals;
// get a globals reference
FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
// blit the buffer to the real screen
{
UInt8 *ptrLCDScreen, *ptrScreen;
Int16 loop;
ptrLCDScreen = DeviceWindowGetPointer(WinGetDisplayWindow());
ptrLCDScreen += ((SCREEN_WIDTH*16) / (8 / globals->scrDepth));
// 160x16 @ depth
ptrScreen = DeviceWindowGetPointer(globals->drawWindow);
// determine how many "160" byte blits we need :))
loop = ((SCREEN_WIDTH * SCREEN_HEIGHT) / (8 / globals->scrDepth) / 160);
// push all registers (except a7) on stack
asm("movem.l %%d0-%%d7/%%a0-%%a6, -(%%sp)" : : );
// copy inner 160x144 from back buffer to screen
asm("move.l %0, %%a0" : : "g" (ptrScreen));
asm("move.l %0, %%a1" : : "g" (ptrLCDScreen));
asm("move.l %0, %%d0" : : "g" (loop-1));
asm("
ScrLoop2:
movem.l (%%a0)+, %%d1-%%d7/%%a2-%%a4
movem.l %%d1-%%d7/%%a2-%%a4, (%%a1)
movem.l (%%a0)+, %%d1-%%d7/%%a2-%%a4
movem.l %%d1-%%d7/%%a2-%%a4, 40(%%a1)
movem.l (%%a0)+, %%d1-%%d7/%%a2-%%a4
movem.l %%d1-%%d7/%%a2-%%a4, 80(%%a1)
movem.l (%%a0)+, %%d1-%%d7/%%a2-%%a4
movem.l %%d1-%%d7/%%a2-%%a4, 120(%%a1)
adda.l #160, %%a1 | blit 160 bytes!!
dbra %%d0, ScrLoop2
" : :);
// pop all registers (except a7) off stack
asm("movem.l (%%sp)+, %%d0-%%d7/%%a0-%%a6" : : );
}
}
//
// 160x160 API call display routines [for future compatability]
//
// -- Aaron Ardiri, 2000
//
/**
* Clear the offscreen image.
*/
static void
GraphicsClear_api()
{
const CustomPatternType erase = {0,0,0,0,0,0,0,0};
const RectangleType rect = {{0,0},{SCREEN_WIDTH,SCREEN_HEIGHT}};
GraphicsGlobals *globals;
WinHandle currWindow;
// get a globals reference
FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
// clear the buffer
currWindow = WinSetDrawWindow(globals->drawWindow);
WinSetPattern(&erase);
WinFillRectangle(&rect, 0);
WinSetDrawWindow(currWindow);
}
/**
* Blit the offscreen image to the screen.
*/
static void
GraphicsRepaint_api()
{
const RectangleType rect = {{0,0},{SCREEN_WIDTH,SCREEN_HEIGHT}};
GraphicsGlobals *globals;
// get a globals reference
FtrGet(appCreator, ftrGraphicsGlobals, (UInt32 *)&globals);
// copy the backbuffer to the screen
WinCopyRectangle(globals->drawWindow, WinGetDisplayWindow(),
&rect, 0, 16, winPaint);
}