// Copyright (c) 1999 Philip A. Hardin (pahardin@cs.utexas.edu) // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License v2 or later. #include #include // to get strlen #include #include // to get XEvent, XFontStruct #ifndef NO_OPENGL #include #include #endif #include "bbgfxtarget.h" #include "xpanel3d.h" // to get MINDIST #define DEFAULTWINWIDTH 512 #define DEFAULTWINHEIGHT ((int)(DEFAULTWINWIDTH*0.6+6*14+2)) /*======================================================================*/ bbGfxTarget::bbGfxTarget(bool ugl) : gfxTarget(ugl), gfxSize(pt2d(DEFAULTWINWIDTH,DEFAULTWINWIDTH*0.6)), fontSize(pt2d(6,14)), cursor(pt2d(0,0)), rightmost(0) { cursorOrg= pt2d(8,gfxSize.y); textSize= pt2d(gfxSize.x,fontSize.y*6+2); } /*----------------------------------------------------------------------*/ void bbGfxTarget::LoadFont(const char *name) { font= XLoadQueryFont(disp,name); if (font==NULL) { cerr << "cannot open font " << name << endl; exit(-1); } } /*----------------------------------------------------------------------*/ void bbGfxTarget::GetGC() { unsigned long valuemask= 0; XGCValues values; gc= XCreateGC(disp,win,valuemask,&values); XSetLineAttributes(disp,gc,0,LineSolid,CapRound,JoinRound); XSetFont(disp,gc,font->fid); pmgc= XCreateGC(disp,pm,valuemask,&values); XSetLineAttributes(disp,pmgc,0,LineSolid,CapRound,JoinRound); XSetFont(disp,pmgc,font->fid); } /*----------------------------------------------------------------------*/ // Creates the BB window. Also sets the .cmap field. void bbGfxTarget::CreateWindow(int argc, char *argv[]) { static short x=0, y=0; x += 48; y += 48; #ifndef NO_OPENGL if (UseGL()) { int dummy; if (!glXQueryExtension(disp,&dummy,&dummy)) { cout << "X server does not appear to support OpenGL; using Xlib rendering instead..." <visual,AllocNone); swa.colormap= cmap; win= XCreateWindow(disp, rootWin, x, y, DEFAULTWINWIDTH, DEFAULTWINHEIGHT, 0,vi->depth, InputOutput, vi->visual, CWEventMask|CWColormap|CWBorderPixel, &swa); XFree(vi); #endif } else { cmap= DefaultColormap(disp,screenNo); win= XCreateWindow(disp, rootWin, x, y, DEFAULTWINWIDTH, DEFAULTWINHEIGHT, 0,CopyFromParent, InputOutput, CopyFromParent, CWEventMask|CWBorderPixel, &swa); } XSetStandardProperties(disp,win,"BattleBall","BattleBall",None,argv,argc, NULL); #ifndef NO_OPENGL if (UseGL()) { glXMakeCurrent(disp,win,ctx); glViewport(0,(GLint)textSize.y,(GLsizei)gfxSize.x,(GLsizei)gfxSize.y); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-0.5,0.5, -0.3,0.3, MINDIST,100000); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //gluLookAt(0,0,0, 0,0,-1, 0,1,0); } #endif LoadFont("6x13"); XWindowAttributes attr; XGetWindowAttributes(disp,win,&attr); pm= XCreatePixmap(disp,win,attr.width,attr.height,attr.depth); GetGC(); XMapWindow(disp,win); } /*----------------------------------------------------------------------*/ void bbGfxTarget::AllocColors(char *colorNames[], int numColors) { forii(numColors) GetColor(colorNames[i],colors[i]); } /*----------------------------------------------------------------------*/ void bbGfxTarget::GetColor(char *name, ulong& colorPixel) { XColor color1,color2; XAllocNamedColor(disp,cmap,name,&color1,&color2); colorPixel= color1.pixel; } /*----------------------------------------------------------------------*/ void bbGfxTarget::HandleResize(XEvent *event, bool refit) { gfxSize.x= ((XConfigureEvent *)event)->width; textSize.x= gfxSize.x; gfxSize.y= 0.6*gfxSize.x; cursorOrg.y= gfxSize.y; if (refit) ResizeWindow(gfxSize +pt2d(0,textSize.y)); else gfxTarget::HandleResize(); #ifndef NO_OPENGL if (UseGL()) glViewport(0,(GLint)textSize.y,(GLsizei)gfxSize.x,(GLsizei)gfxSize.y); #endif } /*----------------------------------------------------------------------*/ void bbGfxTarget::DoubleBufferEnd() { gfxTarget::DoubleBufferEnd(); #ifndef NO_OPENGL if (UseGL()) XCopyArea(disp,pm,win,gc, 0,(int)gfxSize.y, (int)textSize.x,(int)textSize.y, 0,(int)gfxSize.y); #endif } /*----------------------------------------------------------------------*/ // Clear the gfx area of the game window void bbGfxTarget::ClearGfx() const { if (UseGL()) { #ifndef NO_OPENGL glClearIndex(White()); glClear(GL_COLOR_BUFFER_BIT); #endif } else { SetForeground(White()); FillRectangle(pt2d(0,0),gfxSize); } } void bbGfxTarget::ClearStatus() const { SetForeground(White()); FillRectangle(pt2d(0,gfxSize.y),textSize); SetForeground(Black()); DrawRectangle(pt2d(0,gfxSize.y),textSize -pt2d(1,1)); } /*----------------------------------------------------------------------*/ // pt = character position in text window // Returns the pixel position in the text window corresponding to 'pt' pt2d bbGfxTarget::PixelPos(const pt2d& pt) { return pt2d(pt.x*fontSize.x, pt.y*fontSize.y+gfxSize.y); } /*----------------------------------------------------------------------*/ bbGfxTarget& bbGfxTarget::operator<<(char *s) { int len= strlen(s); DrawString(cursorOrg +cursor*fontSize +pt2d(0,fontSize.y-2),s); if (cursor.x+len >rightmost) rightmost= (int) cursor.x+len; cursor.y++; return *this; } /*-------------------------------------------------------------------------*/ bbGfxTarget& bbGfxTarget::Box(int x, int y, int width, int height, bool highlight) { DrawRectangle(cursorOrg +pt2d(x+cursor.x,y)*fontSize +pt2d(-3,1), pt2d(width,height)*fontSize +pt2d(4,-2)); if (highlight) { DrawRectangle(cursorOrg +pt2d(x+cursor.x,y)*fontSize +pt2d(-4,0), pt2d(width,height)*fontSize +pt2d(6,0)); } return *this; } /*-------------------------------------------------------------------------*/ bbGfxTarget& bbGfxTarget::Tab(int spaces, int newy) { cursor.x= rightmost +spaces; cursor.y= newy; return *this; }