#include "compiler.h"
#include <gx.h>
#include "bmpdata.h"
#include "scrnmng.h"
#include "scrndraw.h"
#include "vramhdl.h"
#include "menubase.h"
#include "nekop2.res"
#include "cmndraw.h"
#include "softkbd.h"
#if defined(GX_DLL)
#pragma comment(lib, "gx.lib")
#endif
typedef struct {
BOOL rotate;
VRAMHDL vram;
UINT posx;
UINT posy;
int width;
int height;
long start;
long xalign;
long yalign;
#if defined(SUPPORT_SOFTKBD)
int kbdposy;
int kbdheight;
int allflash;
#endif
} SCRNMNG;
typedef struct {
int width;
int height;
} SCRNSTAT;
GXDisplayProperties gx_dp;
static SCRNMNG scrnmng;
static SCRNSTAT scrnstat;
static SCRNSURF scrnsurf;
static UINT8 gx_disable = 1;
extern GXKeyList gx_keylist;
static const TCHAR errmsg[] = _T("Error");
typedef struct {
int xalign;
int yalign;
int width;
int height;
int srcpos;
int dstpos;
} DRAWRECT;
// ---- GX DLL‚Ć‚©
#if !defined(WIN32_PLATFORM_PSPC) || !defined(SIZE_VGA)
#define GXGETDISPLAYPROPERTIES() GXGetDisplayProperties()
#define GXBEGINDRAW() GXBeginDraw()
#define GXENDDRAW() GXEndDraw()
#else // PocketPC2003SE VGA
typedef struct {
WORD wFormat;
WORD wBPP;
VOID *pFramePointer;
int cxStride;
int cyStride;
int cxPixels;
int cyPixels;
} RAWFRAMEBUFFERINFO;
#define GETRAWFRAMEBUFFER 0x00020001
enum {
RFBIFMT_565 = 1,
RFBIFMT_555 = 2,
RFBIFMT_OTHER = 3
};
static RAWFRAMEBUFFERINFO rfbi;
static GXDisplayProperties GXGETDISPLAYPROPERTIES(void) {
HDC hdc;
GXDisplayProperties ret;
hdc = GetDC(NULL);
ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(rfbi), (char *)&rfbi);
ReleaseDC(NULL, hdc);
ret.cxWidth = rfbi.cxPixels;
ret.cyHeight = rfbi.cyPixels;
ret.cbxPitch = rfbi.cxStride;
ret.cbyPitch = rfbi.cyStride;
ret.cBPP = rfbi.wBPP;
ret.ffFormat = 0;
switch(rfbi.wFormat) {
case RFBIFMT_565:
ret.ffFormat |= kfDirect565;
break;
case RFBIFMT_555:
ret.ffFormat |= kfDirect555;
break;
}
return(ret);
}
#define GXBEGINDRAW() (rfbi.pFramePointer)
#define GXENDDRAW()
#endif
// ----
static BOOL calcdrawrect(DRAWRECT *dr, VRAMHDL s, const RECT_T *rt) {
int pos;
dr->xalign = scrnmng.xalign;
dr->yalign = scrnmng.yalign;
dr->srcpos = 0;
dr->dstpos = scrnmng.start;
dr->width = min(scrnmng.width, s->width);
dr->height = min(scrnmng.height, s->height);
if (rt) {
pos = max(rt->left, 0);
dr->srcpos += pos;
dr->dstpos += pos * dr->xalign;
dr->width = min(rt->right, dr->width) - pos;
pos = max(rt->top, 0);
dr->srcpos += pos * s->width;
dr->dstpos += pos * dr->yalign;
dr->height = min(rt->bottom, dr->height) - pos;
}
if ((dr->width <= 0) || (dr->height <= 0)) {
return(FAILURE);
}
return(SUCCESS);
}
static void palcnv(CMNPAL *dst, const RGB32 *src, UINT pals, UINT bpp) {
UINT i;
if (bpp == 16) {
for (i=0; i<pals; i++) {
dst[i].pal16 = ((src[i].p.r & 0xf8) << 8) |
((src[i].p.g & 0xfc) << 3) |
(src[i].p.b >> 3);
}
}
}
static void bmp16draw(void *bmp, UINT8 *dst, int width, int height,
int xalign, int yalign) {
CMNVRAM vram;
vram.ptr = dst;
vram.width = width;
vram.height = height;
vram.xalign = xalign;
vram.yalign = yalign;
vram.bpp = 16;
cmndraw_bmp16(&vram, bmp, palcnv, CMNBMP_CENTER | CMNBMP_MIDDLE);
}
// ----
void scrnmng_initialize(void) {
scrnstat.width = 640;
scrnstat.height = 400;
}
BOOL scrnmng_create(HWND hWnd, LONG width, LONG height) {
TCHAR msg[32];
#if defined(SUPPORT_SOFTKBD)
int kbdheight;
#endif
if ((width <= 0) || (height <= 0)) {
return(FAILURE);
}
if (GXOpenDisplay(hWnd, GX_FULLSCREEN) == 0) {
MessageBox(hWnd, _T("Couldn't GAPI Object"),
errmsg, MB_OK | MB_ICONSTOP);
return(FAILURE);
}
gx_dp = GXGETDISPLAYPROPERTIES();
if (gx_dp.cBPP != 16) {
MessageBox(hWnd, _T("Only 16bit color support..."),
errmsg, MB_OK | MB_ICONSTOP);
return(FAILURE);
}
if (!(gx_dp.ffFormat & kfDirect565)) {
MessageBox(hWnd, _T("Only 16bit(565) support..."),
errmsg, MB_OK | MB_ICONSTOP);
return(FAILURE);
}
if ((gx_dp.cxWidth >= (DWORD)width) &&
(gx_dp.cyHeight >= (DWORD)height)) {
scrnmng.rotate = FALSE;
}
else if ((gx_dp.cxWidth >= (DWORD)height) &&
(gx_dp.cyHeight >= (DWORD)width)) {
scrnmng.rotate = TRUE;
}
else {
wsprintf(msg, _T("Required %dx%d..."), width, height);
MessageBox(hWnd, msg, errmsg, MB_OK | MB_ICONSTOP);
return(FAILURE);
}
if (!scrnmng.rotate) {
scrnmng.posx = ((gx_dp.cxWidth - width) / 2);
scrnmng.posy = ((gx_dp.cyHeight - height) / 2);
scrnmng.start = scrnmng.posx * gx_dp.cbxPitch +
scrnmng.posy * gx_dp.cbyPitch;
scrnmng.width = width;
scrnmng.height = height;
scrnmng.xalign = gx_dp.cbxPitch;
scrnmng.yalign = gx_dp.cbyPitch;
}
else {
scrnmng.posx = ((gx_dp.cxWidth - height) / 2);
scrnmng.posy = ((gx_dp.cyHeight - width) / 2);
scrnmng.start = ((scrnmng.posy + width - 1) * gx_dp.cbyPitch) +
(scrnmng.posx * gx_dp.cbxPitch);
scrnmng.width = width;
scrnmng.height = height;
scrnmng.xalign = -gx_dp.cbyPitch;
scrnmng.yalign = gx_dp.cbxPitch;
}
gx_disable = 0;
scrnmng_clear(TRUE);
#if defined(SUPPORT_SOFTKBD)
softkbd_initialize();
if (softkbd_getsize(NULL, &kbdheight) != SUCCESS) {
kbdheight = 0;
}
kbdheight = min(kbdheight, height);
scrnmng.kbdposy = height - kbdheight;
scrnmng.kbdheight = kbdheight;
#endif
return(SUCCESS);
}
void scrnmng_destroy(void) {
gx_disable = 1;
GXCloseDisplay();
#if defined(SUPPORT_SOFTKBD)
softkbd_deinitialize();
#endif
}
#if defined(SUPPORT_SOFTKBD)
void scrnmng_allflash(void) {
scrnmng.allflash = 1;
}
#endif
RGB16 scrnmng_makepal16(RGB32 pal32) {
RGB16 ret;
ret = (pal32.p.r & 0xf8) << 8;
#if defined(SIZE_QVGA) && !defined(SIZE_VGATEST)
ret += (pal32.p.g & 0xfc) << (3 + 16);
#else
ret += (pal32.p.g & 0xfc) << 3;
#endif
ret += pal32.p.b >> 3;
return(ret);
}
void scrnmng_setwidth(int posx, int width) {
scrnstat.width = width;
}
void scrnmng_setheight(int posy, int height) {
scrnstat.height = height;
}
const SCRNSURF *scrnmng_surflock(void) {
if (gx_disable) {
return(NULL);
}
if (scrnmng.vram == NULL) {
scrnsurf.ptr = (UINT8 *)GXBEGINDRAW() + scrnmng.start;
scrnsurf.xalign = scrnmng.xalign;
scrnsurf.yalign = scrnmng.yalign;
}
else {
scrnsurf.ptr = scrnmng.vram->ptr;
scrnsurf.xalign = 2;
scrnsurf.yalign = scrnmng.vram->yalign;
}
#if !defined(SIZE_VGATEST)
scrnsurf.width = min(scrnstat.width, 640);
scrnsurf.height = min(scrnstat.height, 400);
#else
scrnsurf.width = min(scrnstat.width, 320);
scrnsurf.height = min(scrnstat.height, 200);
#endif
scrnsurf.bpp = 16;
scrnsurf.extend = 0;
return(&scrnsurf);
}
static void draw_onmenu(void) {
RECT_T rt;
DRAWRECT dr;
const UINT8 *p;
UINT8 *q;
const UINT8 *a;
int salign;
int dalign;
int r;
rt.left = 0;
rt.top = 0;
#if defined(SUPPORT_SOFTKBD)
if (!scrnmng.allflash) {
#endif
rt.right = min(scrnstat.width, 640);
rt.bottom = min(scrnstat.height, 400);
#if defined(SIZE_QVGA)
rt.right >>= 1;
rt.bottom >>= 1;
#endif
#if defined(SUPPORT_SOFTKBD)
}
else {
scrnmng.allflash = 0;
rt.right = scrnmng.width;
rt.bottom = scrnmng.height;
}
#endif
if (calcdrawrect(&dr, menuvram, &rt) != SUCCESS) {
return;
}
p = scrnmng.vram->ptr + (dr.srcpos * 2);
q = (UINT8 *)GXBEGINDRAW() + dr.dstpos;
a = menuvram->alpha + dr.srcpos;
salign = menuvram->width - dr.width;
dalign = dr.yalign - (dr.width * dr.xalign);
do {
r = dr.width;
do {
if (a[0] == 0) {
*(UINT16 *)q = *(UINT16 *)p;
}
p += 2;
q += dr.xalign;
a += 1;
} while(--r);
p += salign * 2;
q += dalign;
a += salign;
} while(--dr.height);
GXENDDRAW();
}
void scrnmng_surfunlock(const SCRNSURF *surf) {
#if defined(SUPPORT_SOFTKBD)
CMNVRAM vram;
#endif
if (surf) {
if (scrnmng.vram == NULL) {
#if defined(SUPPORT_SOFTKBD)
if (scrnmng.allflash) {
scrnmng.allflash = 0;
vram.ptr = surf->ptr + (scrnmng.kbdposy * surf->yalign);
vram.width = scrnmng.width;
vram.height = scrnmng.kbdheight;
vram.xalign = surf->xalign;
vram.yalign = surf->yalign;
vram.bpp = 16;
softkbd_paint(&vram, palcnv, TRUE);
}
#endif
GXENDDRAW();
}
else {
if (menuvram) {
draw_onmenu();
}
}
}
}
// ---- for wince
void scrnmng_enable(BOOL enable) {
if (enable) {
gx_disable &= ~2;
}
else {
gx_disable |= 2;
}
}
BOOL scrnmng_mousepos(LPARAM *lp) {
UINT x;
UINT y;
if (!scrnmng.rotate) {
x = LOWORD(*lp) - scrnmng.posx;
y = HIWORD(*lp) - scrnmng.posy;
}
else {
x = scrnmng.width - HIWORD(*lp) - 1 - scrnmng.posy;
y = LOWORD(*lp) - scrnmng.posx;
}
if ((x >= (UINT)scrnmng.width) || (y >= (UINT)scrnmng.height)) {
return(FAILURE);
}
*lp = (x & 0xffff) | ((y << 16) & 0xffff0000);
return(SUCCESS);
}
void scrnmng_clear(BOOL logo) {
void *bmp;
UINT8 *p;
UINT8 *q;
int y;
int x;
long yalign;
if (gx_disable) {
return;
}
bmp = NULL;
if (logo) {
bmp = (void *)bmpdata_solvedata(nekop2_bmp);
}
p = (UINT8 *)GXBEGINDRAW();
q = p;
y = gx_dp.cyHeight;
yalign = gx_dp.cbyPitch - (gx_dp.cbxPitch * gx_dp.cxWidth);
do {
x = gx_dp.cxWidth;
do {
*(UINT16 *)q = 0;
q += gx_dp.cbxPitch;
} while(--x);
q += yalign;
} while(--y);
bmp16draw(bmp, p + scrnmng.start, scrnmng.width, scrnmng.height,
scrnmng.xalign, scrnmng.yalign); GXENDDRAW();
if (bmp) {
_MFREE(bmp);
}
}
void scrnmng_keybinds(void) {
short tmp;
if (scrnmng.rotate) {
tmp = gx_keylist.vkLeft;
gx_keylist.vkLeft = gx_keylist.vkDown;
gx_keylist.vkDown = gx_keylist.vkRight;
gx_keylist.vkRight = gx_keylist.vkUp;
gx_keylist.vkUp = tmp;
}
}
// ---- for menubase
BOOL scrnmng_entermenu(SCRNMENU *smenu) {
VRAMHDL vram;
#if defined(SUPPORT_SOFTKBD)
CMNVRAM kbdvram;
#endif
if (smenu == NULL) {
goto smem_err;
}
vram_destroy(scrnmng.vram);
vram = vram_create(scrnmng.width, scrnmng.height, FALSE, 16);
scrnmng.vram = vram;
if (vram == NULL) {
goto smem_err;
}
scrndraw_redraw();
#if defined(SUPPORT_SOFTKBD)
kbdvram.ptr = vram->ptr + (vram->yalign * scrnmng.kbdposy);
kbdvram.width = vram->width;
kbdvram.height = scrnmng.kbdheight;
kbdvram.xalign = vram->xalign;
kbdvram.yalign = vram->yalign;
kbdvram.bpp = vram->bpp;
softkbd_paint(&kbdvram, palcnv, TRUE);
#endif
smenu->width = scrnmng.width;
smenu->height = scrnmng.height;
smenu->bpp = 16;
return(SUCCESS);
smem_err:
return(FAILURE);
}
void scrnmng_leavemenu(void) {
VRAM_RELEASE(scrnmng.vram);
}
void scrnmng_menudraw(const RECT_T *rct) {
DRAWRECT dr;
const UINT8 *p;
const UINT8 *q;
UINT8 *r;
UINT8 *a;
int salign;
int dalign;
int x;
if ((gx_disable) || (menuvram == NULL)) {
return;
}
if (calcdrawrect(&dr, menuvram, rct) != SUCCESS) {
return;
}
p = scrnmng.vram->ptr + (dr.srcpos * 2);
q = menuvram->ptr + (dr.srcpos * 2);
r = (UINT8 *)GXBEGINDRAW() + dr.dstpos;
a = menuvram->alpha + dr.srcpos;
salign = menuvram->width;
dalign = dr.yalign - (dr.width * dr.xalign);
do {
x = 0;
do {
if (a[x]) {
if (a[x] & 2) {
*(UINT16 *)r = *(UINT16 *)(q + x * 2);
}
else {
a[x] = 0;
*(UINT16 *)r = *(UINT16 *)(p + x * 2);
}
}
r += dr.xalign;
} while(++x < dr.width);
p += salign * 2;
q += salign * 2;
r += dalign;
a += salign;
} while(--dr.height);
GXENDDRAW();
}
// ----
#if defined(SUPPORT_SOFTKBD)
BOOL scrnmng_kbdpos(LPARAM *lp) {
UINT x;
UINT y;
x = LOWORD(*lp);
y = HIWORD(*lp) - scrnmng.kbdposy;
*lp = (x & 0xffff) | ((y << 16) & 0xffff0000);
return(SUCCESS);
}
BOOL scrnmng_ismenu(LPARAM lp) {
if ((LOWORD(lp) < 32) && (HIWORD(lp) >= (scrnmng.height - 32))) {
return(TRUE);
}
else {
return(FALSE);
}
}
#endif
RetroPC.NET-CVS <cvs@retropc.net>