// pass key character to platform void mgKeyChar( int unicode, int flags) { mgScriptPlatform* platform = (mgScriptPlatform*) mgPlatform; try { platform->keyChar(unicode, flags); } catch (mgErrorMsg* e) { mgString msg; platform->m_errorTable->msgText(msg, e); mgDebug("Exception: %s", (const char*) msg); } catch (mgException* e) { mgDebug("Exception: %s", (const char*) e->m_message); } catch (...) { mgDebug("Exception \"...\""); } }
// pass mouse down to platform void mgMouseDown( int button, int flags) { mgScriptPlatform* platform = (mgScriptPlatform*) mgPlatform; try { platform->mouseDown(button, flags); } catch (mgErrorMsg* e) { mgString msg; platform->m_errorTable->msgText(msg, e); mgDebug("Exception: %s", (const char*) msg); } catch (mgException* e) { mgDebug("Exception: %s", (const char*) e->m_message); } catch (...) { mgDebug("Exception \"...\""); } }
// pass mouse enter to platform void mgMouseEnter( int x, int y) { mgScriptPlatform* platform = (mgScriptPlatform*) mgPlatform; try { platform->mouseEnter(x, y); } catch (mgErrorMsg* e) { mgString msg; platform->m_errorTable->msgText(msg, e); mgDebug("Exception: %s", (const char*) msg); } catch (mgException* e) { mgDebug("Exception: %s", (const char*) e->m_message); } catch (...) { mgDebug("Exception \"...\""); } }
//-------------------------------------------------------------- // return minimum size void mgFormPane::minimumSize( mgDimension& size) { #ifdef TRACE_TABLES mgDebug("FormPane minimumSize..."); #endif // tell the formatter to use tiny page width. Result should be max of // requested width and required width. mgTextFormat format(m_text, (mgTextPage*) this, true, 0, 0, 10); unsigned int posn = 0; format.scan(posn); size.m_width = format.m_boxWidth; // size.m_height = format.m_boxHeight; // =-= table resize of text boxes still broken. keep demos working with this change. size.m_height = format.m_lineHeight; if (m_frame != NULL) { mgDimension exterior; m_frame->getOutsideSize(size, exterior); size = exterior; } #ifdef TRACE_TABLES mgDebug("FormPane minimumSize is (%d by %d)", size.m_width, size.m_height); #endif }
//-------------------------------------------------------------- // load a font and return handle void* mgFTLoadFont( const char* fontFile, double size, int dpi, double &fontHeight, double &fontAscent, double &charWidth) { FT_Face face; int error = FT_New_Face(mgFTLibrary, fontFile, 0, &face); if (error == FT_Err_Unknown_File_Format) { throw new mgException("unknown file format %s", (const char*) fontFile); } else if (error != 0) { throw new mgException("FT_New_Face(%s) returns %d", (const char*) fontFile, error); } mgDebug("load font %s - %s : %d faces, %d glyphs.", face->family_name, face->style_name, face->num_faces, face->num_glyphs); error = FT_Set_Char_Size(face, 0, (FT_F26Dot6) (size*64), dpi, dpi); if (error != 0) mgDebug("FT_Set_Char_Size = %d", error); fontHeight = face->size->metrics.height/64.0; fontAscent = face->size->metrics.ascender/64.0; double advanceX, advanceY, posnX, posnY; int imageWidth, imageHeight; BYTE* imageData; mgFTGetChar(face, 'n', advanceX, advanceY, posnX, posnY, imageWidth, imageHeight, imageData); charWidth = advanceX; return face; }
//-------------------------------------------------------------- // constructor MinecraftRegion::MinecraftRegion( const char* regionDir, int regionX, int regionZ) { memset(m_header, 0, sizeof(m_header)); m_lock = mgOSLock::create(); // create the region file name m_fileName.format("%s/r.%d.%d.mcr", (const char*) regionDir, regionX, regionZ); mgOSFixFileName(m_fileName); // open the file m_regionFile = mgOSFileOpen(m_fileName, "rb"); if (m_regionFile == NULL) { mgDebug("could not open region file %s", (const char*) m_fileName); m_exists = false; return; } else m_exists = true; // read the header int count = fread(m_header, 1, sizeof(m_header), m_regionFile); if (count != sizeof(m_header)) { mgDebug("Could not read region (%d, %d) header -- %d bytes read, %d expected", regionX, regionZ, count, sizeof(m_header)); m_exists = false; } }
//-------------------------------------------------------------- // return preferred size void mgFormPane::preferredSize( mgDimension& size) { #ifdef TRACE_TABLES mgDebug("FormPane preferredSize..."); #endif // tell the formatter to use giant page width. Result should be min of // requested width and required width. mgTextFormat format(m_text, (mgTextPage*) this, true, 0, 0, 10000); unsigned int posn = 0; format.scan(posn); size.m_width = format.m_boxWidth; size.m_height = format.m_boxHeight; if (m_frame != NULL) { mgDimension exterior; m_frame->getOutsideSize(size, exterior); size = exterior; } #ifdef TRACE_TABLES mgDebug("FormPane preferredSize is (%d by %d)", size.m_width, size.m_height); #endif }
//-------------------------------------------------------------- // parse the file void BVHFile::parseFile( const char* fileName) { FILE* bvhFile = fopen(fileName, "rt"); if (bvhFile == NULL) throw new mgException("cannot open %s", (const char*) fileName); m_state = STATE_START; m_linenum = 1; char buffer[4096]; while (true) { size_t readLen = fread(buffer, 1, sizeof(buffer), bvhFile); if (readLen == 0) break; parseBuffer(buffer, (int) readLen); } if (!m_token.isEmpty()) processToken(m_token); fclose(bvhFile); if (m_root != NULL) mgDebug("read %d nodes", m_root->nodeCount()); mgDebug("frameCount: %d, frameTime: %g, totalChannels: %d", m_frameCount, m_frameTime, m_totalChannels); if (m_state != STATE_DONE) mgDebug("did not read all samples. count = %d, expected %d", m_count, m_totalChannels*m_frameCount); }
//-------------------------------------------------------------- // compute size at width. return false if not implemented BOOL mgFormPane::preferredSizeAtWidth( int width, mgDimension& size) { #ifdef TRACE_TABLES mgDebug("FormPane preferredSizeAtWidth(%d)...", width); #endif // subtract frame from requested width if (m_frame != NULL) { mgRectangle rect(0, 0, width, width); m_frame->getInsideRect(rect); width = rect.m_width; } // format at requested width mgTextFormat format(m_text, (mgTextPage*) this, true, 0, 0, width); unsigned int posn = 0; format.scan(posn); size.m_width = format.m_boxWidth; size.m_height = format.m_boxHeight; if (m_frame != NULL) { mgDimension exterior; m_frame->getOutsideSize(size, exterior); size = exterior; } #ifdef TRACE_TABLES mgDebug("FormPane preferredSizeAtWidth(%d) is (%d by %d)", width, size.m_width, size.m_height); #endif return true; }
//-------------------------------------------------------------- // terminate framework void termFramework(void) { // shutdown mgOSXServices* platform = (mgOSXServices*) mgPlatform; mgDebug("------ shutdown"); platform->logTiming(true); double sessionEnd = mgOSGetTime(); mgDebug(":Session time: %.2f seconds", (sessionEnd - platform->m_sessionStart)/1000.0); mgDebug(":Session exit: clean"); /* // too much of the window has already been destroyed by Cocoa. skip this // shutdown platform->termView(); // delete buffers platform->m_theApp->appDeleteBuffers(); platform->m_theApp->appTerm(); delete platform->m_theApp; platform->m_theApp = NULL; platform->termDisplay(); */ mgBlockPool::freeMemory(); }
//-------------------------------------------------------------- // compile OpenGL21 shader GLuint mgWinGL21Support::compileShader( const char* source, GLenum shaderType) { // Create shader objects GLuint shader = glCreateShader(shaderType); const GLchar* strings[1]; strings[0] = (GLchar *) source; glShaderSource(shader, 1, strings, NULL); glCompileShader(shader); mgDebug("%s shader log:", (shaderType == GL_VERTEX_SHADER) ? "vertex" : "fragment"); printShaderLog(shader); // Check for errors GLint testVal; glGetShaderiv(shader, GL_COMPILE_STATUS, &testVal); if (testVal == GL_FALSE) { mgDebug("%s shader compilation failed.", (shaderType == GL_VERTEX_SHADER) ? "vertex" : "fragment"); return 0; } return shader; }
// pass window resize to platform void mgViewResized( int width, int height) { mgScriptPlatform* platform = (mgScriptPlatform*) mgPlatform; try { platform->windowResized(width, height); } catch (mgErrorMsg* e) { mgString msg; platform->m_errorTable->msgText(msg, e); mgDebug("Exception: %s", (const char*) msg); } catch (mgException* e) { mgDebug("Exception: %s", (const char*) e->m_message); } catch (...) { mgDebug("Exception \"...\""); } }
//-------------------------------------------------------------- // compile OpenGL33 shader GLuint mgLinuxGL33Support::compileShader( const char* source, GLenum shaderType) { // Create shader objects GLuint shader = glCreateShader(shaderType); const GLchar* strings[1]; strings[0] = (GLchar *) source; glShaderSource(shader, 1, strings, NULL); const char* typeStr = (shaderType == GL_VERTEX_SHADER) ? "vertex" : "fragment"; glCompileShader(shader); mgString log; getShaderLog(shader, log); log.trim(); if (log.isEmpty()) mgDebug("%s shader compiled.", typeStr); else mgDebug("%s shader log:\n%s", typeStr, (const char*) log); // Check for errors GLint testVal; glGetShaderiv(shader, GL_COMPILE_STATUS, &testVal); if (testVal == GL_FALSE) { mgDebug("%s shader compilation failed.", typeStr); return 0; } return shader; }
//-------------------------------------------------------------- // constructor SolarSystem::SolarSystem( const mgOptionsFile& options) { m_planetDayLen = options.getDouble("planetDayLen", 600.0); // seconds if (m_planetDayLen == 0.0) m_planetDayLen = 1e10; // infinity m_moonDayLen = options.getDouble("moonDayLen", 300.0); // seconds if (m_moonDayLen == 0.0) m_moonDayLen = 1e10; // infinity m_ringDayLen = options.getDouble("ringDayLen", 200.0); // seconds if (m_ringDayLen == 0.0) m_ringDayLen = 1e10; // infinity m_moonMonthLen = options.getDouble("moonMonthLen", 1000.0); // seconds if (m_moonMonthLen == 0.0) m_moonMonthLen = 1e10; // infinity m_beltMonthLen = options.getDouble("beltMonthLen", 1000.0); // seconds if (m_beltMonthLen == 0.0) m_beltMonthLen = 1e10; // infinity m_planet = new Planet(options, PLANET_RADIUS); // m_belt = new Belt(options, BELT_RADIUS); m_moon = new Moon(options, MOON_RADIUS); m_ring = new Ring(options, RING_RADIUS, RING_WALL_HEIGHT, RING_WALL_WIDTH); m_planetDay = 90.0; m_moonDay = 0.0; m_ringDay = 0.0; m_moonMonth = 30.0; m_beltMonth = 0.0; m_coordSystem = COORDS_PLANET; m_coordPosn = mgPoint3(0.0, 2.0, 0.0); m_eyeRotX = 0.0; m_eyeRotY = 0.0; m_eyeRotZ = 0.0; mgDebug("Planet radius = %g km (%g miles)", PLANET_RADIUS/1000.0, PLANET_RADIUS/1600.0); double val = 4*PI*PLANET_RADIUS*PLANET_RADIUS; mgDebug("Surface area of planet = %g million sq km (%g million sq mi)", val/1e12, (val/1e12)/1.609); mgDebug("Moon radius = %g km (%g miles)", MOON_RADIUS/1000.0, MOON_RADIUS/1600.0); val = 4*PI*MOON_RADIUS*MOON_RADIUS; mgDebug("Surface area of moon = %g million sq km (%g million sq mi)", val/1e12, (val/1e12)/1.609); mgDebug("Moon distance = %g km (%g miles)", MOON_DISTANCE/1000.0, MOON_DISTANCE/1600.0); mgDebug("Ring radius = %g km (%g miles)", RING_RADIUS/1000.0, RING_RADIUS/1600.0); val = 2*PI*RING_RADIUS*RING_WIDTH; mgDebug("Surface area of ring = %g million sq km (%g million sq mi)", val/1e12, (val/1e12)/1.609); mgDebug("Ring width = %g m (%g ft)", RING_WIDTH, RING_WIDTH*3.16); mgDebug("Ring wall height = %g m (%g ft)", RING_WALL_HEIGHT, RING_WALL_HEIGHT*3.16); mgDebug("Ring wall width = %g m (%g ft)", RING_WALL_WIDTH, RING_WALL_WIDTH*3.16); }
//-------------------------------------------------------------- // find current display mode in the list void mgWinServices::findCurrentDisplayMode() { mgDebug("------ initialize display mode"); // find the adapter to use findAdapter(); // Save The Current Display State memset(&m_dmInit, 0, sizeof(m_dmInit)); m_dmInit.dmSize = sizeof(DEVMODE); WCHAR* wideMonitor; int textLen; m_monitorDevice.toWCHAR(wideMonitor, textLen); EnumDisplaySettings(wideMonitor, ENUM_CURRENT_SETTINGS, &m_dmInit); // set fullscreen display mode to current state memset(&m_dmFull, 0, sizeof(m_dmFull)); m_dmFull.dmSize = sizeof(DEVMODE); EnumDisplaySettings(wideMonitor, ENUM_CURRENT_SETTINGS, &m_dmFull); mgDebug("current display mode: %d by %d by %d, %d hz, flags=%x", m_dmFull.dmPelsWidth, m_dmFull.dmPelsHeight, m_dmFull.dmBitsPerPel, m_dmFull.dmDisplayFrequency, m_dmFull.dmDisplayFlags); // don't set all fields when we ChangeDisplayMode m_dmInit.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; m_dmFull.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; // find the current display mode in the list DEVMODE dm; memset(&dm, 0, sizeof(dm)); dm.dmSize = sizeof(DEVMODE); BOOL found = false; for (int i = 0; ; i++) { if (!EnumDisplaySettings(wideMonitor, i, &dm)) break; if (dm.dmBitsPerPel == m_dmFull.dmBitsPerPel && dm.dmPelsWidth == m_dmFull.dmPelsWidth && dm.dmPelsHeight == m_dmFull.dmPelsHeight) { found = true; break; } } // fail if we can't find display mode! if (!found) { throw new mgErrorMsg("winDisplayMode", "width,height,depth,freq,flags", "%d,%d,%d,%d,%d", m_dmFull.dmPelsWidth, m_dmFull.dmPelsHeight, m_dmFull.dmBitsPerPel, m_dmFull.dmDisplayFrequency, m_dmFull.dmDisplayFlags); } delete wideMonitor; }
//-------------------------------------------------------------- // move current working directory up tree until file is found void mgOSFindWD( const char* fileName) { char* oldCWD = getcwd(NULL, 0); if (oldCWD == NULL) throw new mgException("unable to get getcwd"); mgDebug("CWD is %s", oldCWD); BOOL changed = false; mgString cwd(oldCWD); while (true) { mgString name; if (cwd.endsWith("/")) name.format("%s%s", (const char*) cwd, fileName); else name.format("%s/%s", (const char*) cwd, fileName); struct stat filestat; if (0 == stat(name, &filestat)) { mgDebug("found %s", (const char*) name); break; } else { // remove last directory from cwd int slash = cwd.reverseFind(cwd.length(), '/'); if (slash != -1) { cwd.deleteAt(slash, cwd.length()-slash); changed = true; } else { // no more directories. file not found. throw new mgException("mgOSFindWD cannot find %s", fileName); } } } // set the new working directory if (changed) { // move errors.txt to new location mgString oldErrors, newErrors; oldErrors.format("%s/errors.txt", (const char*) oldCWD); newErrors.format("%s/errors.txt", (const char*) cwd); rename(oldErrors, newErrors); if (0 != chdir(cwd)) throw new mgException("unable to chdir(%s)", (const char*) cwd); } free(oldCWD); }
//-------------------------------------------------------------- // constructor mgGenFont::mgGenFont( mgGenSurface* surface, const char* faceName, int size, BOOL bold, BOOL italic) { m_surface = surface; int pixelSize = m_surface->points(size); m_faceName = faceName; m_size = size; m_bold = bold; m_italic = italic; mgString fontFile; if (!m_surface->findFont(m_faceName, m_bold, m_italic, fontFile)) throw new mgException("cannot find font %s%s%s or default.", (const char*) m_faceName, m_bold?"-b":"", m_italic?"-i":""); // =-= on errors, try default font face FT_Face face; int error = FT_New_Face((FT_Library) m_surface->m_ftLibrary, fontFile, 0, &face); if (error == FT_Err_Unknown_File_Format) { throw new mgException("unknown file format %s", (const char*) fontFile); } else if (error != 0) { throw new mgException("FT_New_Face(%s) returns %d", (const char*) fontFile, error); } mgDebug("font family name='%s', style name='%s'", face->family_name, face->style_name); mgDebug("%d faces, %d glyphs.", face->num_faces, face->num_glyphs); int dpi = surface->displayDPI(); error = FT_Set_Char_Size(face, 0, m_size*64, dpi, dpi); if (error != 0) mgDebug("FT_Set_Char_Size = %d", error); m_ftFace = face; m_height = face->size->metrics.height/64; m_ascent = face->size->metrics.ascender/64; const mgGenCharDefn* defn = m_surface->m_charCache->getChar(face, 'n'); if (defn != NULL) m_charWidth = defn->m_advanceX; else mgDebug("No 'n' width in font"); }
//-------------------------------------------------------------------------- // load and compile a shader // =-= source code modified from a version in the OpenGL SuperBible BOOL GL21compileShaderPair( const char* shaderDir, GLuint hVertexShader, const char* vertexFileName, GLuint hFragmentShader, const char* fragmentFileName) { GLint testVal; // Load them. If fail clean up and return null mgString fileName; fileName.format("%s%s", (const char*) shaderDir, (const char*) vertexFileName); mgOSFixFileName(fileName); if (!GL21loadShaderFile(fileName, hVertexShader)) { mgDebug("shader %s not found", (const char*) fileName); return false; } mgString log; // Compile vertex shader glCompileShader(hVertexShader); GL21getShaderLog(hVertexShader, log); log.trim(); if (log.isEmpty()) mgDebug("shader %s compiled", (const char*) fileName); else mgDebug("shader %s log:\n%s", (const char*) fileName, (const char*) log); // Check for errors glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &testVal); if (testVal == GL_FALSE) { mgDebug("shader %s compilation failed.", (const char*) fileName); return false; } fileName.format("%s%s", (const char*) shaderDir, (const char*) fragmentFileName); mgOSFixFileName(fileName); if (!GL21loadShaderFile(fileName, hFragmentShader)) { mgDebug("shader %s not found", (const char*) fileName); return false; } glCompileShader(hFragmentShader); GL21getShaderLog(hFragmentShader, log); log.trim(); if (log.isEmpty()) mgDebug("shader %s compiled", (const char*) fileName); else mgDebug("shader %s log:\n%s", (const char*) fileName, (const char*) log); glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &testVal); if (testVal == GL_FALSE) { mgDebug("shader %s compilation failed.", (const char*) fileName); return false; } return true; }
//-------------------------------------------------------------- // compile OpenGL21 shader pair. DWORD mgWinGL21Support::compileShaderPair( const char* vertexSource, const char* fragmentSource, int attribCount, const char** names, const DWORD* indexes) { GLuint vertexShader = compileShader(vertexSource, GL_VERTEX_SHADER); GLuint fragmentShader = compileShader(fragmentSource, GL_FRAGMENT_SHADER); if (vertexShader == 0 || fragmentShader == 0) return 0; // create the shader program GLuint shader = glCreateProgram(); glAttachShader(shader, vertexShader); glAttachShader(shader, fragmentShader); // bind attributes for (int i = 0; i < attribCount; i++) { glBindAttribLocation(shader, indexes[i], names[i]); } glLinkProgram(shader); // These are no longer needed glDeleteShader(vertexShader); glDeleteShader(fragmentShader); // Make sure link worked too GLint testVal; glGetProgramiv(shader, GL_LINK_STATUS, &testVal); if (testVal == GL_FALSE) { // get the linker log GLsizei msgSize, msgLen; glGetProgramiv(shader, GL_INFO_LOG_LENGTH, &msgSize); GLchar* message = new char[msgSize]; glGetProgramInfoLog(shader, msgSize, &msgLen, message); mgDebug("%s", (const char*) message); delete message; glDeleteProgram(shader); shader = 0; mgDebug("shader link failed."); } return shader; }
//-------------------------------------------------------------- // get location of chunk in region file. return false if not present BOOL MinecraftRegion::getChunkLoc( int chunkX, int chunkZ, int& chunkPosn, int& chunkLen, int& compressCode) { // if this region does not exist, none of the chunks do if (!m_exists) return false; int headerPosn = 4 * ((chunkX%32) + (chunkZ%32) * 32); int loc = m_header[headerPosn++]; loc = (loc << 8) | m_header[headerPosn++]; loc = (loc << 8) | m_header[headerPosn++]; int len = m_header[headerPosn]; // if no chunk at this position if (loc == 0 || len == 0) return false; // locations are in 4K sectors chunkPosn = loc*4096; BYTE chunkHeader[5]; m_lock->lock(); FILE* regionFile = getFile(); if (0 == fseek(m_regionFile, chunkPosn, SEEK_SET)) { if (5 != fread(chunkHeader, 1, 5, regionFile)) { mgDebug("could not read chunk data"); memset(chunkHeader, 0, sizeof(chunkHeader)); } } else mgDebug("could not seek to %d", chunkPosn); m_lock->unlock(); // get length and format of compressed chunk data chunkLen = (chunkHeader[0] << 24) | (chunkHeader[1] << 16) | (chunkHeader[2] << 8) | chunkHeader[3]; compressCode = chunkHeader[4]; chunkPosn += 5; // start of data chunkLen -= 1; // length after compress code return true; }
//-------------------------------------------------------------- // get a character in the font void mgFTGetChar( void* ftFace, int letter, double &advanceX, // from start to end point double &advanceY, double &posnX, // from start to top-left of image double &posnY, int &imageWidth, int &imageHeight, BYTE*& imageData) { FT_Face face = (FT_Face) ftFace; advanceX = advanceY = posnX = posnY = 0.0; imageWidth = imageHeight = 0; imageData = NULL; FT_UInt glyphIndex = FT_Get_Char_Index(face, letter); int error = FT_Load_Glyph(face, glyphIndex, FT_LOAD_RENDER ); if (error != 0) { mgDebug("FT_Load_Glyph returns %d", error); return; } FT_GlyphSlot slot = face->glyph; FT_Bitmap bitmap = slot->bitmap; advanceX = slot->advance.x/64.0; advanceY = slot->advance.y/64.0; posnX = slot->bitmap_left; posnY = slot->bitmap_top; imageWidth = bitmap.width; imageHeight = bitmap.rows; // round width up to next multiple of 4 for OpenGL glTexSubImage alignment int outWidth = 4*((bitmap.width+3)/4); // enlarge character buffer if required size_t size = (size_t) (outWidth * bitmap.rows); if (size > mgFTCharImageSize) { delete mgFTCharImage; mgFTCharImageSize = size; mgFTCharImage = new BYTE[mgFTCharImageSize]; } // copy data from FreeType bitmap imageData = mgFTCharImage; memset(imageData, 0, bitmap.rows*outWidth); for (int i = 0; i < bitmap.rows; i++) { BYTE* outLine = imageData + outWidth * i; BYTE* bitmapLine = bitmap.buffer + bitmap.pitch * i; memcpy(outLine, bitmapLine, bitmap.width); } }
//-------------------------------------------------------------- // initialize for scene rendering void mgDX9Display::initView() { mgWinSystem* framework = (mgWinSystem*) mgPlatform; mgDebug("initView"); // =-= turn off culling // mg_d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); mg_d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); // mg_d3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS, true); mg_d3dDevice->SetRenderState(D3DRS_ZENABLE, true); mg_d3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); mg_d3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); mg_d3dDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); mg_d3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); mg_d3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); mg_d3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); mg_d3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); mg_d3dDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); mg_d3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); mg_d3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); mg_d3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_DIFFUSE); mg_d3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); mg_d3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); mg_d3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC); mg_d3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); mg_d3dDevice->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 2); // m_state->m_deviceCaps.MaxAnisotropy); mg_d3dDevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); mg_d3dDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC); mg_d3dDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); mg_d3dDevice->SetSamplerState(1, D3DSAMP_MAXANISOTROPY, 2); // m_state->m_deviceCaps.MaxAnisotropy); mgDebug("view size is %d by %d", m_graphicsWidth, m_graphicsHeight); setProjection(m_graphicsWidth, m_graphicsHeight); if (m_theApp != NULL) m_theApp->viewResized(m_graphicsWidth, m_graphicsHeight); }
//-------------------------------------------------------------- // get preferred size at width void mgFormPane::childSizeAtWidth( const void* child, int width, mgDimension& size) { mgControl* cntl = (mgControl*) child; #ifdef TRACE_TABLES mgDebug("formatter childSizeAtWidth %d...", width); #endif // get preferred size of control if (!cntl->preferredSizeAtWidth(width, size)) cntl->preferredSize(size); #ifdef TRACE_TABLES mgDebug("formatter childSizeAtWidth(%d) is %d by %d", width, size.m_width, size.m_height); #endif }
//-------------------------------------------------------------------------- // print shader log error messages on mgDebug void mgWinGL21Support::printShaderLog( GLuint shader) { GLint logLen, retLen; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLen); char* logText = new char[logLen]; glGetShaderInfoLog(shader, logLen, &retLen, logText); mgDebug("%s", (const char*) logText); delete logText; }
//-------------------------------------------------------------- // launch the mgSendLog application void mgOSLaunchSendLog() { // fork and let the child run the app pid_t app = fork(); if (app == 0 || app == -1) return; // wait for app to end int status; pid_t child = waitpid(app, &status, 0); // send return code to sendLog char statusStr[10]; if (WIFEXITED(status)) sprintf(statusStr, "%d", WEXITSTATUS(status)); else sprintf(statusStr, "-666"); try { mgOSFindWD("errors.txt"); } catch (...) { mgDebug("could not find errors.txt"); // something is seriously wrong! _exit(0); } mgString location; if (!mgOSFindFile(location, "mgSendLog")) { mgDebug("could not find mgSendLog"); _exit(0); } if (execl(location, location, statusStr, NULL) == -1) { mgDebug("exec(mgSendLog) failed, rc = %d", errno); _exit(0); } }
//-------------------------------------------------------------- // read the font list void readFontList() { char winDir[MAX_PATH]; GetWindowsDirectory(winDir, sizeof(winDir)); mgString fontPath; fontPath.format("%s\\Fonts\\", winDir); mgDebug("windows font dir is %s", (const char*) fontPath); m_fontDirs.add(fontPath); m_fontList = new mgFontList("docs\\fonts.xml"); }
//-------------------------------------------------------------- // paint content of control void mgFormPane::paint( mgContext* gc) { mgDimension size; getSize(size); mgRectangle interior(0, 0, size.m_width, size.m_height); if (m_frame != NULL) { m_frame->paintBackground(gc, 0, 0, size.m_width, size.m_height); m_frame->getInsideRect(interior); } m_drawGC = gc; //#define SHOWBACK #ifdef SHOWBACK // =-= debug gc->setBrush(getSurface()->createBrush(mgColor(1.0-m_defaultTextColor.m_r, 1.0-m_defaultTextColor.m_g, 1.0-m_defaultTextColor.m_b))); gc->fillRect(1, 1, size.m_width-2, size.m_height-2); #endif //#define SHOWEDGE #ifdef SHOWEDGE // =-= debug gc->setPen(getSurface()->createPen(mgColor("green"), 1)); gc->drawRect(1, 1, size.m_width-2, size.m_height-2); #endif gc->setAlphaMode(MG_ALPHA_MERGE); #ifdef TRACE_TABLES mgDebug("FormPane interior = (%d, %d) (%d by %d)", interior.m_x, interior.m_y, interior.m_width, interior.m_height); #endif mgTextDraw draw(m_text, this, interior, interior.m_x, interior.m_y, interior.m_width); unsigned int posn = 0; draw.scan(posn); //#define SHOWPAGE #ifdef SHOWPAGE gc->setPen(getSurface()->createPen(mgColor("red"), 1)); gc->drawLine(5, draw.m_boxHeight-3, size.m_width-3, draw.m_boxHeight-3); gc->drawLine(draw.m_boxWidth-3, 5, draw.m_boxWidth-3, size.m_height-3); #endif m_drawGC = NULL; if (m_frame != NULL) { m_frame->paintForeground(gc, 0, 0, size.m_width, size.m_height); } }
//-------------------------------------------------------------- // get width range of child void mgFormPane::childWidthRange( const void* child, int& minWidth, int& maxWidth) { mgControl* cntl = (mgControl*) child; #ifdef TRACE_TABLES mgDebug("formatter childWidthRange..."); #endif // get size range of control mgDimension minSize, maxSize; cntl->minimumSize(minSize); cntl->preferredSize(maxSize); minWidth = minSize.m_width; maxWidth = maxSize.m_width; #ifdef TRACE_TABLES mgDebug("formatter childWidthRange is %d to %d", minWidth, maxWidth); #endif }
//-------------------------------------------------------------- // attribute set void mgOptionsTag::tagAttr( mgXMLParser* parser, const char* attrName, const char* attrValue) { mgOptionsFile* options = (mgOptionsFile*) parser; mgDebug(" %s: %s", (const char*) attrName, (const char*) attrValue); mgString key(attrName); key.makeLower(); options->m_options.setAt(key, attrValue); }
//-------------------------------------------------------------- // reset the display void mgDX9Display::displayReset() { mgDebug("reset display"); // reset the D3D Device, losing all graphics state deleteBuffers(); // set current size of window m_state->m_presentParms.BackBufferWidth = m_graphicsWidth; m_state->m_presentParms.BackBufferHeight = m_graphicsHeight; HRESULT hr = mg_d3dDevice->Reset(&m_state->m_presentParms); if (hr == S_OK) createBuffers(); }