//constructor MGuiWindow::MGuiWindow(const MVector2 & position, const MVector2 & scale, const MVector4 & color, void (* pointerEvent)(MGuiWindow * window, MGuiEvent * guiEvent)): m_breakEvents(false), m_margin(10, 10), m_isScrolled(false), m_scroll(0, 0), m_minScroll(0, 0), m_maxScroll(0, 0), m_hScrollSlide(MVector2(0, scale.y-6), MVector2(50, 6), MVector4(1, 1, 1, 0.3f), NULL), m_vScrollSlide(MVector2(scale.x-6, 0), MVector2(6, 50), MVector4(1, 1, 1, 0.3f), NULL) { m_hScrollSlide.setParentWindow(this); m_vScrollSlide.setParentWindow(this); setParentWindow(NULL); setPosition(position); setScale(scale); setNormalColor(color); setPointerEvent(pointerEvent); // horizontal slide m_hScrollSlide.setScrollAffect(false); m_hScrollSlide.setMinValue(0); m_hScrollSlide.setMaxValue(1); // vertical slide m_vScrollSlide.setScrollAffect(false); m_vScrollSlide.setMinValue(0); m_vScrollSlide.setMaxValue(1); resizeScroll(); }
void drawLogo(void) { MWindow * window = MWindow::getInstance(); MGui2d quad; quad.setPosition(MVector2((window->getWidth()-512)*0.5f, (window->getHeight()-512)*0.5f)); quad.setScale(MVector2(512, 512)); quad.drawTexturedQuad(logoTextureId); }
void MGui2d::drawTexturedQuad(unsigned int textureId) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); MVector2 g_vertices[8]; MVector2 g_texCoords[8]; render->disableNormalArray(); render->disableColorArray(); render->enableVertexArray(); render->enableTexCoordArray(); g_vertices[0] = MVector2(m_position.x, m_position.y); g_vertices[1] = MVector2(m_position.x, m_position.y + m_scale.y); g_vertices[3] = MVector2(m_position.x + m_scale.x, m_position.y + m_scale.y); g_vertices[2] = MVector2(m_position.x + m_scale.x, m_position.y); g_texCoords[0] = MVector2(0, 0); g_texCoords[1] = MVector2(0, 1); g_texCoords[3] = MVector2(1, 1); g_texCoords[2] = MVector2(1, 0); render->setTexCoordPointer(M_FLOAT, 2, g_texCoords); render->setVertexPointer(M_FLOAT, 2, g_vertices); render->bindTexture(textureId); render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); }
void MInput::flush(void) { // keys map<string, int>::iterator mit (m_keys.begin()), mend(m_keys.end()); for(; mit!=mend; mit++) { if(mit->second == 1) mit->second = 2; else if(mit->second == 3) mit->second = 0; } // axis unsigned int a, aSize = m_axisToFlush.size(); for(a=0; a<aSize; a++) (*m_axisToFlush[a]) = 0; // touches map<int, TouchData>::iterator t_it(m_touches.begin()), t_end(m_touches.end()); for(; t_it!=t_end; t_it++) { TouchData* data = &(t_it->second); data->phase = M_TOUCH_NONE; data->touchPoint = MVector2(0.0f); } }
void MGuiEditText::autoScaleFromText(void) { MGui2d::autoScaleFromText(); if(getScale().x == 0) setScale(MVector2(getTextSize() * 10.0f, getTextSize())); }
bool isLineCircleIntersection(const MVector2 & origin, const MVector2 & dest, const MVector2 & circleCenter, float circleRadius) { float rr = circleRadius*circleRadius; if((origin - circleCenter).getSquaredLength() < rr) return true; if((dest - circleCenter).getSquaredLength() < rr) return true; MVector2 vec = dest - origin; MVector2 N = MVector2(-vec.y, vec.x).getNormalized(); float d = N.dotProduct(circleCenter - origin); if(fabs(d) >= circleRadius) return false; MVector2 I = circleCenter - (N * d); if(fabs(vec.x) > fabs(vec.y)) { if(((I.x > origin.x) && (I.x < dest.x)) || ((I.x < origin.x) && (I.x > dest.x))) return true; return false; } if(((I.y > origin.y) && (I.y < dest.y)) || ((I.y < origin.y) && (I.y > dest.y))) return true; return false; }
void MGuiTextureFont::draw(const char * text, const MVector2 & position, float size) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); MVector2 g_vertices[4]; MVector2 g_texCoords[4]; float xc=position.x, yc=position.y, u=0, v=0; render->disableNormalArray(); render->disableColorArray(); render->enableVertexArray(); render->enableTexCoordArray(); render->setVertexPointer(M_FLOAT, 2, g_vertices); render->setTexCoordPointer(M_FLOAT, 2, g_texCoords); render->bindTexture(m_texture); unsigned int i; unsigned int textLength = strlen(text); for(i=0; i<textLength; i++) { if(text[i] == '\n') // return { yc += size; xc = position.x; } else if(text[i] == ' ') // tab { xc += size * getTabSpace(); } else { u=float((unsigned char)text[i]%16)/16.0f; //u position of character v=float((unsigned char)text[i]/16)/16.0f; //v position of character g_texCoords[0] = MVector2(u, v+0.0625f); g_vertices[0] = MVector2(xc, yc+size); g_texCoords[1] = MVector2(u+0.0625f, v+0.0625f); g_vertices[1] = MVector2(xc+size, yc+size); g_texCoords[3] = MVector2(u+0.0625f, v+0.001f); g_vertices[3] = MVector2(xc+size, yc); g_texCoords[2] = MVector2(u, v+0.001f); g_vertices[2] = MVector2(xc, yc); render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); xc += size * getSpace(); //move to next character } } }
void beginDraw(M_PRIMITIVE_TYPES primitiveType) { g_verticesNumber = 0; g_primitiveType = primitiveType; renderColors = false; renderTexcoords = false; previousColor = MVector4(1, 1, 1, 1); previousTexcoords = MVector2(0, 0); }
void MGuiWindow::rescaleScrollingBar(void) { MVector2 scale = getScale(); m_hScrollSlide.setPosition(MVector2(0, scale.y - m_hScrollSlide.getButtonScale().y)); m_vScrollSlide.setPosition(MVector2(scale.x - m_vScrollSlide.getButtonScale().x, 0)); float length = (scale.x / (m_maxScroll.x - m_minScroll.x)) * scale.x; if(length < scale.x) { m_hScrollSlide.setButtonScale(MVector2(length, m_hScrollSlide.getButtonScale().y)); m_hScrollSlide.setDirection(MVector2(scale.x - length - m_vScrollSlide.getButtonScale().x, 0)); if(isScrollBarPressed()) { float value = m_hScrollSlide.getValue(); m_scroll.x = -(m_minScroll.x + (m_maxScroll.x - m_minScroll.x - scale.x)*value); } } float height = (scale.y / (m_maxScroll.y - m_minScroll.y)) * scale.y; if(height < scale.y) { m_vScrollSlide.setButtonScale(MVector2(m_vScrollSlide.getButtonScale().x, height)); m_vScrollSlide.setDirection(MVector2(0, scale.y - height)); if(isScrollBarPressed()) { float value = m_vScrollSlide.getValue(); m_scroll.y = -(m_minScroll.y + (m_maxScroll.y - m_minScroll.y - scale.y)*value); } } }
MVector2 MInput::getLastTouchPosition(int touchID) { map<int, TouchData>::iterator iter = m_touches.find(touchID); if(iter != m_touches.end()) { TouchData* data = &(iter->second); if (data->phase != M_TOUCH_NONE) { return data->lastTouchPoint; } } return MVector2(0.0f); }
void MGuiEditText::upCharId(int direction) { MVector2 pos = getFont()->getCharacterPosition(getText(), getPosition(), getTextSize(), getCharId()); pos.x += 0.1f; pos.y += 0.1f; pos += MVector2(0, getTextSize() * direction); if(pos.y < getPosition().y) return; if(pos.y > (getPosition().y + getScale().y)) return; unsigned int id = getFont()->findPointedCharacter(getText(), getPosition(), getTextSize(), pos); setCharId(id); }
// constructor MGuiSlide::MGuiSlide(MVector2 position, MVector2 scale, MVector4 color, void (* pointerEvent)(MGuiSlide * slide, MGuiEvent * guiEvent)): m_value(0), m_minValue(0), m_maxValue(1) { m_button.setPosition(position); m_button.setScale(scale); setDirection(MVector2(10, 0)); setParentWindow(NULL); setPosition(position); setScale(getDirection() + scale); setNormalColor(color); setHighLightColor(color); setPressedColor(color); setPointerEvent(pointerEvent); }
void MGuiFileBrowser::resize(const MVector2 & position, const MVector2 & scale) { m_headWin->setPosition(position); m_headWin->setScale(MVector2(scale.x, m_fileButtonsHeight*2 + m_margin*3)); m_dirWin->setPosition(position + MVector2(m_margin)); m_dirWin->setScale(MVector2(scale.x - m_fileButtonsWidth - m_margin*3, m_fileButtonsHeight)); m_fileWin->setPosition(position + MVector2(m_margin) + MVector2(0, m_fileButtonsHeight + m_margin)); m_fileWin->setScale(MVector2(scale.x - m_fileButtonsWidth - m_margin*3, m_fileButtonsHeight)); m_mainWin->setPosition(position + MVector2(0, m_headWin->getScale().y)); m_mainWin->setScale(MVector2(scale.x, scale.y - m_headWin->getScale().y)); m_okButton->setXPosition(m_dirWin->getScale().x + m_margin*2); m_cancelButton->setXPosition(m_dirWin->getScale().x + m_margin*2); if(m_mainWin->isVisible()) updateMainWin(); }
void MGameBoard::Init( void ) { m_BgSprite = ISpritePtr(new MSprite("Sprites/SpaceBG.png",1024,576,0.0f)); /*m_pMonkey = ISpritePtr(new MSprite("Sprites/gogorisset1.png",273,9,37,42,255,0,255,1.0f)); m_pHealthBar = ISpritePtr(new MSprite("Manifests/HealthBar.xml")); m_pShieldBar = ISpritePtr(new MSprite("Manifests/ShieldBar.xml")); m_PlayerShip = IEntityPtr(new MShip()); m_pMonkey->SetPosition(15,10); m_pShieldBar->SetPosition(60,20); m_pHealthBar->SetPosition(60,35);*/ Engine::GetInstance()->Renderer()->RegisterDrawable(m_BgSprite); for( int i = 0; i < 15; ++i ) { for( int j = 0; j < 67; ++j ) { //shared_ptr<MTempEntity> TempEnt(new MTempEntity(MVector2(10.0f + (j * 15),10.0f + (i * 15)),MVector2(rand() % 300 + 100,rand() % 300 + 100))); shared_ptr<MTempEntity> TempEnt(new MTempEntity(MVector2(10.0f + (j * 15),10.0f + (i * 15)),MVector2(50.0f,50.0f))); Engine::GetInstance()->EntityManager()->RegisterEntity(TempEnt); } } /*Engine::GetInstance()->Renderer()->RegisterDrawable(m_pMonkey); Engine::GetInstance()->Renderer()->RegisterDrawable(m_pHealthBar); Engine::GetInstance()->Renderer()->RegisterDrawable(m_pShieldBar); Engine::GetInstance()->EntityManager()->RegisterEntity(m_PlayerShip); Engine::GetInstance()->InputManager()->RegisterListener(dynamic_pointer_cast<IInputListener>(m_PlayerShip)); m_fSpeedTier1 = Engine::GetInstance()->VarManager()->CreateVar("f_speedtier1",75.0f); m_fSpeedTier2 = Engine::GetInstance()->VarManager()->CreateVar("f_speedtier2",100.0f); m_fSpeedTier3 = Engine::GetInstance()->VarManager()->CreateVar("f_speedtier3",150.0f); m_fSpeedTier4 = Engine::GetInstance()->VarManager()->CreateVar("f_speedtier4",300.0f); for( int i = 0; i < INVADERS_NUM_ROWS; ++i ) { for( int j = 0; j < INVADERS_NUM_COLS; ++j ) { m_pEnemies[i][j] = IEntityPtr(new MBaseEnemy(MVector2(20.0f + (j * 50),80.0f + (i * 30)),this,j,i)); Engine::GetInstance()->EntityManager()->RegisterEntity(m_pEnemies[i][j]); } }*/ }
MImage* Atlas::AddImage(MImage* image, const char* name) { if(m_Images.find(name) != m_Images.end()) return m_Images[name].image; if(m_Layout == NULL) { m_Layout = new char[m_MaxSize * m_MaxSize]; memset(m_Layout, 0, m_MaxSize * m_MaxSize); } uint32 w = image->getWidth(); uint32 h = image->getHeight(); uint32 i = 0; MVector2 uv; // loop fail condition - end of the array uint32 fail = m_MaxSize * m_MaxSize; bool found = false; while(!found) { // look for the next empty pixel while(m_Layout[i] && i < fail) ++i; if(i == fail) return NULL; uv.x = i / m_MaxSize; uv.y = i % m_MaxSize; // check for every pixel in this area found = true; // be optimistic for(uint32 x = 0; x < w + PAD; ++x) for(uint32 y = 0; y < h + PAD; ++y) if(m_Layout[(m_MaxSize * ((uint32)uv.y+y)) + (uint32)uv.x+x]) found = NULL; // :( ++i; } // update the layout to block the space for future for(uint32 x = 0 ; x < w + PAD; ++x) for(uint32 y = PAD; y < h + PAD;++y) m_Layout[(m_MaxSize * ((uint32)uv.y+y)) + (uint32)uv.x+x] = 1; // update the target height for(uint32 x = 0; x < m_MaxSize; ++x) for(uint32 y = 0; y < m_MaxSize; ++y) if(m_Layout[y*m_MaxSize +x]) m_Height = MAX(m_Height, y+1); // update the target width for(uint32 y = 0; y < m_MaxSize; ++y) for(uint32 x = 0; x < m_MaxSize; ++x) if(m_Layout[y*m_MaxSize +x]) m_Width = MAX(m_Width, x+1); imageDef& def = m_Images[name]; def.uv = uv + MVector2(PAD/2, PAD/2); def.image = image; def.width = image->getWidth(); def.height = image->getHeight(); return image; }
void MGuiFileBrowser::updateMainWin(void) { m_mainWin->clear(); m_files.clear(); m_files.push_back(string("..")); if(readDirectory(m_currentDirectory.getSafeString(), &m_files)) { char filename[256]; // prepare unsigned int f, fSize = m_files.size(); for(f=0; f<fSize; f++) { const char * name = m_files[f].c_str(); if(f > 0) { getGlobalFilename(filename, m_currentDirectory.getSafeString(), name); if(isDirectory(filename)) m_files[f] = "/" + m_files[f]; } } // sort sort(m_files.begin(), m_files.end(), stringCompare); // scan for(f=0; f<fSize; f++) { float y = m_browserHeight*f; const char * name = m_files[f].c_str(); string textName = name; float grey = 0.24f; if((f%2) == 0) grey = 0.2f; MGuiButton * button = new MGuiButton( MVector2(0, y), MVector2(m_mainWin->getScale().x, m_browserHeight), MVector3(grey*0.9f, grey*1.1f, grey*1.3f), NULL ); button->setHighLightColor(MVector3(0.35f)); button->setPressedColor(MVector3(0.35f)); m_mainWin->addButton(button); MGuiText * text = new MGuiText(textName.c_str(), MVector2(0, y), 16, m_browserTextColor); m_mainWin->addText(text); } } m_mainWin->resizeScroll(); }
bool resizeImage(MImage * image, unsigned int destWidth, unsigned int destHeight, float filter) { if(! isImageValid(image)) return false; M_TYPES type = image->getDataType(); if(type == M_FLOAT) { MImage copy(*image); unsigned int components = image->getComponents(); unsigned int srcWidth = image->getWidth(); unsigned int srcHeight = image->getHeight(); float xFilter = filter; float yFilter = filter; MVector2 scale(srcWidth/(float)destWidth, srcHeight/(float)destHeight); image->create(type, destWidth, destHeight, components); float * destData = (float *)image->getData(); if(filter > 0) { #pragma omp parallel for schedule(dynamic, 8) for(unsigned int y=0; y<destHeight; y++) { float color[4]; float totalColor[4]; float * pixel = destData + destWidth*y*components; for(unsigned int x=0; x<destWidth; x++) { unsigned int i; MVector2 srcPos, destPos = MVector2((float)x, (float)y); float score = 0; memset(totalColor, 0, components*sizeof(float)); float dx, dy; for(dy=-yFilter; dy<=yFilter; dy+=yFilter) for(dx=-xFilter; dx<=xFilter; dx+=xFilter) { srcPos = (destPos + MVector2(dx, dy))*scale; getImageSubPixel_float(©, srcPos.x-0.5f, srcPos.y-0.5f, color); for(i=0; i<components; i++) totalColor[i] += color[i]; score++; } for(i=0; i<components; i++) pixel[i] = (totalColor[i] / score); pixel += components; } } } else if(filter == 0) { #pragma omp parallel for schedule(dynamic, 8) for(unsigned int y=0; y<destHeight; y++) { float * pixel = destData + destWidth*y*components; for(unsigned int x=0; x<destWidth; x++) { MVector2 srcPos = MVector2((float)x, (float)y)*scale; getImageSubPixel_float(©, srcPos.x-0.5f, srcPos.y-0.5f, pixel); pixel += components; } } } else { for(unsigned int y=0; y<destHeight; y++) { float * pixel = destData + destWidth*y*components; for(unsigned int x=0; x<destWidth; x++) { MVector2 srcPos = MVector2((float)x, (float)y)*scale; copy.readPixel(srcPos.x, srcPos.y, pixel); pixel += components; } } } } else if(type == M_UBYTE) { convertToFloat(image); resizeImage(image, destWidth, destHeight, filter); convertToUbyte(image); return true; } return true; }
void MGuiTextureFont::drawSelection(const char * text, const MVector2 & position, float size, unsigned int startId, unsigned int endId) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); if(startId == endId) return; MVector2 g_vertices[4]; render->disableNormalArray(); render->disableColorArray(); render->disableTexCoordArray(); render->enableVertexArray(); render->setVertexPointer(M_FLOAT, 2, g_vertices); unsigned int start; unsigned int end; if(endId > startId) { start = startId; end = endId; } else { start = endId; end = startId; } render->disableTexture(); MVector2 startPosition = getCharacterPosition(text, position, size, start); float xc = startPosition.x; float yc = startPosition.y; float offset = (size - (size*getSpace()))*0.5f; // left quad g_vertices[0] = MVector2(xc+offset, yc); g_vertices[1] = MVector2(xc+offset, yc+size); unsigned int i; unsigned int textLength = strlen(text); for(i=start; i<end && i<textLength; i++) { if(text[i] == '\n') // return { // right quad { g_vertices[3] = MVector2(xc+size*0.5f, yc+size); g_vertices[2] = MVector2(xc+size*0.5f, yc); render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); } yc += size; xc = position.x; // left quad { g_vertices[0] = MVector2(xc+offset, yc); g_vertices[1] = MVector2(xc+offset, yc+size); } } else if(text[i] == ' ') // tab { xc += size * getTabSpace(); if(i+1 == end || i+1 == textLength) { // right quad g_vertices[3] = MVector2(xc+offset, yc+size); g_vertices[2] = MVector2(xc+offset, yc); render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); } } else { xc += size * getSpace(); //move to next character if(i+1 == end || i+1 == textLength) { // right quad g_vertices[3] = MVector2(xc+offset, yc+size); g_vertices[2] = MVector2(xc+offset, yc); render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); } } } }
MGuiFileBrowser::MGuiFileBrowser(const MVector2 & position, const MVector2 & scale) { m_fileButtonsWidth = 150; m_fileButtonsHeight = 18; m_browserHeight = 18; m_margin = 3; m_headWinColor = MVector4(0.2f, 0.3f, 0.4f, 1.0f); m_mainWinColor = MVector4(0.15f, 0.15f, 0.15f, 1.0f); m_filesWinColor = MVector4(0.4f, 0.6f, 0.8f, 0.3f); m_headTextColor = MVector4(0.0f, 0.0f, 0.0f, 1.0f); m_browserTextColor = MVector4(1, 1, 1, 0.75f); m_buttonColor = MVector4(0.4f, 0.6f, 0.8f, 0.75f); m_highButtonColor = MVector4(0.8, 0.9f, 1.0f, 0.75f); m_pressButtonColor = MVector4(1.0, 1.0f, 0.5f, 1.0f); m_headWin = new MGuiWindow( position, MVector2(scale.x, m_fileButtonsHeight*2 + m_margin*3), m_headWinColor, NULL ); m_dirWin = new MGuiWindow( position + MVector2(m_margin), MVector2(scale.x - m_fileButtonsWidth - m_margin*3, m_fileButtonsHeight), m_filesWinColor, NULL ); m_dirWin->setScrollBarVisible(false); m_fileWin = new MGuiWindow( position + MVector2(m_margin) + MVector2(0, m_fileButtonsHeight + m_margin), MVector2(scale.x - m_fileButtonsWidth - m_margin*3, m_fileButtonsHeight), m_filesWinColor, NULL ); m_fileWin->setScrollBarVisible(false); m_mainWin = new MGuiWindow( position + MVector2(0, m_headWin->getScale().y), MVector2(scale.x, scale.y - m_headWin->getScale().y), m_mainWinColor, mainWinEvents ); m_mainWin->setMargin(MVector2(0.0f)); m_mainWin->setCustomVariable(this); // head texts and buttons { m_dirEditText = new MGuiEditText("", MVector2(1, 1), 16, m_headTextColor, dirEditTextEvents); m_dirEditText->enableVariable(&m_currentDirectory, M_VAR_STRING); m_dirEditText->setSingleLine(true); m_dirEditText->setCustomVariable(this); m_dirWin->addEditText(m_dirEditText); m_fileEditText = new MGuiEditText("", MVector2(1, 1), 16, m_headTextColor, NULL); m_fileEditText->enableVariable(&m_currentFile, M_VAR_STRING); m_fileEditText->setSingleLine(true); m_fileWin->addEditText(m_fileEditText); m_okButton = new MGuiButton( MVector2(m_dirWin->getScale().x + m_margin*2, m_margin), MVector2(m_fileButtonsWidth, m_fileButtonsHeight), m_buttonColor, fileBrowserOkButtonEvents ); m_okButton->setCenterText(true); m_okButton->setAutoScaleFromText(false); m_okButton->setTextColor(MVector4(0, 0, 0, 1)); m_okButton->setText("ok"); m_okButton->setHighLightColor(m_highButtonColor); m_okButton->setPressedColor(m_pressButtonColor); m_okButton->setCustomVariable(this); m_headWin->addButton(m_okButton); m_cancelButton = new MGuiButton( MVector2(m_dirWin->getScale().x + m_margin*2, m_margin*2 + m_fileButtonsHeight), MVector2(m_fileButtonsWidth, m_fileButtonsHeight), m_buttonColor, fileBrowserCancelButtonEvents ); m_cancelButton->setCenterText(true); m_cancelButton->setAutoScaleFromText(false); m_cancelButton->setTextColor(MVector4(0, 0, 0, 1)); m_cancelButton->setText("cancel"); m_cancelButton->setHighLightColor(m_highButtonColor); m_cancelButton->setPressedColor(m_pressButtonColor); m_cancelButton->setCustomVariable(this); m_headWin->addButton(m_cancelButton); } m_headWin->setVisible(false); m_dirWin->setVisible(false); m_fileWin->setVisible(false); m_mainWin->setVisible(false); MGui * gui = MGui::getInstance(); gui->addWindow(m_headWin); gui->addWindow(m_dirWin); gui->addWindow(m_fileWin); gui->addWindow(m_mainWin); }
void MGuiEditText::draw(void) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); if(! isVisible()) return; if(! isPressed()) updateFromVariable(); // draw selection if(isPressed()) { render->disableTexture(); render->setColor4(MVector4(1, 0.1f, 0.1f, 0.3f)); getFont()->drawSelection(getText(), getPosition(), getTextSize(), m_startSelectionId, m_endSelectionId); } // set text color if(isPressed()){ render->setColor4(getPressedColor()); } else if(isHighLight()){ render->setColor4(getHighLightColor()); } else{ render->setColor4(getNormalColor()); } // draw text render->enableTexture(); getFont()->draw(getText(), getPosition(), getTextSize()); if(isPressed() && (m_startSelectionId == m_endSelectionId)) // cursor { render->disableTexture(); render->setColor4(MVector4(1, 0, 0, 0.5f)); // position MVector2 position = getFont()->getCharacterPosition( getText(), getPosition(), getTextSize(), getCharId() ); // scale MVector2 scale = MVector2(getTextSize() * 0.1f, getTextSize()); float offset = (getTextSize() - (getTextSize()*getFont()->getSpace()))*0.5f; float px = (float)((int)(position.x + offset)); float py = (float)((int)position.y); // draw render->disableNormalArray(); render->disableTexCoordArray(); render->disableColorArray(); render->enableVertexArray(); MVector2 vertices[4] = { MVector2(px, py), MVector2(px, py + scale.y), MVector2(px + scale.x, py), MVector2(px + scale.x, py + scale.y) }; render->setVertexPointer(M_FLOAT, 2, vertices); render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); } MGuiEvent guiEvent; guiEvent.type = MGUI_EVENT_DRAW; if(m_pointerEvent) m_pointerEvent(this, &guiEvent); }
// main int main(int argc, char **argv) { setlocale(LC_NUMERIC, "C"); // get engine (first time call onstructor) MEngine * engine = MEngine::getInstance(); // get window (first time call onstructor) MWindow * window = MWindow::getInstance(); // create window window->create("Maratis", 1024,768, 32, false); // set current directory char rep[256]; getRepertory(rep, argv[0]); window->setCurrentDirectory(rep); // get Maratis (first time call onstructor) Maratis * maratis = Maratis::getInstance(); MRenderingContext * render = engine->getRenderingContext(); // init gui MGui * gui = MGui::getInstance(); gui->setRenderingContext(render); gui->addFont(new MGuiTextureFont("font/default.tga")); // init MaratisUI window->setPointerEvent(MaratisUI::windowEvents); // logo { MImage image; if(! M_loadImage("gui/Title.png", &image)) return 0; render->createTexture(&logoTextureId); render->bindTexture(logoTextureId); render->sendTextureImage(&image, false, false, false); // clear window draw(); MGuiText text("LOADING", MVector2(480, 280), 16, MVector4(1, 1, 1, 1)); text.draw(); window->swapBuffer(); } // load project if(argc > 1) { maratis->loadProject(argv[1]); } // time unsigned int frequency = 60; unsigned long previousFrame = 0; unsigned long startTick = window->getSystemTick(); int f = 0; int t = 0; // on events while(window->isActive()) { // on events if(window->onEvents()) { // compute target tick unsigned long currentTick = window->getSystemTick(); unsigned long tick = currentTick - startTick; unsigned long frame = (unsigned long)(tick * (frequency * 0.001f)); // update elapsed time unsigned int i; unsigned int steps = (unsigned int)(frame - previousFrame); if(window->getFocus()) { // don't wait too much if(steps >= (frequency/2)) { update(); draw(); previousFrame += steps; continue; } // update for(i=0; i<steps; i++) { update(); previousFrame++; t++; if(t == frequency) { MGame * game = engine->getGame(); if(game) { if(! game->isRunning()) MFilesUpdate::update(); } else { MFilesUpdate::update(); } //printf("fps:%d\n", f); t = 0; f = 0; } } // draw //if(steps > 0) { draw(); f++; } } else { previousFrame = frame; window->swapBuffer(); } } } gui->clear(); maratis->clear(); return 0; }
bool M_loadFont(const char * filename, void * data, void * arg) { MFont * font = (MFont *)data; int pen_x, pen_y, max_y; unsigned int n, max_code = 4096; unsigned int size = font->getFontSize(); unsigned int space = 2; unsigned int width = 1024; unsigned int height = 0; MImage image; FT_GlyphSlot slot; FT_Library library; FT_Face face; FT_Byte * file_base; FT_Long file_size; // init FT_Error error = FT_Init_FreeType(&library); if(error){ printf("ERROR Load Font : unable to init FreeType\n"); return false; } // open file MFile * file = M_fopen(filename, "rb"); if(! file) { FT_Done_FreeType(library); printf("ERROR Load Font : can't read file %s\n", filename); return false; } M_fseek(file, 0, SEEK_END); file_size = M_ftell(file); M_rewind(file); file_base = new FT_Byte[file_size]; if(file_size != M_fread(file_base, sizeof(FT_Byte), file_size, file)) { M_fclose(file); FT_Done_FreeType(library); delete [] file_base; return false; } // read font error = FT_New_Memory_Face(library, file_base, file_size, 0, &face); M_fclose(file); if(error) { printf("ERROR Load Font : unable to read data %s\n", filename); FT_Done_FreeType(library); delete [] file_base; return false; } // set font size error = FT_Set_Pixel_Sizes(face, 0, size); if(error) { printf("ERROR Load Font : unable to size font\n"); FT_Done_FreeType(library); delete [] file_base; return false; } // parse characters max_y = 0; slot = face->glyph; pen_x = space; pen_y = space; for(n = 0; n<max_code; n++) { // load glyph image into the slot (erase previous one) error = FT_Load_Char(face, n, FT_LOAD_RENDER | FT_LOAD_NO_HINTING); if(error) continue; if(FT_Get_Char_Index(face, n) == 0) continue; // max y max_y = MAX(max_y, slot->bitmap.rows); if((pen_x + slot->bitmap.width + space) > width) { pen_x = space; pen_y += max_y + space; height += max_y + space; max_y = 0; } // increment pen position pen_x += slot->bitmap.width + space; } if(height == 0) { printf("ERROR Load Font : unable to create font texture\n"); FT_Done_FreeType(library); delete [] file_base; return false; } // create image height = getNextPowerOfTwo(height); image.create(M_UBYTE, width, height, 4); memset(image.getData(), 0, image.getSize()*sizeof(char)); // init font font->setTextureWidth(width); font->setTextureHeight(height); // create font texture max_y = 0; slot = face->glyph; pen_x = space; pen_y = space; for(n = 0; n<max_code; n++) { // load glyph image into the slot (erase previous one) error = FT_Load_Char(face, n, FT_LOAD_RENDER | FT_LOAD_NO_HINTING); if(error) continue; if(FT_Get_Char_Index(face, n) == 0) continue; // max y max_y = MAX(max_y, slot->bitmap.rows); if((pen_x + slot->bitmap.width + space) > (int)image.getWidth()){ pen_x = space; pen_y += max_y + space; } // get character properties float xAdvance = (slot->advance.x >> 6) / ((float)size); MVector2 offset = MVector2((float)slot->bitmap_left - 1, - (float)slot->bitmap_top - 1) / ((float)size); MVector2 pos = MVector2((float)(pen_x-1) / (float)width, (float)(pen_y-1) / (float)height); MVector2 scale = MVector2((float)(slot->bitmap.width+2) / (float)width, (float)(slot->bitmap.rows+2) / (float)height); // set character font->setCharacter(n, MCharacter(xAdvance, offset, pos, scale)); // draw to image drawBitmap(&image, &slot->bitmap, pen_x, pen_y); // increment pen position pen_x += slot->bitmap.width + space; } // send texture MEngine * engine = MEngine().getInstance(); MRenderingContext * render = engine->getRenderingContext(); // gen texture id unsigned int textureId = font->getTextureId(); if(textureId == 0) { render->createTexture(&textureId); font->setTextureId(textureId); } // send texture image render->bindTexture(textureId); render->setTextureUWrapMode(M_WRAP_REPEAT); render->setTextureVWrapMode(M_WRAP_REPEAT); render->sendTextureImage(&image, 0, 1, 0); // finish FT_Done_FreeType(library); delete [] file_base; return true; }
void MOText::prepare(void) { MFont * font = getFont(); const char * text = m_text.getData(); if(! (strlen(text) > 0 && font)){ m_boundingBox = MBox3d(); return; } MVector3 * min = m_boundingBox.getMin(); MVector3 * max = m_boundingBox.getMax(); (*min) = (*max) = MVector3(0, 0, 0); float tabSize = m_size*2; float fontSize = (float)font->getFontSize(); float widthFactor = font->getTextureWith() / fontSize; float heightFactor = font->getTextureHeight() / fontSize; float xc = 0, yc = 0; unsigned int i; unsigned int size = strlen(text); for(i=0; i<size; i++) { if(text[i] == '\n') // return { yc += m_size; xc = 0; continue; } if(text[i] == '\t') // tab { int tab = (int)(xc / tabSize) + 1; xc = tab*tabSize; continue; } // get character unsigned int charCode = (unsigned int)((unsigned char)text[i]); MCharacter * character = font->getCharacter(charCode); if(! character) continue; MVector2 scale = character->getScale(); MVector2 offset = character->getOffset() * m_size; float width = scale.x * widthFactor * m_size; float height = scale.y * heightFactor * m_size; MVector2 charMin = MVector2(xc, yc) + offset; MVector2 charMax = charMin + MVector2(width, height); if(charMin.x < min->x) min->x = charMin.x; if(charMin.y < min->y) min->y = charMin.y; if(charMax.x > max->x) max->x = charMax.x; if(charMax.y > max->y) max->y = charMax.y; //move to next character xc += character->getXAdvance() * m_size; } updateLinesOffset(); }
void MFixedRenderer::drawText(MOText * textObj) { M_PROFILE_SCOPE(MFixedRenderer::drawText); MFont * font = textObj->getFont(); const char * text = textObj->getText(); vector <float> * linesOffset = textObj->getLinesOffset(); if(! (strlen(text) > 0 && font)) return; if(linesOffset->size() == 0) return; MRenderingContext * render = MEngine().getInstance()->getRenderingContext(); render->enableBlending(); render->enableTexture(); render->disableLighting(); render->setColor4(*textObj->getColor()); render->setBlendingMode(M_BLENDING_ALPHA); static MVector2 vertices[4]; static MVector2 texCoords[4]; render->disableNormalArray(); render->disableColorArray(); render->enableVertexArray(); render->enableTexCoordArray(); render->setVertexPointer(M_FLOAT, 2, vertices); render->setTexCoordPointer(M_FLOAT, 2, texCoords); render->bindTexture(font->getTextureId()); unsigned int lineId = 0; float lineOffset = (*linesOffset)[0]; float size = textObj->getSize(); float tabSize = size*2; float fontSize = (float)font->getFontSize(); float widthFactor = font->getTextureWith() / fontSize; float heightFactor = font->getTextureHeight() / fontSize; float xc = 0, yc = 0; unsigned int i; unsigned int textLen = strlen(text); for(i=0; i<textLen; i++) { if(text[i] == '\n') // return { if(((i+1) < textLen)) { lineId++; lineOffset = (*linesOffset)[lineId]; yc += size; xc = 0; } continue; } if(text[i] == '\t') // tab { int tab = (int)(xc / tabSize) + 1; xc = tab*tabSize; continue; } // get character unsigned int charCode = (unsigned int)((unsigned char)text[i]); MCharacter * character = font->getCharacter(charCode); if(! character) continue; MVector2 pos = character->getPos(); MVector2 scale = character->getScale(); MVector2 offset = character->getOffset() * size + MVector2(lineOffset, 0); float width = scale.x * widthFactor * size; float height = scale.y * heightFactor * size; // construct quad texCoords[0] = MVector2(pos.x, (pos.y + scale.y)); vertices[0] = MVector2(xc, (yc + height)) + offset; texCoords[1] = MVector2((pos.x + scale.x), (pos.y + scale.y)); vertices[1] = MVector2((xc + width), (yc + height)) + offset; texCoords[3] = MVector2((pos.x + scale.x), pos.y); vertices[3] = MVector2((xc + width), yc) + offset; texCoords[2] = MVector2(pos.x, pos.y); vertices[2] = MVector2(xc, yc) + offset; // draw quad render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); //move to next character xc += character->getXAdvance() * size; } }
void MFixedRenderer::drawDisplay(MSubMesh * subMesh, MDisplay * display, MVector3 * vertices, MVector3 * normals, MColor * colors) { M_PROFILE_SCOPE(MFixedRenderer::drawDisplay); MEngine * engine = MEngine::getInstance(); MRenderingContext * render = engine->getRenderingContext(); render->setColor4(MVector4(1, 1, 1, 1)); // get material MMaterial * material = display->getMaterial(); { float opacity = material->getOpacity(); if(opacity <= 0.0f) return; // data M_TYPES indicesType = subMesh->getIndicesType(); void * indices = subMesh->getIndices(); MVector2 * texCoords = subMesh->getTexCoords(); // begin / size unsigned int begin = display->getBegin(); unsigned int size = display->getSize(); // get properties M_PRIMITIVE_TYPES primitiveType = display->getPrimitiveType(); M_BLENDING_MODES blendMode = material->getBlendMode(); M_CULL_MODES cullMode = display->getCullMode(); MVector3 * diffuse = material->getDiffuse(); MVector3 * specular = material->getSpecular(); MVector3 * emit = material->getEmit(); float shininess = material->getShininess(); // get current fog color MVector3 currentFogColor; render->getFogColor(¤tFogColor); // set cull mode if(cullMode == M_CULL_NONE){ render->disableCullFace(); } else{ render->enableCullFace(); render->setCullMode(cullMode); } // texture passes unsigned int texturesPassNumber = MIN(8, material->getTexturesPassNumber()); // set blending mode render->setBlendingMode(blendMode); // alpha test if(blendMode != M_BLENDING_ALPHA && texturesPassNumber > 0) { MTexturePass * texturePass = material->getTexturePass(0); MTexture * texture = texturePass->getTexture(); if(texture) { if(texture->getTextureRef()->getComponents() > 3) render->setAlphaTest(0.5f); } } // set fog color depending on blending switch(blendMode) { case M_BLENDING_ADD: case M_BLENDING_LIGHT: render->setFogColor(MVector3(0, 0, 0)); break; case M_BLENDING_PRODUCT: render->setFogColor(MVector3(1, 1, 1)); break; } // fixed pipeline { // no FX render->bindFX(0); // Vertex render->enableVertexArray(); render->setVertexPointer(M_FLOAT, 3, vertices); // Normal if(normals) { render->enableNormalArray(); render->setNormalPointer(M_FLOAT, normals); } // Color if(colors) { render->disableLighting(); render->enableColorArray(); render->setColorPointer(M_UBYTE, 4, colors); } // Material render->setMaterialDiffuse(MVector4(diffuse->x, diffuse->y, diffuse->z, opacity)); render->setMaterialSpecular(MVector4(*specular)); render->setMaterialAmbient(MVector4()); render->setMaterialEmit(MVector4(*emit)); render->setMaterialShininess(shininess); // switch to texture matrix mode if(texturesPassNumber > 0) render->setMatrixMode(M_MATRIX_TEXTURE); else render->disableTexture(); // Textures int id = texturesPassNumber; for(unsigned int t=0; t<texturesPassNumber; t++) { MTexturePass * texturePass = material->getTexturePass(t); MTexture * texture = texturePass->getTexture(); if((! texture) || (! texCoords)) { render->bindTexture(0, t); render->disableTexture(); render->disableTexCoordArray(); continue; } // texCoords unsigned int offset = 0; if(subMesh->isMapChannelExist(texturePass->getMapChannel())) offset = subMesh->getMapChannelOffset(texturePass->getMapChannel()); // texture id unsigned int textureId = 0; MTextureRef * texRef = texture->getTextureRef(); if(texRef) textureId = texRef->getTextureId(); // bind texture render->bindTexture(textureId, t); render->enableTexture(); render->setTextureCombineMode(texturePass->getCombineMode()); render->setTextureUWrapMode(texture->getUWrapMode()); render->setTextureVWrapMode(texture->getVWrapMode()); // texture matrix render->loadIdentity(); render->translate(MVector2(0.5f, 0.5f)); render->scale(*texture->getTexScale()); render->rotate(MVector3(0, 0, -1), texture->getTexRotate()); render->translate(MVector2(-0.5f, -0.5f)); render->translate(*texture->getTexTranslate()); // texture coords render->enableTexCoordArray(); render->setTexCoordPointer(M_FLOAT, 2, texCoords + offset); } // switch back to modelview matrix mode if(texturesPassNumber > 0) render->setMatrixMode(M_MATRIX_MODELVIEW); // draw if(indices) { switch(indicesType) { case M_USHORT: render->drawElement(primitiveType, size, indicesType, (unsigned short*)indices + begin); break; case M_UINT: render->drawElement(primitiveType, size, indicesType, (unsigned int*)indices + begin); break; } } else{ render->drawArray(primitiveType, begin, size); } // disable arrays render->disableVertexArray(); if(normals) render->disableNormalArray(); if(colors) render->disableColorArray(); // restore textures for(int t=(int)(id-1); t>=0; t--) { render->bindTexture(0, t); render->disableTexture(); render->disableTexCoordArray(); render->setTextureCombineMode(M_TEX_COMBINE_MODULATE); render->setMatrixMode(M_MATRIX_TEXTURE); render->loadIdentity(); render->setMatrixMode(M_MATRIX_MODELVIEW); } } // restore fog and alpha test render->setFogColor(currentFogColor); if(blendMode != M_BLENDING_ALPHA) render->setAlphaTest(0.0f); // restore lighting if(colors) render->enableLighting(); } }
void MGuiWindow::onEvent(MWinEvent * windowEvent) { MMouse * mouse = MMouse::getInstance(); switch(windowEvent->type) { case MWIN_EVENT_WINDOW_RESIZE: if(m_pointerEvent) // send gui event { MGuiEvent guiEvent; guiEvent.type = MGUI_EVENT_RESIZE; m_pointerEvent(this, &guiEvent); } resizeScroll(); break; case MWIN_EVENT_KEY_DOWN: switch(windowEvent->data[0]) { case MKEY_TAB: { // editTexts unsigned int eSize = m_editTexts.size(); unsigned int i; // select next edit text for(i=0; i<eSize; i++) { if(m_editTexts[i]->isSingleLine() && m_editTexts[i]->isPressed()) { m_editTexts[i]->setPressed(false); m_editTexts[i]->sendVariable(); unsigned int nextId = i + 1; if(nextId >= eSize) nextId = 0; m_editTexts[nextId]->setPressed(true); m_editTexts[nextId]->setCharId(0); m_editTexts[nextId]->setSelection(0, strlen(m_editTexts[nextId]->getText())); return; } } break; } case MKEY_DOWN: { // editTexts unsigned int eSize = m_editTexts.size(); unsigned int i; // select next edit text for(i=0; i<eSize; i++) { if(m_editTexts[i]->isSingleLine() && m_editTexts[i]->isPressed()) { m_editTexts[i]->setPressed(false); m_editTexts[i]->sendVariable(); unsigned int nextId = i + 1; if(nextId >= eSize) nextId = 0; m_editTexts[nextId]->setPressed(true); m_editTexts[nextId]->setCharId(m_editTexts[i]->getCharId()); return; } } break; } case MKEY_UP: { // editTexts unsigned int eSize = m_editTexts.size(); unsigned int i; // select previous edit text for(i=0; i<eSize; i++) { if(m_editTexts[i]->isSingleLine() && m_editTexts[i]->isPressed()) { m_editTexts[i]->setPressed(false); m_editTexts[i]->sendVariable(); int nextId = i - 1; if(nextId < 0) nextId = eSize - 1; m_editTexts[nextId]->setPressed(true); m_editTexts[nextId]->setCharId(m_editTexts[i]->getCharId()); return; } } break; } } break; case MWIN_EVENT_MOUSE_WHEEL_MOVE: if(isHighLight()) moveScroll(MVector2(0, mouse->getWheelDirection() * (getTextSize() * 3))); break; case MWIN_EVENT_MOUSE_MOVE: if(isScrolled()) moveScroll(MVector2((float)mouse->getXDirection(), (float)mouse->getYDirection())); if(isMouseInside()){ setHighLight(true); if(m_pointerEvent) // send mouse move gui event { MGuiEvent guiEvent; guiEvent.type = MGUI_EVENT_MOUSE_MOVE; guiEvent.data[0] = windowEvent->data[0]; guiEvent.data[1] = windowEvent->data[1]; m_pointerEvent(this, &guiEvent); } } else{ setHighLight(false); } break; case MWIN_EVENT_MOUSE_BUTTON_DOWN: if(isHighLight()) { if(windowEvent->data[0] == MMOUSE_BUTTON_LEFT){ setPressed(true); } if(windowEvent->data[0] == MMOUSE_BUTTON_MIDDLE){ resizeScroll(); setScrolled(true); } } if(m_pointerEvent) // send mouse button down gui event { MGuiEvent guiEvent; guiEvent.type = MGUI_EVENT_MOUSE_BUTTON_DOWN; guiEvent.data[0] = windowEvent->data[0]; m_pointerEvent(this, &guiEvent); } break; case MWIN_EVENT_MOUSE_BUTTON_UP: if(windowEvent->data[0] == MMOUSE_BUTTON_MIDDLE) setScrolled(false); if(windowEvent->data[0] == MMOUSE_BUTTON_LEFT) setPressed(false); if(isHighLight()) { if(m_pointerEvent) // send mouse button up gui event { MGuiEvent guiEvent; guiEvent.type = MGUI_EVENT_MOUSE_BUTTON_UP; guiEvent.data[0] = windowEvent->data[0]; m_pointerEvent(this, &guiEvent); } } break; } internalEvent(windowEvent); }
void MGui2d::drawShadow(void) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); MVector2 g_vertices[8]; MVector4 g_colors[8]; render->disableTexture(); render->enableBlending(); render->setBlendingMode(M_BLENDING_ALPHA); MVector4 color0 = MVector4(0, 0, 0, 0); MVector4 color1 = MVector4(0, 0, 0, 0.05f); float size = 4; MVector2 dir[4]; dir[0] = MVector2(size, size*0.4f); dir[1] = MVector2(size*0.4f, size); dir[2] = MVector2(size*0.4f, size*0.1f); dir[3] = MVector2(size*0.1f, size*0.4f); render->disableNormalArray(); render->disableTexCoordArray(); render->enableVertexArray(); render->enableColorArray(); render->setVertexPointer(M_FLOAT, 2, g_vertices); render->setColorPointer(M_FLOAT, 4, g_colors); for(int i=0; i<4; i++) { g_colors[0] = color1; g_vertices[0] = MVector2(0, m_scale.y) + MVector2(dir[i].x, 0); g_colors[1] = color0; g_vertices[1] = MVector2(0, m_scale.y) + MVector2(size, size) + dir[i]; g_colors[2] = color1; g_vertices[2] = MVector2(m_scale.x, m_scale.y); g_colors[3] = color0; g_vertices[3] = MVector2(m_scale.x, m_scale.y) + MVector2(size, size) + dir[i]; g_colors[4] = color1; g_vertices[4] = MVector2(m_scale.x, 0) + MVector2(0, dir[i].y); g_colors[5] = color0; g_vertices[5] = MVector2(m_scale.x, 0) + MVector2(size, size) + dir[i]; render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 6); } }
void MGameBoard::CollisionEvent( int iType, int iIndex, int iRow ) { if( !m_bReachedBottom && iType == COLLISION_LEFT_SCREEN ) { m_bRowShift = true; for( int i = 0; i < INVADERS_NUM_ROWS; ++i ) { for( int j = 0; j < INVADERS_NUM_COLS; ++j ) { if( m_pEnemies[i][j] ) { m_pEnemies[i][j]->SetVelocity(MVector2(50.0f,0.0f)); switch( m_iSpeedTier ) { case 1: m_pEnemies[i][j]->SetVelocity(MVector2(m_fSpeedTier1->GetValueFloat(),0.0f)); break; case 2: m_pEnemies[i][j]->SetVelocity(MVector2(m_fSpeedTier2->GetValueFloat(),0.0f)); break; case 3: m_pEnemies[i][j]->SetVelocity(MVector2(m_fSpeedTier3->GetValueFloat(),0.0f)); break; case 4: m_pEnemies[i][j]->SetVelocity(MVector2(m_fSpeedTier4->GetValueFloat(),0.0f)); break; } } } } } else if( !m_bReachedBottom && iType == COLLISION_RIGHT_SCREEN ) { for( int i = 0; i < INVADERS_NUM_ROWS; ++i ) { for( int j = 0; j < INVADERS_NUM_COLS; ++j ) { if( m_pEnemies[i][j] ) { m_pEnemies[i][j]->SetVelocity(MVector2(-50.0f,0.0f)); switch( m_iSpeedTier ) { case 1: m_pEnemies[i][j]->SetVelocity(MVector2(-m_fSpeedTier1->GetValueFloat(),0.0f)); break; case 2: m_pEnemies[i][j]->SetVelocity(MVector2(-m_fSpeedTier2->GetValueFloat(),0.0f)); break; case 3: m_pEnemies[i][j]->SetVelocity(MVector2(-m_fSpeedTier3->GetValueFloat(),0.0f)); break; case 4: m_pEnemies[i][j]->SetVelocity(MVector2(-m_fSpeedTier4->GetValueFloat(),0.0f)); break; } } } } if( m_bRowShift ) { if( m_iSpeedTier < 4 ) ++m_iSpeedTier; for( int i = 0; i < INVADERS_NUM_ROWS; ++i ) { for( int j = 0; j < INVADERS_NUM_COLS; ++j ) { if( m_pEnemies[i][j] ) { MVector2 vPosition = m_pEnemies[i][j]->GetPosition(); m_pEnemies[i][j]->SetPosition(MVector2(vPosition.x,vPosition.y + 20.0f)); } } } m_bRowShift = false; } } else if( !m_bReachedBottom && iType == COLLISION_LOWER_SCREEN ) { for( int i = 0; i < INVADERS_NUM_ROWS; ++i ) { for( int j = 0; j < INVADERS_NUM_COLS; ++j ) { if( m_pEnemies[i][j] ) { if( rand() % 1 == 1 ) m_pEnemies[i][j]->SetVelocity(MVector2(rand() % 500 + 300,-rand() % 500 + 300)); else m_pEnemies[i][j]->SetVelocity(MVector2(-rand() % 500 + 300,-rand() % 500 + 300)); } } } m_bReachedBottom = true; } else if( iType == COLLISION_ENTITY ) { m_pEnemies[iRow][iIndex].reset(); } }