home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magazyn Exec 1
/
CD_Magazyn_EXEC_nr_1.iso
/
Gry
/
battalion.lha
/
Battalion
/
source
/
tk_amiga.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-12-23
|
23KB
|
807 lines
/*
* (c) Copyright 1993, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the above
* copyright notice appear in all copies and that both the copyright notice
* and this permission notice appear in supporting documentation, and that
* the name of Silicon Graphics, Inc. not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission.
*
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
/* Mesa tkAmiga by Stefan Z (d94sz@efd.lth.se)*/
/*
History:
1.0 960315 Now almost evetything is implemented
1.1 960425 Fixed problem with double closeclicks (Thanx to Daniel Jönsson)
1.2 960731 Modified due to api change in AmigaMesa
1.3 Implemented div. Input modifier and changed windowhandling (Georg 'Wulf' Krämer)
2.0 Modifications for vbcc version and StormMesa by Frank Wille
TODO:
Exposefunc
*/
#undef USE_CLIP_LAYER
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/libraries.h>
#include <exec/io.h>
#include <devices/inputevent.h>
#include <intuition/intuition.h>
#ifdef __GNUC__
#include <inline/exec.h>
#include <inline/intuition.h>
#include <inline/graphics.h>
#ifdef USE_CLIP_LAYER
#include <inline/layers.h>
#endif
#else
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/console.h>
#ifdef USE_CLIP_LAYER
#include <proto/layers.h>
#endif
#endif
#include "tk_amiga.h"
#include <GL/Amigamesa.h>
#define static
#if defined(__cplusplus) || defined(c_plusplus)
#define class c_class
#endif
#if DBG
#define TKASSERT(x) \
if ( !(x) ) { \
PrintMessage("%s(%d) Assertion failed %s\n", \
__FILE__, __LINE__, #x); \
}
#else
#define TKASSERT(x)
#endif /* DBG */
/* Some Bitmasks for Amigaevents */
#define ControlMask (IEQUALIFIER_CONTROL)
#define ShiftMask (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)
#define MousePressedMask (SELECTDOWN | MENUDOWN | MIDDLEDOWN)
/******************************************************************************/
struct wnd
{
int x, y, width, height;
GLenum type;
struct amigamesa_context *context;
};
struct wnd win={0,0,100,100,TK_INDEX,NULL};
struct Screen *screen = NULL;
struct Window *tkhwnd = NULL;
struct Library *ConsoleDevice = NULL;
static struct IOStdReq *conio;
#ifdef USE_CLIP_LAYER
struct Region *tkclipreg = NULL;
#endif
/* Local prototypes */
struct Region *clipWindow(struct Window *win,
LONG minX, LONG minY, LONG maxX, LONG maxY);
struct Region *clipWindowToBorders(struct Window *win);
/* key map */
static char keymap[128] = { 0 }; /* state of all raw keys */
GLboolean tkPopupEnable = TRUE;
/* Fixed palette support. */
/*
#define BLACK PALETTERGB(0,0,0)
#define WHITE PALETTERGB(255,255,255)
#define NUM_STATIC_COLORS (COLOR_BTNHIGHLIGHT - COLOR_SCROLLBAR + 1)
*/
static void (*ExposeFunc)(int, int) = NULL;
static void (*ReshapeFunc)(GLsizei, GLsizei) = NULL;
static void (*DisplayFunc)(void) = NULL;
static GLenum (*KeyDownFunc)(int, GLenum) = NULL;
static GLenum (*KeyUpFunc)(int, GLenum) = NULL;
static GLenum (*MouseDownFunc)(int, int, GLenum) = NULL;
static GLenum (*MouseUpFunc)(int, int, GLenum) = NULL;
static GLenum (*MouseMoveFunc)(int, int, GLenum) = NULL;
static void (*IdleFunc)(void) = NULL;
/*
* Prototypes for the debugging functions go here
*/
#define DBGFUNC 0
#if DBGFUNC
static void DbgPrintf( const char *Format, ... );
static void pwi( void );
static void pwr(RECT *pr);
/*static void ShowPixelFormat(HDC hdc);*/
#endif
#ifdef USE_CLIP_LAYER
/* Get from clipping example of the RKM */
/*
** clipWindow()
** Clip a window to a specified rectangle (given by upper left and
** lower right corner.) the removed region is returned so that it
** may be re-installed later.
*/
struct Region *clipWindow(struct Window *win,
LONG minX, LONG minY, LONG maxX, LONG maxY)
{
struct Region *new_region;
struct Rectangle my_rectangle;
/* set up the limits for the clip */
my_rectangle.MinX = minX;
my_rectangle.MinY = minY;
my_rectangle.MaxX = maxX;
my_rectangle.MaxY = maxY;
/* get a new region and OR in the limits. */
if (NULL != (new_region = NewRegion()))
{
if (FALSE == OrRectRegion(new_region, &my_rectangle))
{
DisposeRegion(new_region);
new_region = NULL;
}
}
/* Install the new region, and return any existing region.
** If the above allocation and region processing failed, then
** new_region will be NULL and no clip region will be installed.
*/
return(InstallClipRegion(win->WLayer, new_region));
}
/*
** clipWindowToBorders()
** clip a window to its borders.
** The removed region is returned so that it may be re-installed later.
*/
struct Region *clipWindowToBorders(struct Window *win)
{
return(clipWindow(win, win->BorderLeft, win->BorderTop,
win->Width - win->BorderRight - 1, win->Height - win->BorderBottom - 1));
}
#endif
float tkRGBMap[8][3] =
{
{ 0, 0, 0 },
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 1, 1, 0 },
{ 0, 0, 1 },
{ 1, 0, 1 },
{ 0, 1, 1 },
{ 1, 1, 1 }
};
int atk_setIDCMPs(void)
{
int mask;
mask=IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE;
if (ReshapeFunc)
mask |=IDCMP_NEWSIZE;
if (KeyDownFunc)
mask |=IDCMP_RAWKEY;
if (MouseDownFunc||MouseUpFunc)
mask |=IDCMP_MOUSEBUTTONS;
if (MouseMoveFunc)
mask |= IDCMP_MOUSEMOVE;
return(mask);
}
/* TODO (*ExposeFunc)(int, int) */
void atk_modifyIDCMP(void)
{
if(tkhwnd)
{
ModifyIDCMP( tkhwnd, atk_setIDCMPs() );
}
}
int atk_SpecialKeyConv(int code)
{
int key = 0;
switch (code) {
case 0x40: key = TK_SPACE; break;
case 0x41: key = TK_BACKSPACE; break;
case 0x42: key = TK_TAB; break;
case 0x43:
case 0x44: key = TK_RETURN; break;
case 0x45: key = TK_ESCAPE; break;
case 0x46: key = TK_DEL; break;
case CURSORLEFT: key = TK_LEFT; break;
case CURSORRIGHT: key = TK_RIGHT; break;
case CURSORUP: key = TK_UP; break;
case CURSORDOWN: key = TK_DOWN; break;
case 0x60: key = TK_SHIFT_L; break;
case 0x61: key = TK_SHIFT_R; break;
case 0x63: key = TK_CONTROL_L; break;
case 0x64: key = TK_ALT_L; break;
case 0x65: key = TK_ALT_R; break;
}
return (key);
}
int atk_RawKeyConv(UWORD code,UWORD qual)
{
static struct InputEvent ie = {
NULL,IECLASS_RAWKEY,0,0,0
};
int cnt,key = 0;
UBYTE buf[8];
ie.ie_Code = code;
ie.ie_Qualifier = qual;
ie.ie_position.ie_addr = NULL; /* ??? @@@@ */
if (RawKeyConvert(&ie,buf,8,NULL) == 1)
return ((unsigned)buf[0]);
return (0);
}
GLenum atk_SendKeyEvents()
{
int i,key;
char code;
UWORD qual;
GLenum mask,redraw=GL_FALSE;
for (i=0; i<0x68; i++) {
if (code = keymap[i]) {
mask = 0;
if (i < 0x40) {
qual = 0;
if (code & 2) {
qual |= IEQUALIFIER_LSHIFT;
mask |= TK_SHIFT;
}
if (code & 4) {
qual |= IEQUALIFIER_CONTROL;
mask |= TK_CONTROL;
}
if (!(key = atk_RawKeyConv((UWORD)i,qual)))
key = atk_SpecialKeyConv(i);
}
else
key = atk_SpecialKeyConv(i);
if (code & 16) {
/* key release event */
keymap[i] = 0;
if (key && KeyUpFunc)
if ((*KeyUpFunc)(key,mask) == GL_TRUE)
redraw = GL_TRUE;
}
else if (key && KeyDownFunc) {
if ((*KeyDownFunc)(key,mask) == GL_TRUE)
redraw = GL_TRUE;
}
}
}
return (redraw);
}
/***************************************************************
* *
* Exported Functions go here *
* *
***************************************************************/
void tkNewCursor(GLint id, GLubyte *shapeBuf, GLubyte *maskBuf,
GLenum fgColor, GLenum bgColor, GLint hotX, GLint hotY)
{
/* cursor.c */
}
void tkSetCursor(GLint id)
{
/* cursor.s*/
}
void tkErrorPopups(GLboolean bEnable)
{
tkPopupEnable = bEnable;
}
void tkCloseWindow(void)
{
if (ConsoleDevice) {
CloseDevice((struct IORequest *)conio);
DeleteMsgPort(conio->io_Message.mn_ReplyPort);
DeleteIORequest(conio);
ConsoleDevice = NULL;
}
if (win.context)
{
AmigaMesaDestroyContext(win.context);
win.context=NULL;
}
#ifdef USE_CLIP_LAYER
if (tkclipreg)
{
tkclipreg = InstallClipRegion(tkhwnd->WLayer, tkclipreg);
DisposeRegion(tkclipreg);
tkclipreg = NULL;
}
#endif
if (tkhwnd)
{
CloseWindow(tkhwnd);
tkhwnd=NULL;
}
}
void tkExec(void)
{
struct IntuiMessage *msg;
BOOL done = FALSE;
BOOL press=FALSE;
BOOL rawkey = FALSE;
int key,id;
/* Redraw handling changed by Wulf 11. Aug. 96 to ensure the
same handling under all systems */
GLenum Redraw=GL_FALSE;
for (key=0; key<128; keymap[key++]=0); /* reset keymap */
if (ReshapeFunc)
(*ReshapeFunc)(tkhwnd->Width-tkhwnd->BorderLeft-tkhwnd->BorderRight-2,
tkhwnd->Height-tkhwnd->BorderTop-tkhwnd->BorderBottom-2);
if (DisplayFunc)
(*DisplayFunc)();
while (!done)
{
if (msg = (struct IntuiMessage *)GetMsg(tkhwnd->UserPort))
{
id=msg->Class;
/* after ReplyMsg, you are nolonger allowed to use msg !*/
switch (id)
{
case IDCMP_NEWSIZE:
/* Sizes should be adjusted by border, but painting isn't adjusted :-( */
win.width= tkhwnd->Width-tkhwnd->BorderLeft-tkhwnd->BorderRight-2;
win.height= tkhwnd->Height-tkhwnd->BorderTop-tkhwnd->BorderBottom-2;
#ifdef USE_CLIP_LAYER
if (tkclipreg) /* Get rid of last clipping region */
{
DisposeRegion(InstallClipRegion(msg->IDCMPWindow->WLayer,NULL));
}
clipWindowToBorders(msg->IDCMPWindow);
#endif
ReplyMsg((struct Message *)msg);
if (ReshapeFunc)
(*ReshapeFunc)(win.width, win.height);
Redraw = GL_TRUE;
break;
case IDCMP_RAWKEY:
{
char k = 1;
key = (int)(msg->Code & 0x7f);
if (key < 0x40) {
if (msg->Qualifier & ShiftMask)
k |= 2;
#if 0 /* don't want CTRL-keys for Battalion! */
if (msg->Qualifier & ControlMask)
k |= 4;
#endif
}
if (msg->Code & IECODE_UP_PREFIX)
keymap[key] |= 16; /* release flag */
else
keymap[key] = k;
ReplyMsg((struct Message *)msg);
rawkey = TRUE;
}
break;
case IDCMP_MOUSEMOVE:
if (MouseMoveFunc) {
int x = msg->MouseX,y = msg->MouseY;
ReplyMsg((struct Message *)msg);
Redraw = (*MouseMoveFunc)(x,y,press);
} else
ReplyMsg((struct Message *)msg);
break;
case IDCMP_MOUSEBUTTONS:
/* Buttonhandling changed phx 22.12.99 */
{
GLenum mask = 0;
int x = msg->MouseX, y = msg->MouseY;
switch (msg->Code & 0x7f)
{
case IECODE_LBUTTON:
mask |= TK_LEFTBUTTON; break;
case IECODE_MBUTTON:
mask |= TK_MIDDLEBUTTON; break;
case IECODE_RBUTTON:
mask |= TK_RIGHTBUTTON; break;
}
if (msg->Qualifier & ControlMask)
mask |= TK_CONTROL;
if (msg->Qualifier & ShiftMask)
mask |= TK_SHIFT;
if (msg->Code & IECODE_UP_PREFIX)
{
if (MouseUpFunc)
{
ReplyMsg((struct Message *)msg);
Redraw = (*MouseUpFunc)(x,y,mask);
} else
ReplyMsg((struct Message *)msg);
press=0;
}
else
{
press=mask;
if (MouseDownFunc) {
ReplyMsg((struct Message *)msg);
Redraw = (*MouseDownFunc)(x,y,mask);
} else
ReplyMsg((struct Message *)msg);
}
}
break;
case IDCMP_REFRESHWINDOW: /* Not entierly tested! Wulf 11.08.96 */
BeginRefresh(msg->IDCMPWindow); /* Refresh Gadgets */
EndRefresh(msg->IDCMPWindow, TRUE);
ReplyMsg((struct Message *)msg);
if (ExposeFunc)
(*ExposeFunc)(win.width, win.height);
Redraw = GL_TRUE;
break;
case IDCMP_CLOSEWINDOW:
ReplyMsg((struct Message *)msg);
done = TRUE;
break;
default:
ReplyMsg((struct Message *)msg);
break;
}
}
#if 0
if (rawkey) {
rawkey = FALSE;
}
else {
#endif
if (atk_SendKeyEvents() == GL_TRUE)
Redraw = GL_TRUE;
/* TODO Fill this with tests and call apropriate functions */
if (IdleFunc)
{
(*IdleFunc)();
Redraw = GL_TRUE;
}
if ((Redraw==GL_TRUE) && DisplayFunc) /* Redraw handling changed by Wulf 11. Aug. 96 */
{
(*DisplayFunc)();
Redraw = GL_FALSE;
}
if(!done && !IdleFunc)
{
WaitPort(tkhwnd->UserPort);
}
/* }*/
}
tkQuit(); /* do not return after quit */
}
void tkExposeFunc(void (*Func)(int, int))
{
ExposeFunc = Func;
atk_modifyIDCMP();
}
void tkReshapeFunc(void (*Func)(GLsizei, GLsizei))
{
ReshapeFunc = Func;
atk_modifyIDCMP();
}
void tkDisplayFunc(void (*Func)(void))
{
DisplayFunc = Func;
}
void tkKeyDownFunc(GLenum (*Func)(int, GLenum))
{
KeyDownFunc = Func;
atk_modifyIDCMP();
}
void tkKeyUpFunc(GLenum (*Func)(int, GLenum))
{
KeyUpFunc = Func;
}
void tkMouseDownFunc(GLenum (*Func)(int, int, GLenum))
{
MouseDownFunc = Func;
atk_modifyIDCMP();
}
void tkMouseUpFunc(GLenum (*Func)(int, int, GLenum))
{
MouseUpFunc = Func;
atk_modifyIDCMP();
}
void tkMouseMoveFunc(GLenum (*Func)(int, int, GLenum))
{
MouseMoveFunc = Func;
atk_modifyIDCMP();
}
void tkIdleFunc(void (*Func)(void))
{
IdleFunc = Func;
}
void tkInitPosition(int x, int y, int width, int height)
{
win.x=x;
win.y=y;
win.width=width;
win.height=height;
}
void tkInitDisplayMode(GLenum type)
{
win.type = type;
}
GLenum tkInitWindow(char *title)
{
struct MsgPort *conport;
GLenum Result =GL_FALSE,
RGB_Flag=GL_TRUE,
DB_Flag =GL_FALSE;
if (!(screen = LockPubScreen("MESA")))
screen = LockPubScreen(NULL);
if (screen)
{
/* open the window on the public screen */
tkhwnd = OpenWindowTags(NULL,
WA_Left, win.x, WA_Top, win.x,
WA_InnerWidth, win.width,WA_InnerHeight, win.height,
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_SizeGadget, TRUE,
WA_DepthGadget, TRUE,
WA_SmartRefresh, TRUE,
WA_ReportMouse, TRUE,
WA_NoCareRefresh, TRUE,
WA_RMBTrap, TRUE, /* Detect right mouse events, no Menus */
WA_SizeBBottom, TRUE,
WA_Activate, TRUE,
WA_MinWidth,100, WA_MinHeight,30,
WA_MaxWidth,-1, WA_MaxHeight,-1,
WA_IDCMP, atk_setIDCMPs(),
WA_Flags, WFLG_SIZEGADGET | WFLG_DRAGBAR,
WA_Title, title,
WA_PubScreen, screen,
TAG_END);
/* Unlock the screen. The window now acts as a lock on
** the screen, and we do not need the screen after the
** window has been closed. */
UnlockPubScreen(NULL, screen);
if (tkhwnd)
{
#ifdef USE_CLIP_LAYER
tkclipreg = clipWindowToBorders(tkhwnd);
#endif
if (win.type & TK_INDEX)
{
RGB_Flag=GL_FALSE;
}
if (win.type & TK_DOUBLE)
{
DB_Flag=GL_TRUE;
}
win.context=AmigaMesaCreateContextTags(
AMA_Window,(unsigned long) tkhwnd,
AMA_RastPort,(unsigned long)tkhwnd->RPort,
AMA_Screen,(unsigned long) tkhwnd->WScreen,
AMA_RGBMode, RGB_Flag,
AMA_DoubleBuf, DB_Flag,
AMA_NoStencil, GL_TRUE,
AMA_Left, tkhwnd->BorderLeft,
AMA_Bottom, tkhwnd->BorderBottom,
AMA_Width, win.width,
AMA_Height, win.height,
AMA_Fast, GL_TRUE,
TAG_DONE,0);
AmigaMesaMakeCurrent(win.context,win.context->buffer);
/* open console.device */
if (conport = CreateMsgPort()) {
if (conio = CreateIORequest(conport,
sizeof(struct IOStdReq))) {
if (OpenDevice("console.device",-1,
(struct IORequest *)conio,0) == 0) {
ConsoleDevice = (struct Library *)conio->io_Device;
Result = GL_TRUE;
}
else {
DeleteIORequest(conio);
DeleteMsgPort(conport);
}
}
else
DeleteMsgPort(conport);
}
if (Result == GL_FALSE)
printf("Couldn't open console.device!\n");
}
else
{
printf("Failed to open window.\n");
}
}
return (Result);
}
/******************************************************************************/
/*
* You cannot just call DestroyWindow() here. The programs do not expect
* tkQuit() to return; DestroyWindow() just sends a WM_DESTROY message
*/
void tkQuit(void)
{
tkCloseWindow();
exit(0); /*TODO*/
}
/******************************************************************************/
void tkSetOneColor(int index, float r, float g, float b)
{
AmigaMesaSetOneColor(win.context,index,r,g,b);
}
void tkSetFogRamp(int density, int startIndex)
{
/* TODO */
printf("tkSetFogRamp(%d,%d) TODO\n",density,startIndex);
}
void tkSetGreyRamp(void)
{
/* TODO */
printf("tkSetGreyRamp() TODO\n");
}
void tkSetRGBMap( int Size, float *Values )
{
/* TODO */
printf("tkSetRGBMap(%d,%f) TODO\n",Size,*Values);
}
void tkSetOverlayMap(int size, float *rgb)
{
printf("tkSetOverlayMap(%d,%f) TODO\n",size,*rgb);
}
/******************************************************************************/
void tkSwapBuffers(void)
{
AmigaMesaSwapBuffers(win.context);
}
/******************************************************************************/
GLint tkGetColorMapSize(void)
{
/* TODO */
printf("tkGetColorMapSize() TODO\n");
return(255);
}
void tkGetMouseLoc(int *x, int *y)
{
*x = tkhwnd->MouseX;
*y = tkhwnd->MouseY;
}
GLenum tkGetDisplayMode(void)
{
return win.type;
}
GLenum tkSetWindowLevel(GLenum level)
{
printf("tkSetWindowLevel(%d) TODO\n",level);
return GL_FALSE;
}
/*
TK_RGBImageRec *tkRGBImageLoad(char *fileName)
{
printf("tkRGBImageLoad(%s) TODO\n",fileName);
}
*/
void tkGetSystem(TKenum type, void *ptr)
{
printf("tkGetSystem(%d,*ptr) TODO\n",type);
/* getset.c */
}
#undef USE_CLIP_LAYER