Time for GAPI Sample

  
// GAPI1.cpp
//
// This sample program uses the GAPI library to access screen memory.
// The program will clear the screen to a random color and then draw
// a line.

#include "stdafx.h"
#include "GAPI1.h"
#include 
#include 
#include 

#include "gx.h"


#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE			hInst;					// The current instance
HWND				hwndCB;					// The command bar handle

// Global GAPI variables:
GXDisplayProperties gx_displayprop;
GXKeyList gx_keylist;


// Global variables for this program (line drawing stuff only)
 int x1=10,x2=100,y1=40,y2=80, dx1=4,dy1=-4, dx2=3,dy2=3;



static SHACTIVATEINFO s_sai;

// Forward declarations of functions included in this code module:
ATOM				MyRegisterClass	(HINSTANCE, LPTSTR);
BOOL				InitInstance	(HINSTANCE, int);
LRESULT CALLBACK	WndProc			(HWND, UINT, WPARAM, LPARAM);


int WINAPI WinMain(	HINSTANCE hInstance,
					HINSTANCE hPrevInstance,
					LPTSTR    lpCmdLine,
					int       nCmdShow)
{
	MSG msg;
	HACCEL hAccelTable;

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_GAPI1);

	// Main message loop:
	while (GetMessage(&msg;, NULL, 0, 0)) 
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg;)) 
		{
			TranslateMessage(&msg;);
			DispatchMessage(&msg;);
		}
	}

	return msg.wParam;
}


ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
	WNDCLASS	wc;

    wc.style			= CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc		= (WNDPROC) WndProc;
    wc.cbClsExtra		= 0;
    wc.cbWndExtra		= 0;
    wc.hInstance		= hInstance;
    wc.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GAPI1));
    wc.hCursor			= 0;
    wc.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName		= 0;
    wc.lpszClassName	= szWindowClass;

	return RegisterClass(&wc;);
}


BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HWND	hWnd = NULL;
	TCHAR	szTitle[MAX_LOADSTRING];			// The title bar text
	TCHAR	szWindowClass[MAX_LOADSTRING];		// The window class name

	hInst = hInstance;		// Store instance handle in our global variable
	// Initialize global strings
	LoadString(hInstance, IDC_GAPI1, szWindowClass, MAX_LOADSTRING);
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

	//If it is already running, then focus on the window
	hWnd = FindWindow(szWindowClass, szTitle);	
	if (hWnd) 
	{
		SetForegroundWindow ((HWND) (((DWORD)hWnd) | 0x01));    
		return 0;
	} 

	MyRegisterClass(hInstance, szWindowClass);
	
	RECT	rect;
	GetClientRect(hWnd, ▭);
	
	hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
	if (!hWnd)
	{	
		return FALSE;
	}
	//When the main window is created using CW_USEDEFAULT the height of the menubar (if one
	// is created is not taken into account). So we resize the window after creating it
	// if a menubar is present
	{
		RECT rc;
		GetWindowRect(hWnd, &rc;);
		rc.bottom -= MENU_HEIGHT;
		if (hwndCB)
			MoveWindow(hWnd, rc.left, rc.top, rc.right, rc.bottom, FALSE);
	}


	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	// GAPI Stuff

	// Attempt to take over the screen
	if (GXOpenDisplay( hWnd, GX_FULLSCREEN) == 0)
		return FALSE;

	// Get display properties
	gx_displayprop = GXGetDisplayProperties();

	// Check for 16 bit color display
	if (gx_displayprop.cBPP != 16)
	{
		// Only dealing with 16 bit color in this code
		GXCloseDisplay();
		MessageBox(hWnd,L"Sorry, only supporting 16bit color",L"Sorry!", MB_OK);
		return FALSE;
	}

	// Take over button handling
	GXOpenInput();

	// Get default buttons for up/down etc.
	gx_keylist = GXGetDefaultKeys(GX_NORMALKEYS);


	return TRUE;
}



// Plot a pixel given video memory address, color, x and y co-ords
void PlotPixel(unsigned short *buffer, int x, int y, int r, int g, int b)
{

	int address  = (x * gx_displayprop.cbxPitch>>1) + (y * gx_displayprop.cbyPitch>>1);

	unsigned short PixelCol;

	if (gx_displayprop.ffFormat & kfDirect565)
	{
		PixelCol = (unsigned short) (r & 0xff) << 11 | (g & 0xff) << 6 | (b & 0xff);
	}
	else
	{
		PixelCol = (unsigned short) (r & 0xff) << 10 | (g & 0xff) << 5 | (b & 0xff);
	}

	*(unsigned short *)(buffer+address) = PixelCol;
}


// Simple midpoint line algorithm. See Foly, vanDam, Feiner, Hughes
void DrawLine(unsigned short *buffer, int x0, int y0, int x1, int y1, int r, int g, int b)
{

	int x;

	if (x0>x1) {x=x1; x1=x0; x0=x;}
	if (y0>y1) {x=y1; y1=y0; y0=x;}
	
	float dx,dy,y,m;

	dy=y1-y0;
	dx=x1-x0;
	m=dy/dx;
	y=y0;
	for (x=x0; x<x1; x++)
	{
		PlotPixel(buffer,x,(int)y,r,g,b);
		y+=m;
	}
}



// Clear the screen to a color desribed by the red, green, blue values
void ClearScreen(int r, int g, int b)
{

	// Get the start of the screen memory from the GX function.
	unsigned short * buffer  = (unsigned short *) GXBeginDraw();
	unsigned short * line_buffer  = buffer;


	if (buffer == NULL) return;


	// Calculate the pixel color from the r,g,b components.
	unsigned short PixelCol;

	if (gx_displayprop.ffFormat & kfDirect565)
	{
		PixelCol = (unsigned short) (r & 0xff) << 11 | (g & 0xff) << 6 | (b & 0xff);
	}
	else
	{
		PixelCol = (unsigned short) (r & 0xff) << 10 | (g & 0xff) << 5 | (b & 0xff);
	}


	// Use two loops to fill the entire screen with the necessary color
	for (unsigned int y=0; y<gx_displayprop.cyHeight; y++)
	{
		unsigned short * pixel = buffer;

		for (unsigned int x=0; x<gx_displayprop.cxWidth; x++)
		{
			*pixel = PixelCol;
			pixel += gx_displayprop.cbxPitch >> 1;
		}

		buffer += gx_displayprop.cbyPitch >> 1;
	}



	// A little extra line-drawing fun. It makes
	// sense to rewrite the ClearScreen code to
	// accept the buffer as a parameter too,
	// instead of building GXBeginDraw into it..
	
	DrawLine(line_buffer,x1,y1,x2,y2,0,0,0);

	x1+=dx1; if (x1<2 || x1>238) dx1=-dx1;
	x2+=dx2; if (x2<2 || x2>238) dx2=-dx2;
	y1+=dy1; if (y1<2 || y1>328) dy1=-dy1;
	y2+=dy2; if (y2<2 || y2>328) dy2=-dy2;

	// End the drawing code
	GXEndDraw();
}



LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

	switch (message) 
	{
		
		case WM_CREATE:
			SetTimer(hWnd,1,100,NULL);
			break;

		case WM_TIMER:
			ClearScreen(rand(),rand(),rand());
		
			break;


		case WM_KEYDOWN:

			if (wParam == (unsigned) gx_keylist.vkUp)
			{
				SendMessage(hWnd,WM_CLOSE,0,0);
			}

			break;


		
		case WM_DESTROY:

			KillTimer(hWnd,1);

			GXCloseInput();
			GXCloseDisplay();

			PostQuitMessage(0);
			break;

		case WM_KILLFOCUS:
			GXSuspend();
			break;

		case WM_SETFOCUS:
			GXResume();
			break;


		case WM_SETTINGCHANGE:
			SHHandleWMSettingChange(hWnd, wParam, lParam, &s;_sai);
     		break;

		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}