| 1 | /***************************************************************************\r |
| 2 | menu.c - description\r |
| 3 | -------------------\r |
| 4 | begin : Sun Mar 08 2009\r |
| 5 | copyright : (C) 1999-2009 by Pete Bernert\r |
| 6 | web : www.pbernert.com \r |
| 7 | \r |
| 8 | PCSX rearmed adjustments (c) notaz, 2012\r |
| 9 | ***************************************************************************/\r |
| 10 | \r |
| 11 | /***************************************************************************\r |
| 12 | * *\r |
| 13 | * This program is free software; you can redistribute it and/or modify *\r |
| 14 | * it under the terms of the GNU General Public License as published by *\r |
| 15 | * the Free Software Foundation; either version 2 of the License, or *\r |
| 16 | * (at your option) any later version. See also the license.txt file for *\r |
| 17 | * additional informations. *\r |
| 18 | * *\r |
| 19 | ***************************************************************************/\r |
| 20 | \r |
| 21 | #include "gpuStdafx.h"\r |
| 22 | \r |
| 23 | #define _IN_MENU\r |
| 24 | \r |
| 25 | #include "gpuExternals.h"\r |
| 26 | \r |
| 27 | ////////////////////////////////////////////////////////////////////////\r |
| 28 | // field with menu chars... like good old C64 time :)\r |
| 29 | ////////////////////////////////////////////////////////////////////////\r |
| 30 | \r |
| 31 | static const GLubyte texrasters[40][12]= {\r |
| 32 | \r |
| 33 | // 0,0 FPS\r |
| 34 | {0x00,0x60,0x60,0x60,0x60,0x60,0x7e,0x60,0x60,0x60,0x60,0x7f},\r |
| 35 | {0x00,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x1f},\r |
| 36 | {0x00,0x03,0x06,0x00,0x00,0x00,0xc3,0x66,0x66,0x66,0x66,0xc3},\r |
| 37 | {0x00,0xf0,0x18,0x18,0x18,0x18,0xf0,0x00,0x00,0x00,0x18,0xf0},\r |
| 38 | // 4,0 0\r |
| 39 | {0x00,0x3c,0x66,0xc3,0xe3,0xf3,0xdb,0xcf,0xc7,0xc3,0x66,0x3c},\r |
| 40 | // 5,0 1\r |
| 41 | {0x00,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78,0x38,0x18},\r |
| 42 | // 6,0 2\r |
| 43 | {0x00,0xff,0xc0,0xc0,0x60,0x30,0x18,0x0c,0x06,0x03,0xe7,0x7e},\r |
| 44 | // 7,0 3\r |
| 45 | \r |
| 46 | {0x00,0x7e,0xe7,0x03,0x03,0x07,0x7e,0x07,0x03,0x03,0xe7,0x7e},\r |
| 47 | // 0,1 4\r |
| 48 | {0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0xff,0xcc,0x6c,0x3c,0x1c,0x0c},\r |
| 49 | // 1,1 5\r |
| 50 | {0x00,0x7e,0xe7,0x03,0x03,0x07,0xfe,0xc0,0xc0,0xc0,0xc0,0xff},\r |
| 51 | // 2,1 6\r |
| 52 | {0x00,0x7e,0xe7,0xc3,0xc3,0xc7,0xfe,0xc0,0xc0,0xc0,0xe7,0x7e},\r |
| 53 | // 3,1 7\r |
| 54 | {0x00,0x30,0x30,0x30,0x30,0x18,0x0c,0x06,0x03,0x03,0x03,0xff},\r |
| 55 | // 4,1 8\r |
| 56 | {0x00,0x7e,0xe7,0xc3,0xc3,0xe7,0x7e,0xe7,0xc3,0xc3,0xe7,0x7e},\r |
| 57 | // 5,1 9\r |
| 58 | {0x00,0x7e,0xe7,0x03,0x03,0x03,0x7f,0xe7,0xc3,0xc3,0xe7,0x7e},\r |
| 59 | // 6,1 smiley\r |
| 60 | {0x00,0x3c,0x42,0x99,0xa5,0x81,0xa5,0x81,0x42,0x3c,0x00,0x00},\r |
| 61 | // 7,1 sun\r |
| 62 | {0x00,0x08,0x49,0x2a,0x1c,0x7f,0x1c,0x2a,0x49,0x08,0x00,0x00},\r |
| 63 | \r |
| 64 | // 0,2 fl + empty box\r |
| 65 | {0xff,0x81,0x81,0x81,0xff,0x00,0x87,0x84,0x84,0xf4,0x84,0xf8},\r |
| 66 | // 1,2 fs + grey box\r |
| 67 | {0xff,0xab,0xd5,0xab,0xff,0x00,0x87,0x81,0x87,0xf4,0x87,0xf8},\r |
| 68 | // 2,2 od + filled box\r |
| 69 | {0xff,0xff,0xff,0xff,0xff,0x00,0x66,0x95,0x95,0x95,0x96,0x60},\r |
| 70 | // 3,2 fi + half grey box\r |
| 71 | {0xff,0xa1,0xd1,0xa1,0xff,0x00,0x82,0x82,0x82,0xe2,0x82,0xf8},\r |
| 72 | // 4,2 di + half filled box\r |
| 73 | {0xff,0xf1,0xf1,0xf1,0xff,0x00,0xe2,0x92,0x92,0x92,0x92,0xe0},\r |
| 74 | // 5,2 am + grey box\r |
| 75 | {0xff,0xab,0xd5,0xab,0xff,0x00,0x95,0x95,0x95,0xf7,0x95,0x60},\r |
| 76 | // 6,2 ab + filled box\r |
| 77 | {0xff,0xff,0xff,0xff,0xff,0x00,0x97,0x95,0x96,0xf5,0x96,0x60},\r |
| 78 | // 7,2 fa\r |
| 79 | {0x00,0x00,0x00,0x00,0x00,0x00,0x85,0x85,0x87,0xf5,0x82,0xf8},\r |
| 80 | \r |
| 81 | // 0,3 fb\r |
| 82 | {0xff,0x8b,0x85,0x8b,0xff,0x00,0x82,0x82,0x82,0xe2,0x87,0xf8},\r |
| 83 | // 1,3 gf\r |
| 84 | {0xff,0x8f,0x8f,0x8f,0xff,0x00,0x74,0x94,0x96,0xb4,0x87,0x70},\r |
| 85 | // 2,3 D\r |
| 86 | {0xff,0x00,0xfc,0xc6,0xc3,0xc3,0xc3,0xc3,0xc6,0xfc,0x00,0xff}, \r |
| 87 | // 3,3 G\r |
| 88 | {0xff,0x00,0x3e,0x63,0xc3,0xc7,0xc0,0xc0,0x63,0x3e,0x00,0xff},\r |
| 89 | // 4,3\r |
| 90 | {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},\r |
| 91 | // 5,3\r |
| 92 | {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},\r |
| 93 | // 6,3 tex pal smiley\r |
| 94 | {0x00,0x3c,0x7e,0xe7,0xdb,0xff,0xdb,0xff,0x7e,0x3c,0x00,0x00},\r |
| 95 | // 7,3\r |
| 96 | {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},\r |
| 97 | \r |
| 98 | // 0,4 subtract blending (moon)\r |
| 99 | {0x00,0x06,0x1c,0x38,0x78,0x78,0x78,0x38,0x1c,0x06,0x00,0x00},\r |
| 100 | // 1,4 blurring\r |
| 101 | {0x00,0x7e,0x93,0xa5,0x93,0xc9,0x93,0xa5,0x93,0x7e,0x00,0x00},\r |
| 102 | // 2,4 (M)\r |
| 103 | {0xff,0x00,0xc3,0xc3,0xc3,0xdb,0xff,0xe7,0xc3,0x81,0x00,0xff},\r |
| 104 | // 3,4 (A)\r |
| 105 | {0xff,0x00,0xc3,0xc3,0xff,0xc3,0xc3,0x66,0x3c,0x18,0x00,0xff},\r |
| 106 | // 4,4 blank\r |
| 107 | {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},\r |
| 108 | // 5,4\r |
| 109 | {0x00,0xfe,0xc5,0x62,0x35,0x18,0x0c,0xc6,0xc6,0x7c,0x00,0x00},\r |
| 110 | // 6,4 <-\r |
| 111 | {0x00,0x00,0x00,0x00,0x00,0x10,0x30,0x7f,0xff,0x7f,0x30,0x10},\r |
| 112 | // 7,4 .\r |
| 113 | {0x00,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}\r |
| 114 | };\r |
| 115 | \r |
| 116 | ////////////////////////////////////////////////////////////////////////\r |
| 117 | // create lists/stuff for fonts \r |
| 118 | // (as a matter of fact: no more display list used, just a texture)\r |
| 119 | ////////////////////////////////////////////////////////////////////////\r |
| 120 | \r |
| 121 | GLuint gTexFontName=0;\r |
| 122 | \r |
| 123 | void MakeDisplayLists(void) // MAKE FONT \r |
| 124 | {\r |
| 125 | GLubyte TexBytes[64][64][3]; // we use a 64x64 texture\r |
| 126 | int x,y,i,j,n=0; GLubyte col,IB;\r |
| 127 | \r |
| 128 | glPixelStorei(GL_UNPACK_ALIGNMENT,1);\r |
| 129 | \r |
| 130 | memset(TexBytes,0,64*64*3);\r |
| 131 | \r |
| 132 | for(y=0;y<5;y++) // create texture out of raster infos\r |
| 133 | {\r |
| 134 | for(x=0;x<8;x++,n++)\r |
| 135 | {\r |
| 136 | for(i=0;i<12;i++)\r |
| 137 | {\r |
| 138 | IB=texrasters[n][i];\r |
| 139 | for(j=0;j<8;j++)\r |
| 140 | {\r |
| 141 | if(IB&(1<<(7-j))) col=255; else col=0;\r |
| 142 | TexBytes[y*12+i][x*8+j][0]=col;\r |
| 143 | TexBytes[y*12+i][x*8+j][1]=col;\r |
| 144 | TexBytes[y*12+i][x*8+j][2]=col;\r |
| 145 | }\r |
| 146 | }\r |
| 147 | }\r |
| 148 | }\r |
| 149 | \r |
| 150 | glGenTextures(1, &gTexFontName); // set tex params for font texture\r |
| 151 | glBindTexture(GL_TEXTURE_2D, gTexFontName);\r |
| 152 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);\r |
| 153 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\r |
| 154 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);\r |
| 155 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);\r |
| 156 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 64, 64, 0, GL_RGB,\r |
| 157 | GL_UNSIGNED_BYTE,TexBytes);\r |
| 158 | glError();\r |
| 159 | }\r |
| 160 | \r |
| 161 | ////////////////////////////////////////////////////////////////////////\r |
| 162 | // kill existing font stuff\r |
| 163 | ////////////////////////////////////////////////////////////////////////\r |
| 164 | \r |
| 165 | void KillDisplayLists(void)\r |
| 166 | {\r |
| 167 | #ifdef _WINDOWS\r |
| 168 | if(hGFont) DeleteObject(hGFont); // windows: kill info font\r |
| 169 | hGFont=NULL;\r |
| 170 | #endif\r |
| 171 | \r |
| 172 | if(gTexFontName) // del font/info textures\r |
| 173 | {glDeleteTextures(1,&gTexFontName);gTexFontName=0;}\r |
| 174 | }\r |
| 175 | \r |
| 176 | ////////////////////////////////////////////////////////////////////////\r |
| 177 | // display text/infos in gpu menu\r |
| 178 | ////////////////////////////////////////////////////////////////////////\r |
| 179 | \r |
| 180 | #define TEXCHAR_VERTEX(t0,t1,v0,v1,v2) \\r |
| 181 | *pta++ = t0; *pta++ = t1; *pva++ = v0; *pva++ = v1; *pva++ = v2\r |
| 182 | \r |
| 183 | #ifdef OWNSCALE\r |
| 184 | #define DRAWTEXCHAR \\r |
| 185 | pta = text_tex_array, pva = text_vertex_array; \\r |
| 186 | TEXCHAR_VERTEX(fX1/256.0f,fY2/256.0f,fXS1,fYS2,1.0f); \\r |
| 187 | TEXCHAR_VERTEX(fX1/256.0f,fY1/256.0f,fXS1,fYS1,1.0f); \\r |
| 188 | TEXCHAR_VERTEX(fX2/256.0f,fY1/256.0f,fXS2,fYS1,1.0f); \\r |
| 189 | TEXCHAR_VERTEX(fX2/256.0f,fY2/256.0f,fXS2,fYS2,1.0f); \\r |
| 190 | glDrawArrays(GL_TRIANGLE_FAN,0,4)\r |
| 191 | \r |
| 192 | #else\r |
| 193 | #define DRAWTEXCHAR glTexCoord2f(fX1,fY2);glVertex3f(fXS1,fYS2,1.0f);glTexCoord2f(fX1,fY1);glVertex3f(fXS1,fYS1,1.0f);glTexCoord2f(fX2,fY1);glVertex3f(fXS2,fYS1,1.0f);glTexCoord2f(fX2,fY2);glVertex3f(fXS2,fYS2,1.0f);\r |
| 194 | #endif\r |
| 195 | \r |
| 196 | static GLfloat text_tex_array[2*4];\r |
| 197 | static GLfloat text_vertex_array[3*4];\r |
| 198 | \r |
| 199 | void DisplayText(const char *ltext, int right_aligned)\r |
| 200 | {\r |
| 201 | int iX,iY,i;\r |
| 202 | GLfloat fX1,fY1,fX2,fY2,fYS1,fYS2,fXS1,fXS2,fXS,fXSC,fYSC,fYD;\r |
| 203 | GLfloat *pta, *pva;\r |
| 204 | \r |
| 205 | glDisable(GL_SCISSOR_TEST); // disable unwanted ogl states\r |
| 206 | glDisable(GL_ALPHA_TEST);\r |
| 207 | if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;}\r |
| 208 | if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;}\r |
| 209 | if(!bTexEnabled) {glEnable(GL_TEXTURE_2D);bTexEnabled=TRUE;}\r |
| 210 | \r |
| 211 | gTexName=gTexFontName;\r |
| 212 | glBindTexture(GL_TEXTURE_2D,gTexFontName); // now set font texture\r |
| 213 | \r |
| 214 | fYD=fYSC=(GLfloat)PSXDisplay.DisplayMode.y/(GLfloat)iResY; // some pre-calculations\r |
| 215 | fYS1=(GLfloat)PSXDisplay.DisplayMode.y-1.0f*fYSC;\r |
| 216 | fYS2=(GLfloat)PSXDisplay.DisplayMode.y-13.0f*fYSC;\r |
| 217 | fYSC*=13.0f;\r |
| 218 | fXS= (GLfloat)PSXDisplay.DisplayMode.x/(GLfloat)iResX;\r |
| 219 | fXSC= 8.0f*fXS;fXS*=10.0f;\r |
| 220 | fXS1=0.0f;\r |
| 221 | fXS2=50.0f*fXS; // 3 is one option\r |
| 222 | \r |
| 223 | vertex[0].c.lcol=0xffffffff; // set menu text color\r |
| 224 | SETCOL(vertex[0]); \r |
| 225 | \r |
| 226 | //glBegin(GL_QUADS);\r |
| 227 | glEnableClientState(GL_VERTEX_ARRAY);\r |
| 228 | glEnableClientState(GL_TEXTURE_COORD_ARRAY);\r |
| 229 | glDisableClientState(GL_COLOR_ARRAY);\r |
| 230 | glVertexPointer(3,GL_FLOAT,0,text_vertex_array);\r |
| 231 | glTexCoordPointer(2,GL_FLOAT,0,text_tex_array);\r |
| 232 | glError();\r |
| 233 | \r |
| 234 | if(right_aligned)\r |
| 235 | fYSC=fXS1=(GLfloat)PSXDisplay.DisplayMode.x-strlen(ltext)*8.0f;\r |
| 236 | else\r |
| 237 | fYSC=fXS1=1.0f*fXS; // start pos of numbers\r |
| 238 | \r |
| 239 | i=0;do // paint fps numbers\r |
| 240 | {\r |
| 241 | iX=4;iY=4;\r |
| 242 | if(ltext[i]>='0' && ltext[i]<='3')\r |
| 243 | {iX=4+ltext[i]-'0';iY=0;}\r |
| 244 | else\r |
| 245 | if(ltext[i]>='4' && ltext[i]<='9')\r |
| 246 | {iX=ltext[i]-'4';iY=1;}\r |
| 247 | else\r |
| 248 | if(ltext[i]=='.')\r |
| 249 | {iX=7;iY=4;}\r |
| 250 | else\r |
| 251 | if(ltext[i]==0) break;\r |
| 252 | \r |
| 253 | fX1=(GLfloat)iX*32.0f; fX2=fX1+32.0f;\r |
| 254 | fY1=(GLfloat)iY*48.0f; fY2=fY1+48.0f;\r |
| 255 | fXS1+=fXS;\r |
| 256 | fXS2=fXS1+fXSC;\r |
| 257 | \r |
| 258 | DRAWTEXCHAR;\r |
| 259 | \r |
| 260 | i++;\r |
| 261 | }\r |
| 262 | while(i);\r |
| 263 | \r |
| 264 | //glEnd();\r |
| 265 | glDisableClientState(GL_VERTEX_ARRAY);\r |
| 266 | glDisableClientState(GL_TEXTURE_COORD_ARRAY);\r |
| 267 | CSTEXTURE = CSVERTEX = CSCOLOR = 0;\r |
| 268 | \r |
| 269 | glEnable(GL_ALPHA_TEST); // repair needed states\r |
| 270 | glEnable(GL_SCISSOR_TEST); \r |
| 271 | glError();\r |
| 272 | }\r |
| 273 | \r |
| 274 | ////////////////////////////////////////////////////////////////////////\r |
| 275 | \r |
| 276 | void HideText(void)\r |
| 277 | {\r |
| 278 | GLfloat fYS1,fYS2,fXS1,fXS2,fXS,fXSC,fYSC;\r |
| 279 | \r |
| 280 | glDisable(GL_SCISSOR_TEST); // turn off unneeded ogl states\r |
| 281 | glDisable(GL_ALPHA_TEST);\r |
| 282 | if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;}\r |
| 283 | if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;}\r |
| 284 | if(bTexEnabled) {glDisable(GL_TEXTURE_2D);bTexEnabled=FALSE;}\r |
| 285 | \r |
| 286 | fYSC=(GLfloat)PSXDisplay.DisplayMode.y/(GLfloat)iResY;\r |
| 287 | fYS1=12.0f*fYSC;fYSC*=13.0f;\r |
| 288 | fYS2=0.0f;\r |
| 289 | fXS= (GLfloat)PSXDisplay.DisplayMode.x/(GLfloat)iResX;\r |
| 290 | fXSC= 8.0f*fXS;fXS*=10.0f;\r |
| 291 | fXS1=0.0f;\r |
| 292 | fXS2=50.0f*fXS; \r |
| 293 | \r |
| 294 | vertex[0].c.lcol=0xff000000; // black color\r |
| 295 | SETCOL(vertex[0]); \r |
| 296 | \r |
| 297 | //glBegin(GL_QUADS); // make one quad\r |
| 298 | \r |
| 299 | {\r |
| 300 | GLfloat vertex_array[3*4] = {\r |
| 301 | fXS1,fYS2,0.99996f,\r |
| 302 | fXS1,fYSC,0.99996f,\r |
| 303 | fXS2,fYSC,0.99996f,\r |
| 304 | fXS2,fYS2,0.99996f,\r |
| 305 | };\r |
| 306 | glDisableClientState(GL_TEXTURE_COORD_ARRAY);\r |
| 307 | glEnableClientState(GL_VERTEX_ARRAY);\r |
| 308 | glVertexPointer(3,GL_FLOAT,0,vertex_array);\r |
| 309 | \r |
| 310 | glDrawArrays(GL_TRIANGLE_STRIP,0,4);\r |
| 311 | glDisableClientState(GL_VERTEX_ARRAY);\r |
| 312 | }\r |
| 313 | \r |
| 314 | //glEnd();\r |
| 315 | glEnable(GL_ALPHA_TEST); // enable needed ogl states\r |
| 316 | glEnable(GL_SCISSOR_TEST); \r |
| 317 | }\r |
| 318 | \r |