// 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;
}