home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Dream 59
/
CDDream59.ISO
/
Amiga
/
Emulation
/
cp4.lha
/
cp4
/
c2p_src
/
c2p_windowcard.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-12-03
|
14KB
|
501 lines
/* :ts=4 c2p_windowcard.c
*
* cp4 - Commodore C+4 emulator
* Copyright (C) 1998 Gßti Gergely
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* e-mail: gatig@dragon.klte.hu
*/
#include <proto/graphics.h>
#include <graphics/gfxbase.h>
#include <proto/exec.h>
#include <exec/alerts.h>
#include <proto/intuition.h>
#include <intuition/pointerclass.h>
#include <proto/gadtools.h>
#include <proto/layers.h>
#define C2P_INFO "Workbench window driver. Works on GFX cards and AGA too."
#define C2P_VERSION "1"
#define C2P_REVISION "1"
#define C2P_AUTHOR "gega <Gßti Gergely>"
#define C2P_NAME "WindowCard"
#include "c2p_module.c"
#include "c2p_windowcard_palette.c"
#include "c2p_color_priority.c"
struct GfxBase *GfxBase=NULL;
struct ExecBase *SysBase;
struct IntuitionBase *IntuitionBase=NULL;
struct Library *GadToolsBase=NULL;
struct Library *LayersBase=NULL;
static struct BitMap *bmap;
static struct Window *win=NULL;
static int offx=0,offy=0;
static int maxx,maxy;
static int borhoriz,borvert;
static struct BitMap mybmap;
static void *mypointer=NULL;
static UWORD *mypntchip0=NULL;
static UWORD *mypntchip1=NULL;
static struct ColorMap *colmap=NULL;
static struct BitMap *bmapwpx;
static struct RastPort *tmpraswpx;
static struct RastPort *raswpx;
static int winsleeped=0;
static struct Requester InvisibleRequester;
static LONG PenTable[256];
static unsigned char PenArray[SCRSIZE];
static struct Menu *mMenus=NULL;
static APTR visualinfo=NULL;
/* LORES-POINTER
*/
#define POINTERHEIGHT 31
static UWORD pointerp0[]={ 0,384,384,3504,3504,3504,28080,28080,28080,28086,28086,28086,32758,32758,32766,32766,32764,16380,16376,16376,0,32764,0,32764,32740,32764,32740,32764,32764,32736,28672 };
static UWORD pointerp1[]={ 384,960,4080,8184,8184,32760,65528,65528,65534,65535,65535,65535,65535,65535,65535,65535,65534,32766,32764,32764,65534,65534,65534,32770,32794,32770,32794,32770,32770,32768,32768 };
/* prefs
*/
static int WTop,WLeft,WHeight,WWidth,Wx,Wy;
static char *WPubName=NULL;
/* Protos
*/
static char *initgfx(void);
static void freegfx(void);
static int mReset(struct IntuiMessage *imsg);
static int mHReset(struct IntuiMessage *imsg);
static int mDebug(struct IntuiMessage *imsg);
static int mPrefs(struct IntuiMessage *imsg);
static int mJump(struct IntuiMessage *imsg);
static int mQuit(struct IntuiMessage *imsg);
/* Menu
*/
static struct NewMenu mNewMenu[]={
{ NM_TITLE, (STRPTR)"Project", NULL, 0, NULL, NULL },
{ NM_ITEM, (STRPTR)"Reset", (STRPTR)"R", 0, 0L, (APTR)mReset },
{ NM_ITEM, (STRPTR)"HardReset", (STRPTR)"H", 0, 0L, (APTR)mHReset },
{ NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL },
{ NM_ITEM, (STRPTR)"Debug...", (STRPTR)"D", 0, 0L, (APTR)mDebug },
{ NM_ITEM, (STRPTR)"Prefs...", (STRPTR)"P", 0, 0L, (APTR)mPrefs },
{ NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL },
{ NM_ITEM, (STRPTR)"Quit", (STRPTR)"X", 0, 0L, (APTR)mQuit },
{ NM_TITLE, (STRPTR)"Options", NULL, 0, NULL, NULL },
{ NM_ITEM, (STRPTR)"Jump PubScreen", (STRPTR)"J", 0, 0L, (APTR)mJump },
{ NM_END, NULL, NULL, 0, 0L, NULL }
};
/* Handle MenuPick
*/
static int mReset(struct IntuiMessage *imsg) {
return(RET_RESET);
} // mReset()
static int mHReset(struct IntuiMessage *imsg) {
return(RET_HRESET);
} // mHReset()
static int mDebug(struct IntuiMessage *imsg) {
return(RET_DEBUG);
} // mDebug()
static int mPrefs(struct IntuiMessage *imsg) {
return(RET_PREFS);
} // mPrefs()
static int mQuit(struct IntuiMessage *imsg) {
return(RET_QUIT);
} // mQuit()
static int mJump(struct IntuiMessage *imsg) {
static char newname[MAXPUBSCREENNAME+1];
int r=RET_OK,i;
char *s;
if(NULL!=(NextPubScreen(vec.c2p_Scr,newname))) {
if(NULL!=(s=AllocVec(MAXPUBSCREENNAME+1,MEMF_ANY))) {
freegfx();
r=RET_NEWWIN;
for(i=0;newname[i]!='\0';i++);
CopyMem(newname,s,i+1);
if(WPubName) FreeVec(WPubName);
WPubName=s;
if(NULL!=(initgfx())) {
freegfx();
// PANIC!!!
Alert(AT_Recovery|AG_NoMemory|AO_Unknown);
return(RET_ERROR);
}
}
}
return(r);
} // mJump()
static INLINE void calcwinsizes() {
borhoriz=win->BorderRight+win->BorderLeft-1;
borvert=win->BorderTop+win->BorderBottom-1;
maxx=SCRWIDTH-(win->Width-borhoriz);
maxy=SCRHEIGHT-(win->Height-borvert);
if(offx>maxx) {
ScrollLayer(0,win->RPort->Layer,-(offx-maxx),0);
offx=maxx;
}
if(offy>maxy) {
ScrollLayer(0,win->RPort->Layer,0,-(offy-maxy));
offy=maxy;
}
}
static char *initgfx(void) {
static char pname[MAXPUBSCREENNAME+1];
ULONG r,g,b;
int planes,i,j,mx,my;
for(i=0;i<256;i++) PenTable[i]=-1;
/* Get the required PubScreen
*/
if(NULL==(vec.c2p_Scr=LockPubScreen(WPubName))) {
vec.c2p_Scr=LockPubScreen(NULL);
GetDefaultPubScreen(pname);
if(WPubName) FreeVec(WPubName);
for(i=0;pname[i]!='\0';i++);
if(NULL==(WPubName=AllocVec(i+2,MEMF_ANY))) return(C2P_NOMEM);
CopyMem(pname,WPubName,i+1);
}
/* ScreenToFront
*/
ScreenToFront(vec.c2p_Scr);
/* Get Screen Attribs
*/
planes=vec.c2p_Scr->BitMap.Depth;
colmap=vec.c2p_Scr->ViewPort.ColorMap;
if(!(visualinfo=GetVisualInfo(vec.c2p_Scr,TAG_DONE))) return("Can't find VisualInfo");
/* Allocate bitmap
*/
if(NULL==(bmap=AllocBitMap(SCRWIDTH,SCRHEIGHT,planes,BMF_DISPLAYABLE|BMF_CLEAR,NULL))) return(C2P_NOMEM);
/* SetUp Menu
*/
if(!(mMenus=CreateMenus(mNewMenu,GTMN_FrontPen,0L,TAG_DONE,0L))) return("Can't Create Menu");
LayoutMenus(mMenus,visualinfo,GTMN_TextAttr,(ULONG)vec.c2p_Scr->Font,GTMN_NewLookMenus,TRUE,TAG_DONE,0L);
/* Open window
*/
if((win=(struct Window *)OpenWindowTags(NULL,
WA_Left, WLeft,
WA_Top, WTop,
WA_Width, WWidth,
WA_Height, WHeight,
WA_Title, (ULONG)"cp4 WindowCard",
WA_Flags, WFLG_SIZEGADGET|
WFLG_SIZEBBOTTOM|
WFLG_DRAGBAR|
WFLG_DEPTHGADGET|
WFLG_CLOSEGADGET|
WFLG_SUPER_BITMAP|
WFLG_GIMMEZEROZERO|
WFLG_ACTIVATE,
WA_SuperBitMap, (ULONG)bmap,
WA_AutoAdjust, TRUE,
WA_RptQueue, 25,
WA_IDCMP, IDCMP_MOUSEMOVE|
IDCMP_CLOSEWINDOW|
IDCMP_MENUPICK|
IDCMP_NEWSIZE|
IDCMP_MOUSEBUTTONS,
WA_PubScreen, (ULONG)vec.c2p_Scr,
WA_PubScreenFallBack, TRUE,
WA_NewLookMenus, TRUE,
TAG_DONE,0L ))==NULL)
return("Can't open Window");
SetMenuStrip(win,mMenus);
vec.c2p_Win=win;
winsleeped=0;
offx=offy=0;
calcwinsizes();
WindowLimits(win,borhoriz+80,borvert+20,SCRWIDTH+borhoriz,borvert+SCRHEIGHT);
offx+=Wx; offy+=Wy;
mx=Wx; my=Wy;
if(offx<0) { mx-=offx; offx=0; }
if(offx>maxx) { mx-=offx-maxx; offx=maxx; }
if(offy<0) { my-=offy; offy=0; }
if(offy>maxy) { my-=offy-maxy; offy=maxy; }
ScrollLayer(0,win->RPort->Layer,mx,my);
/* Allocate & Init TMP rasters for WritePixel...
*/
bmapwpx=AllocBitMap(SCRWIDTH,1,planes,BMF_CLEAR,NULL);
if(bmapwpx==NULL) return(C2P_NOMEM);
tmpraswpx=AllocVec(sizeof(struct RastPort),MEMF_ANY);
if(tmpraswpx==NULL) return(C2P_NOMEM);
InitRastPort(tmpraswpx);
tmpraswpx->BitMap=bmapwpx;
raswpx=AllocVec(sizeof(struct RastPort),MEMF_ANY);
if(raswpx==NULL) return(C2P_NOMEM);
InitRastPort(raswpx);
raswpx->BitMap=bmap;
/* SetUp PenTable
*/
if(colmap==NULL) return("Can't Find ColorMap");
for(i=0;i<256;i++) {
j=ColorPriority[i]*3;
r=Palette[j];
g=Palette[j+1];
b=Palette[j+2];
if(-1==(PenTable[ColorPriority[i]]=ObtainBestPen(colmap,r,g,b,OBP_Precision,PRECISION_GUI,TAG_DONE))) return("Can't Obtain Pens");
}
return(NULL);
} // initgfx()
static void freegfx(void) {
int i;
mawake();
if(GfxBase) {
WaitTOF();
if(colmap) for(i=0;i<256;i++) if(PenTable[i]!=-1) ReleasePen(colmap,PenTable[i]);
}
if(win) {
WTop=win->TopEdge;
WLeft=win->LeftEdge;
WHeight=win->Height;
WWidth=win->Width;
vec.c2p_AddOptionInt("WINTOP",WTop);
vec.c2p_AddOptionInt("WINLEFT",WLeft);
vec.c2p_AddOptionInt("WINHEIGHT",WHeight);
vec.c2p_AddOptionInt("WINWIDTH",WWidth);
Wx=offx;
Wy=offy;
vec.c2p_AddOptionInt("OFFX",Wx);
vec.c2p_AddOptionInt("OFFY",Wy);
ClearMenuStrip(win);
CloseWindow(win);
win=NULL;
}
vec.c2p_Win=NULL;
if(mMenus) { FreeMenus(mMenus); mMenus=NULL; }
if(visualinfo) { FreeVisualInfo(visualinfo); visualinfo=NULL; }
if(vec.c2p_Scr) {
vec.c2p_AddOptionStr("PUBSCREEN",WPubName);
UnlockPubScreen(NULL,vec.c2p_Scr);
vec.c2p_Scr=NULL;
}
if(bmap) { FreeBitMap(bmap); bmap=NULL; }
if(bmapwpx) { FreeBitMap(bmapwpx); bmapwpx=NULL; }
if(tmpraswpx) { FreeVec(tmpraswpx); tmpraswpx=NULL; }
if(raswpx) { FreeVec(raswpx); raswpx=NULL; }
} // freegfx()
char *SAVEDS minit(ULONG scrmode, ULONG overscan, unsigned char *linedeltatab) {
int i;
ULONG res;
char *s;
SysBase=*((struct ExecBase **)4L);
if(!(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",39))) return("Can't open Graphics.library V39");
if(!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",39))) return("Can't open Intuition.library V39");
if(!(GadToolsBase=OpenLibrary("gadtools.library",37))) return("Can't open GadTools.library V37");
if(!(LayersBase=OpenLibrary("layers.library",33))) return("Can't open Layers.library V33");
/* Set up pointer
*/
if(NULL==(mypntchip0=AllocVec((POINTERHEIGHT+1)*2,MEMF_CHIP))) return(C2P_NOMEM);
if(NULL==(mypntchip1=AllocVec((POINTERHEIGHT+1)*2,MEMF_CHIP))) return(C2P_NOMEM);
CopyMem(pointerp0,mypntchip0,2*POINTERHEIGHT);
CopyMem(pointerp1,mypntchip1,2*POINTERHEIGHT);
InitBitMap(&mybmap,2,16,POINTERHEIGHT);
mybmap.Planes[0]=(PLANEPTR)mypntchip0;
mybmap.Planes[1]=(PLANEPTR)mypntchip1;
res=POINTERYRESN_DEFAULT;
if(((GfxBase->ChipRevBits0&GFXF_HR_AGNUS)!=0)&&((GfxBase->ChipRevBits0&GFXF_HR_DENISE)!=0)) res=POINTERXRESN_SCREENRES;
mypointer=NewObject(NULL,"pointerclass",
POINTERA_BitMap, (ULONG)&mybmap,
POINTERA_XOffset, -6,
POINTERA_WordWidth, 1,
POINTERA_XResolution, res,
POINTERA_YResolution, res,
TAG_DONE );
if(mypointer==NULL) return("Can't Create Pointer");
/* Get Options
*/
Wx=vec.c2p_GetOptionInt("OFFX",0);
Wy=vec.c2p_GetOptionInt("OFFY",0);
WTop=vec.c2p_GetOptionInt("WINTOP",0);
WLeft=vec.c2p_GetOptionInt("WINLEFT",0);
WHeight=vec.c2p_GetOptionInt("WINHEIGHT",100);
WWidth=vec.c2p_GetOptionInt("WINWIDTH",300);
s=vec.c2p_GetOptionStr("PUBSCREEN","Workbench");
for(i=0;s[i]!='\0';i++);
if(NULL==(WPubName=AllocVec(i+2,MEMF_ANY))) return(C2P_NOMEM);
CopyMem(s,WPubName,i+1);
return(initgfx());
} // minit
void SAVEDS mfree(void) {
freegfx();
if(mypntchip0) { FreeVec(mypntchip0); mypntchip0=NULL; }
if(mypntchip1) { FreeVec(mypntchip1); mypntchip1=NULL; }
if(mypointer) { DisposeObject(mypointer); mypointer=NULL; }
if(GfxBase) CloseLibrary((struct Library *)GfxBase);
if(IntuitionBase) { CloseLibrary((struct Library *)IntuitionBase); IntuitionBase=NULL; }
if(GadToolsBase) { CloseLibrary(GadToolsBase); GadToolsBase=NULL; }
if(LayersBase) CloseLibrary(LayersBase);
return;
} // free
int SAVEDS mdo(unsigned char *chunky,unsigned char *delta,int numscreen) {
return(mdofull(chunky,numscreen));
} // do
int SAVEDS mdofull(unsigned char *chunky,int numscreen) {
struct IntuiMessage *imsg;
struct MenuItem *n;
int (*func)(struct IntuiMessage *);
int ret=RET_OK,i,move=0,lastx=0,lasty=0;
unsigned char *p,*c;
while((imsg=(struct IntuiMessage *)RemHead(&vec.c2p_MsgList))) {
switch(imsg->Class) {
case IDCMP_CLOSEWINDOW :
ret=RET_QUIT;
break;
case IDCMP_MENUPICK :
while(imsg->Code!=MENUNULL) {
n=ItemAddress(mMenus,imsg->Code);
func=(void *)(GTMENUITEM_USERDATA(n));
ret=func(imsg);
if(ret==RET_NEWWIN||ret==RET_ERROR) {
move=0;
break;
}
imsg->Code=n->NextSelect;
}
break;
case IDCMP_NEWSIZE :
calcwinsizes();
break;
case IDCMP_MOUSEBUTTONS :
if(imsg->Code==SELECTDOWN) {
move=1;
lastx=imsg->MouseX;
lasty=imsg->MouseY;
} else move=0;
break;
}
}
/* Handle Drag Window
*/
if(move!=0) {
int mx,my,class,t1,t2;
ReportMouse(TRUE,win);
SetWindowPointer(win,WA_Pointer,(ULONG)mypointer,TAG_DONE);
while(move!=0) {
WaitPort(win->UserPort);
imsg=(struct IntuiMessage *)GetMsg(win->UserPort);
mx=imsg->MouseX;
my=imsg->MouseY;
class=imsg->Class;
ReplyMsg((struct Message *)imsg);
switch(class) {
case IDCMP_MOUSEBUTTONS :
move=0;
break;
case IDCMP_MOUSEMOVE :
offx+=lastx-mx; offy+=lasty-my;
t1=mx; t2=my;
mx=lastx-mx; my=lasty-my;
lastx=t1; lasty=t2;
if(offx<0) { mx-=offx; offx=0; }
if(offx>maxx) { mx-=offx-maxx; offx=maxx; }
if(offy<0) { my-=offy; offy=0; }
if(offy>maxy) { my-=offy-maxy; offy=maxy; }
ScrollLayer(0,win->RPort->Layer,mx,my);
break;
}
}
SetWindowPointer(win,TAG_DONE);
ReportMouse(FALSE,win);
}
if(chunky!=NULL) {
/* Convert chunky into PenArray
*/
i=SCRSIZE;
c=chunky;
p=PenArray;
do { *p++=PenTable[*c++]; } while(--i);
if(ret!=RET_NEWWIN||ret!=RET_ERROR) {
/* Do the c2p
*/
WritePixelArray8(raswpx,0,0,SCRWIDTH-1,SCRHEIGHT-1,PenArray,tmpraswpx);
/* Copy into the window
*/
LockLayerRom(win->RPort->Layer);
CopySBitMap(win->RPort->Layer);
UnlockLayerRom(win->RPort->Layer);
}
}
return(ret);
} // dofull
int SAVEDS mdont(void) {
return(mdofull(NULL,0));
} // dont
void SAVEDS msleep(void) {
if(win) {
InitRequester(&InvisibleRequester);
Request(&InvisibleRequester,win);
SetWindowPointer(win,WA_BusyPointer,TRUE,TAG_DONE);
winsleeped=1;
}
}
void SAVEDS mawake(void) {
if(winsleeped) {
if(win) {
EndRequest(&InvisibleRequester,win);
SetWindowPointerA(win,NULL);
winsleeped=0;
}
}
}