XprBool xprAppInitialize() { app = appAlloc(); appInit(app); // remote config { RemoteVarDesc descs[] = { {"gravity", &settings.gravity, 1, 100}, {"airResistance", &settings.airResistance, 1, 20}, {"impact", &settings.impact, 1, 10}, {"shadowSlopScale", &settings.shadowSlopScale, 0, 8}, {nullptr, nullptr, 0, 0} }; config = remoteConfigAlloc(); remoteConfigInit(config, 8080, XprTrue); remoteConfigAddVars(config, descs); } // shadow map shadowMap = xprRenderTargetAcquireBuffer(app->renderTarget, shadowMapSize, shadowMapSize, XprGpuFormat_FloatR16); shadowMapZ = xprRenderTargetAcquireBuffer(app->renderTarget, shadowMapSize, shadowMapSize, XprGpuFormat_Depth16); // materials { const char* directives[] = {nullptr}; appLoadMaterialBegin(app, directives); sceneMtl = appLoadMaterial( "ClothSimulation.Scene.Vertex", "ClothSimulation.Scene.Fragment", nullptr, nullptr, nullptr); bgMtl = appLoadMaterial( "Common.Bg.Vertex", "Common.Bg.Fragment", nullptr, nullptr, nullptr); shadowMapMtl = appLoadMaterial( "ShadowMap.Create.Vertex", "ShadowMap.Create.Fragment", nullptr, nullptr, nullptr); appLoadMaterialEnd(app); } // textures { texture = Pvr_createTexture(red_tile_texture); } // cloth { XprVec3 offset = xprVec3(-1, 1.5f, 0); cloth = Cloth_new(2, 2, &offset, 32); } // balls { ball[0].center = xprVec3(-0.5f, 0.5f, 0); ball[0].radius = 0.25f; ball[1].center = xprVec3(0.5f, 0.5f, 0); ball[1].radius = 0.25f; ballMesh = meshAlloc(); meshInitWithUnitSphere(ballMesh, 32); } // floor { XprVec3 offset = xprVec3(-2.5f, -2.5f, 0); floorMesh = meshAlloc(); meshInitWithQuad(floorMesh, 5, 5, &offset, 1); } // bg { bgMesh = meshAlloc(); meshInitWithScreenQuad(bgMesh); } return XprTrue; }
int main(const int argc, const char * argv[]) { AppContext ctx; if (!appInit(argc, argv, "NTB Widgets Test", 1024, 768, &ctx)) { std::fprintf(stderr, "[APP_ERROR]: Failed to initialize sample app!\n"); return EXIT_FAILURE; } ntb::initialize(ctx.shellInterface, ctx.renderInterface); { bool done = false; ntb::GeometryBatch geoBatch; ntb::PODArray widgets{ sizeof(ntb::Widget *) }; ntb::GUI * gui = ntb::createGUI("Sample GUI"); // Basic blank widget: { auto w = new ntb::Widget{}; w->init(gui, nullptr, ntb::Rectangle{ 20, 20, 300, 300 }, true); widgets.pushBack(w); } // A set of buttons: { MyButtonEventListener buttonEventListener; const int buttonIconCount = static_cast<int>(ntb::ButtonWidget::Icon::Count); constexpr float btnScale = 1.6f; constexpr int btnSize = 50; constexpr int xStart = 350; constexpr int yStart = 20; int x = xStart; for (int i = 1; i < buttonIconCount; ++i) // Skip fist (Icon::None/0) { auto btn = new ntb::ButtonWidget{}; btn->init(gui, nullptr, ntb::Rectangle{ x, yStart, x + btnSize, yStart + btnSize }, true, ntb::ButtonWidget::Icon(i), &buttonEventListener); btn->setTextScaling(btnScale); btn->setState(true); x += btnSize + 20; // gap between each (20) widgets.pushBack(btn); } } // Title bar & Info bar widgets: { constexpr int btnOffsX = 20; constexpr int btnOffsY = 4; constexpr int btnSize = 40; constexpr int btnSpacing = 12; auto tb = new ntb::TitleBarWidget{}; tb->init(gui, nullptr, ntb::Rectangle{ 350, 120, 900, 170 }, true, "A title bar - drag me!", true, true, btnOffsX, btnOffsY, btnSize, btnSpacing); tb->setTextScaling(1.6f); // Title bar text tb->setButtonTextScaling(1.5f); // Button icon text widgets.pushBack(tb); auto ib = new ntb::InfoBarWidget{}; ib->init(gui, nullptr, ntb::Rectangle{ 350, 200, 900, 250 }, true, "Info bar"); ib->setTextScaling(1.6f); widgets.pushBack(ib); } // List widget: { auto l = new ntb::ListWidget{}; l->init(gui, nullptr, ntb::Rectangle{ 20, 350, 300, 500 }, true); l->setTextScaling(1.5f); l->allocEntries(4); l->addEntryText(0, "Hello"); l->addEntryText(1, "World"); l->addEntryText(2, "A longer string"); l->addEntryText(3, "And this one is even longer"); widgets.pushBack(l); } // Scrollbar widget: { auto sb = new ntb::ScrollBarWidget{}; sb->init(gui, nullptr, ntb::Rectangle{ 550, 300, 600, 600 }, true, 30); sb->updateLineScrollState(10, 5); widgets.pushBack(sb); } // Color Picker widget: { constexpr int colorPickerWidth = 360; constexpr int colorPickerHeight = 500; constexpr int xStart = 20; constexpr int yStart = 600; const ntb::Rectangle rect{ xStart, yStart, xStart + colorPickerWidth, yStart + colorPickerHeight }; auto cp = new ntb::ColorPickerWidget{}; cp->init(gui, nullptr, rect, true, 40, 28, 40, 25, 40); cp->setTextScaling(1.5f); cp->setButtonTextScaling(1.0f); widgets.pushBack(cp); } // 3D view widgets: { constexpr int view3dWidth = 450; constexpr int view3dHeight = 500; constexpr int xStart = 500; constexpr int yStart = 650; ntb::View3DWidget::ProjectionParameters projParams; projParams.fovYRadians = ntb::degToRad(60.0f); projParams.aspectRatio = 0.0f; // auto computed projParams.zNear = 0.5f; projParams.zFar = 100.0f; projParams.autoAdjustAspect = true; const int objCount = static_cast<int>(ntb::View3DWidget::ObjectType::Count); int x = xStart; for (int i = 1; i < objCount; ++i) { const ntb::Rectangle rect{ x, yStart, x + view3dWidth, yStart + view3dHeight }; auto v3d = new ntb::View3DWidget{}; v3d->init(gui, nullptr, rect, true, "3D View Widget", 40, 28, 10, projParams, ntb::View3DWidget::ObjectType(i)); v3d->setTextScaling(1.5f); v3d->setButtonTextScaling(1.0f); x += view3dWidth + 50; widgets.pushBack(v3d); } } // Var data display widgets inside a window/panel: { auto varWindow = new ntb::WindowWidget{}; varWindow->init(gui, nullptr, ntb::Rectangle{ 1000, 20, 1500, 600 }, true, false, "Variables Test", 40, 28, 40, 25); varWindow->setTextScaling(1.5f); varWindow->setButtonTextScaling(1.0f); constexpr int varStartX = 1100; constexpr int varStartY = 90; constexpr int varWidth = 300; constexpr int varHeight = 50; constexpr int varOffsY = 8; ntb::Rectangle rect; int y = varStartY; auto var0 = new ntb::VarDisplayWidget{}; rect.set(varStartX, y, varStartX + varWidth, y + varHeight); y += varHeight + varOffsY; var0->init(gui, nullptr, rect, true, varWindow, "Var 0"); var0->setTextScaling(1.5f); var0->setButtonTextScaling(1.5f); auto var1 = new ntb::VarDisplayWidget{}; rect.set(varStartX, y, varStartX + varWidth, y + varHeight); y += varHeight + varOffsY; var1->init(gui, var0, rect, true, varWindow, "Var 1"); var1->setTextScaling(1.5f); auto var2 = new ntb::VarDisplayWidget{}; rect.set(varStartX, y, varStartX + varWidth, y + varHeight); y += varHeight + varOffsY; var2->init(gui, var0, rect, true, varWindow, "Var 2"); var2->setTextScaling(1.5f); // Change sizes so child vars look nested under the parent int cX = varStartX + var0->getExpandCollapseButtonSize(); int cW = varWidth - var0->getExpandCollapseButtonSize(); auto var3 = new ntb::VarDisplayWidget{}; rect.set(cX, y, cX + cW, y + varHeight); y += varHeight + varOffsY; var3->init(gui, var0, rect, true, varWindow, "Var 3"); var3->setTextScaling(1.5f); var3->setButtonTextScaling(1.5f); auto var4 = new ntb::VarDisplayWidget{}; rect.set(cX, y, cX + cW, y + varHeight); y += varHeight + varOffsY; var4->init(gui, var3, rect, true, varWindow, "Var 4"); var4->setTextScaling(1.5f); cX += var0->getExpandCollapseButtonSize(); cW -= var0->getExpandCollapseButtonSize(); auto var5 = new ntb::VarDisplayWidget{}; rect.set(cX, y, cX + cW, y + varHeight); y += varHeight + varOffsY; var5->init(gui, var3, rect, true, varWindow, "Var 5"); var5->setTextScaling(1.5f); var5->setButtonTextScaling(1.5f); auto var6 = new ntb::VarDisplayWidget{}; rect.set(cX, y, cX + cW, y + varHeight); y += varHeight + varOffsY; var6->init(gui, var5, rect, true, varWindow, "Var 6"); var6->setTextScaling(1.5f); auto var7 = new ntb::VarDisplayWidget{}; rect.set(cX, y, cX + cW, y + varHeight); y += varHeight + varOffsY; var7->init(gui, var5, rect, true, varWindow, "Var 7"); var7->setTextScaling(1.5f); #if NEO_TWEAK_BAR_DEBUG varWindow->printHierarchy(); std::cout << "\n"; #endif // NEO_TWEAK_BAR_DEBUG // Only have to add the window, since each var widget is a child, directly or indirectly. widgets.pushBack(varWindow); } // Console/terminal window: { constexpr int maxLines = 1024; constexpr int bufferSize = 2048; auto con = new ntb::ConsoleWindowWidget{}; con->init(gui, nullptr, ntb::Rectangle{ 1550, 20, 2000, 420 }, true, true, "Console Window", 40, 28, 40, 25, maxLines, bufferSize); con->setTextScaling(1.3f); con->setButtonTextScaling(1.0f); ntb::SmallStr line; for (ntb::Int64 i = 0; i < 15; ++i) { line = "Test line "; line += ntb::SmallStr::fromNumber(i); con->pushLine(line.c_str(), line.getLength()); } con->onAdjustLayout(); // Update the scroll bar for lines out of view widgets.pushBack(con); } // To forward window input events to the widget list. ctx.setAppCallback(&ctx, &myAppEventCallback, &widgets); while (!done) { ctx.frameUpdate(&ctx, &done); geoBatch.beginDraw(); // Slider helper (not an actual widget, but used by some widgets): { static ntb::Float64 sliderPercent = 0.0; ntb::ValueSlider slider; slider.setRange(0, 100); slider.setCurrentValue(sliderPercent); slider.drawSelf(geoBatch, ntb::Rectangle{ 650, 350, 950, 400 }, ntb::packColor(255, 255, 255), ntb::packColor(255, 100, 0)); slider.drawSelf(geoBatch, ntb::Rectangle{ 650, 450, 950, 500 }, ntb::packColor(255, 255, 255), ntb::packColor(0, 200, 200)); sliderPercent += 0.2; if (sliderPercent > 100.0) { sliderPercent = 0.0; } } // Render our widgets: widgets.forEach<ntb::Widget *>( [](ntb::Widget * widget, ntb::GeometryBatch * batch) { widget->onDraw(*batch); return true; }, &geoBatch); geoBatch.endDraw(); ctx.framePresent(&ctx); } widgets.forEach<ntb::Widget *>( [](ntb::Widget * widget, void * /*unused*/) { delete widget; return true; }, nullptr); } ctx.shutdown(&ctx); ntb::shutdown(); // This will also free the GUI instance. }
int main(int argc, char *argv[]) { eCmdLineStatus_t status; int keepGoing = 1; Uint32 lastTick; Uint32 current; Uint32 elapsed; Uint32 counter = 0; //GLuint img, fid; int iw, ih, fw, fh; const texture_t *dlg; const texture_t *misc; flubSlice_t *slice; //flubSlice_t *sliceTest; font_t *fnt; int eventCount; int pos; int w; gfxMeshObj_t *mesh; gfxMeshObj_t *fontMesh; sound_t *sound; char cwdbuf[1024]; font_t *pfont; const texture_t *tex_misc; const texture_t *tex_dlg; const texture_t *tex_tiles; flubSlice_t *dlg_title; flubSlice_t *dlg_body; gfxMeshObj_t *meshFont; gfxMeshObj_t *meshChain; gfxMeshObj_t *meshDlg; gfxMeshObj_t *meshTiles; gfxMeshObj_t *meshMisc; gfxEffect_t *effect; int tileMap[127]; char *scene[3] = { "#######\n#UIIIO#\n#JKKKL#\n#WWWWW#\n#######\n#######\n#######", " \n \n \n w P \n F \nCCCCVCC\n ", " \n \n \n D \n \n \n ", }; tileMap['#'] = 0; tileMap['U'] = 23; tileMap['I'] = 7; tileMap['O'] = 24; tileMap['J'] = 21; tileMap['K'] = 5; tileMap['L'] = 22; tileMap['W'] = 16; tileMap['w'] = 32; tileMap['P'] = 36; tileMap['D'] = 37; tileMap['F'] = 33; tileMap['C'] = 34; tileMap['V'] = 19; flubSprite_t *sprites; //log_message = physfs_log; if(!appInit(argc, argv)) { return 1; } // Register command line params and config vars #if 0 infof("### Adding font ###################################"); if(!flubFontLoad("flub/font/times.12.stbfont")) { errorf("Unable to load times font."); } if(!flubFontLoad("flub/font/courier.12.stbfont")) { errorf("Unable to load courier font."); } #endif status = appStart(NULL); if(status != eCMDLINE_OK) { return ((status == eCMDLINE_EXIT_SUCCESS) ? 0 : 1); } //infof("Working dir: [%s]", getcwd(cwdbuf, sizeof(cwdbuf))); //enumDir(""); //enumDir("assets"); fnt = fontGet("consolas", 12, 0); if(fnt == NULL) { infof("Unable to get font"); return 1; } fpsFont = fnt; //fid = fontGetGLImage(fnt, &fw, &fh); //fid = fontGetGLTexture(fnt); //info("Font loaded, targeting images."); //infof("Working dir: [%s]", getcwd(cwdbuf, sizeof(cwdbuf))); misc = texmgrGet("flub-keycap-misc"); dlg = texmgrLoad( "work/dungeondlg2.gif", "dungeondlg2", GL_NEAREST, GL_NEAREST, 1, 255, 0, 255); //img = texmgrQuickLoad( "assets/misc/test_img.gif", GL_NEAREST, GL_NEAREST, 0, 0, 0, 0, &iw, &ih); footex = dlg; slice = gfxSliceCreate(dlg, 0, 0, 18, 22, 74, 69, 126, 106); //sliceTest = gfxSliceCreate(dlg, 145, 6, 150, 11, 182, 27, 186, 31); //infof("Texture id for flubmisc1 is %d", misc->id); //vboTestInit(misc->id); sound = audioSoundGet("resources/sounds/menumove.wav"); mesh = gfxMeshCreate(MESH_QUAD_SIZE(40), 0, misc); //infof("The mesh is 0x%p", mesh); gfxTexMeshBlit(mesh, misc, 20, 20); //gfxMeshBlit(mesh, 220, 20); //gfxMeshBlit(mesh, 420, 20); //gfxMeshBlit(mesh, 20, 220); //gfxMeshBlit(mesh, 220, 220); //gfxMeshBlit(mesh, 420, 220); //infof("Vertices: %d", mesh->pos); fontMesh = gfxMeshCreate(256 * 2, GFX_MESH_FLAG_COLOR, NULL); gfxMeshTextureAssign(fontMesh, fontTextureGet(fnt)); fontPos(150, 240); fontBlitCMesh(fontMesh, fnt, 'F'); fontBlitCMesh(fontMesh, fnt, 'o'); fontBlitCMesh(fontMesh, fnt, 'o'); fontPos(150, 260); fontBlitStrMesh(fontMesh, fnt, "fontBlitStrMesh();"); fontPos(150, 280); fontBlitStrNMesh(fontMesh, fnt, "fontBlitStrNMesh(); is too long", 19); fontPos(150, 300); fontBlitStrfMesh(fontMesh, fnt, "font%sStrf();", "Blit"); fontPos(150, 320); fontBlitQCStrMesh(fontMesh, fnt, "font^2Blit^1QC^wStr();"); fontPos(150, 340); fontBlitIntMesh(fontMesh, fnt, 12345); fontPos(150, 360); fontBlitFloatMesh(fontMesh, fnt, 12.345, 3); // Blitter test resources tex_misc = texmgrGet("flub-keycap-misc"); tex_dlg = texmgrGet("dungeondlg2"); tex_tiles = texmgrLoad( "work/tiletest.gif", "testtiles", GL_NEAREST, GL_NEAREST, 1, 255, 0, 255); sprites = gfxSpriteCreate(tex_tiles, 16, 16); dlg_title = gfxSliceCreate(tex_misc, 41, 17, 43, 19, 60, 26, 62, 28); dlg_body = gfxSliceCreate(tex_misc, 41, 29, 43, 30, 60, 40, 62, 42); // Create meshes for font, flubmisc, and flubsimplegui meshFont = gfxMeshCreate(MESH_QUAD_SIZE(100), GFX_MESH_FLAG_COLOR, fontTextureGet(fnt)); meshDlg = gfxMeshCreate(MESH_QUAD_SIZE(200), GFX_MESH_FLAG_COLOR, tex_dlg); meshTiles = gfxMeshCreate(MESH_QUAD_SIZE(400), 0, tex_tiles); meshMisc = gfxMeshCreate(MESH_QUAD_SIZE(400), GFX_MESH_FLAG_COLOR, tex_misc); meshChain = meshFont; gfxMeshAppendToChain(meshChain, meshMisc); gfxMeshAppendToChain(meshChain, meshDlg); gfxMeshAppendToChain(meshChain, meshTiles); // Excercise mesh blitters gfxTexMeshBlit(meshChain, tex_misc, 400, 5); gfxTexMeshBlitSub(meshChain, tex_dlg, 145, 6, 186, 31, 400, 200, 450, 250); gfxTexMeshTile(meshChain, tex_dlg, 150, 11, 180, 25, 400, 260, 500, 400); blitMeshSpriteMap(meshChain, sprites, 200, 20, tileMap, scene, 3); gfxSpriteMeshBlitResize(meshChain, sprites, 36, 0, 0, 63, 63); gfxSliceMeshBlit(meshChain, dlg_title, 200, 300, 320, 315); gfxSliceMeshBlit(meshChain, dlg_body, 200, 316, 320, 440); gfxKeycapMeshBlit(meshChain, fnt, "META_WINDOWS", 200, 260, NULL, NULL); gfxKeycapMeshBlit(meshChain, fnt, "Ctrl", 240, 260, NULL, NULL); gfxKeycapMeshBlit(meshChain, fnt, "PgDn", 280, 260, NULL, NULL); effectMesh = meshDlg; effectStart = meshDlg->pos; gfxSliceMeshBlit(meshDlg, slice, 10, 50, 150, 190); effectStop = meshDlg->pos; effect = gfxEffectFade(effectMesh, effectStart, effectStop, 0.0, 1.0, 2000); effect->completed = fadeinCompleted; gfxEffectRegister(effect); if((!flubFontLoad("pirulen.30.stbfont")) || ((pfont = fontGet("pirulen", 30, 0)) == NULL)) { fatal("Unable to load pirulen font"); return 0; } inputActionBind("KEY_BACKQUOTE", "showconsole"); //glBlendFunc(GL_ONE, GL_ZERO); //glDisable(GL_BLEND); //glEnable(GL_TEXTURE_2D); info("### Loading theme ###############"); flubGuiThemeLoad("assets/data/flub-basic.theme"); info("### Done loading theme ##########"); lastTick = SDL_GetTicks(); while (keepGoing) { current = SDL_GetTicks(); elapsed = current - lastTick; lastTick = current; counter += elapsed; if(counter >= 2500) { if(sound != NULL) { //Mix_PlayChannel(0, sound, 0); } counter -= 2500; } // Process every event SDL_Event ev; // wait no more than 15ms to avoid exceeding 67 fps //while (SDL_WaitEventTimeout(&ev, 15)) { eventCount = 0; while(inputPollEvent(&ev)) { eventCount++; switch (ev.type) { case SDL_QUIT: keepGoing = 0; break; case SDL_TEXTINPUT: break; case SDL_KEYUP: switch (ev.key.keysym.sym) { case SDLK_HOME: break; case SDLK_END: break; case SDLK_PAGEUP: break; case SDLK_PAGEDOWN: break; case SDLK_UP: case SDLK_e: break; case SDLK_DOWN: case SDLK_d: break; case SDLK_w: break; case SDLK_r: break; case SDLK_LEFT: case SDLK_s: break; case SDLK_RIGHT: case SDLK_f: break; case SDLK_ESCAPE: keepGoing = 0; break; case SDLK_BACKQUOTE: break; case SDLK_RETURN: break; } break; case SDL_KEYDOWN: switch (ev.key.keysym.sym) { case SDLK_HOME: videoScreenshot("screenshot"); break; case SDLK_END: break; case SDLK_PAGEUP: break; case SDLK_PAGEDOWN: break; case SDLK_UP: case SDLK_e: break; case SDLK_DOWN: case SDLK_d: break; case SDLK_w: break; case SDLK_r: break; case SDLK_LEFT: case SDLK_s: break; case SDLK_RIGHT: case SDLK_f: break; case SDLK_ESCAPE: keepGoing = 0; break; case SDLK_BACKQUOTE: /* if(consoleVisible()) { consoleShow(0); } else { consoleShow(1); } */ break; } break; case SDL_CONTROLLERBUTTONDOWN: break; case SDL_CONTROLLERBUTTONUP: break; case SDL_CONTROLLERAXISMOTION: break; } if(eventCount >= BULK_EVENT_LIMIT) { break; } } videoClear(); //glDisable(GL_DEPTH_TEST); //glDisable(GL_CULL_FACE); //glDisable(GL_BLEND); videoPushGLState(); videoOrthoMode(); glLoadIdentity(); glColor3f(1.0, 1.0, 1.0); //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //fontSetColor(1.0, 1.0, 1.0); //gfxBlitKeyStr(fnt, "Use [META_UP] and [META_DOWN] to select a menu option.", 10, 440, NULL, NULL); //gfxBlitKeyStr(fnt, "Use [~] to open the console.", 10, 460, NULL, NULL); glLoadIdentity(); //gfxTexTile(tex_dlg, 150, 11, 180, 25, 200, 260, 298, 400); //gfxTexBlit(tex_misc, 200, 5); //gfxTexBlitSub(tex_misc, 0, 0, 127, 127, 0, 5, 127, 132); //gfxMeshRender(fontMesh); //gfxSliceBlit(dlg_title, 200, 300, 320, 315); //gfxSliceBlit(dlg_body, 200, 316, 320, 440); //gfxSliceBlit(slice, 10, 50, 150, 190); glLoadIdentity(); //fontMode(); //fontPos(10, 200); //fontBlitStr(pfont, "This Is A Test! Werd, yo!"); //glLoadIdentity(); //gfxTexBlit(fontTextureGet(pfont), 10, 200); //videoPushGLState(); //videoOrthoMode(); //vboTestRender(); //gfxGLBlit(img, 380, 10, 380 + iw, 10 + ih); //fontSetColor(0.5, 1.0, 0.5); //fontSetColor(1.0, 1.0, 1.0); //gfxGLBlit(fid, 5, 5, fw, fh); //gfxTexBlit(misc, 25, 120); //gfxGLBlit(misc->id, 5, 100, 5 + misc->width, 100 + misc->height); gfxMeshRender(meshChain); //videoPopGLState(); if(!appUpdate(current)) { keepGoing = 0; } } gfxMeshDestroy(mesh); return 0; }
int main(int argc, char *argv[]) { font_t *font; const texture_t *texture; const texture_t *misc; flubSlice_t *dlg_body; flubSlice_t *dlg_title; eCmdLineStatus_t status; int keepGoing = 1; Uint32 lastTick; Uint32 current; Uint32 elapsed; SDL_Event ev; int eventCount; FILE *fp; eThemerState_t state = eThemerStateType; tsMenuState_t menuState; tsMenuEntry_t menuEntries[] = { {"Bitmap", eCompBitmap}, {"Animation", eCompAnimation}, {"Tile", eCompTile}, {"Slice", eCompSlice}, {NULL, 0}, }; int pos = 0; int curx = 0; int cury = 0; compState_t parentComp, *comp, *walk; flubSimpleEdit_t *edit; const char *path = "flub-theme.txt"; appCmdlineCtx_t appCtx = {.path = NULL}; if(!appInit(argc, argv)) { return 1; } // Register command line params and config vars if((status = appStart(&appCtx)) != eCMDLINE_OK) { return ((status == eCMDLINE_EXIT_SUCCESS) ? 0 : 1); } if(appCtx.path != NULL) { path = appCtx.path; } if((fp = fopen(path, "a+t")) == NULL) { errorf("Failed to open theme output file."); return 1; } else { infof("Opened output file \"%s\"", path); } if((font = fontGet("consolas", 12, 0)) == NULL) { infof("Unable to get font"); return 1; } texture = texmgrGet("flub-simple-gui"); misc = texmgrGet("flub-keycap-misc"); dlg_body = gfxSliceCreate(misc, 41, 29, 43, 30, 60, 40, 62, 42); dlg_title = gfxSliceCreate(misc, 41, 17, 43, 19, 60, 26, 62, 28); inputActionBind("KEY_BACKQUOTE", "showconsole"); tsMenuInit(&menuState, font, menuEntries, 310, 45); edit = flubSimpleEditCreate(font, 30, 310, 70); tsCompStateInit(&parentComp, texture, menuState.pos); comp = &parentComp; lastTick = SDL_GetTicks(); while (keepGoing) { current = SDL_GetTicks(); elapsed = current - lastTick; lastTick = current; tsCompAnimUpdate(comp, elapsed); eventCount = 0; while(inputPollEvent(&ev)) { eventCount++; if(ev.type == SDL_QUIT) { keepGoing = 0; break; } if(ev.type == SDL_KEYDOWN) { if(ev.key.keysym.sym == SDLK_ESCAPE) { state = eThemerStateConfirm; break; } else if(ev.key.keysym.sym == SDLK_HOME) { videoScreenshot("screenshot"); break; } } switch(state) { default: case eThemerStateType: if(tsMenuInput(&menuState, &ev)) { state = eThemerStatePoints; comp = tsCompStateClear(comp); curx = 0; cury = 0; tsCompStateInit(comp, texture, menuState.pos); } break; case eThemerStatePoints: if(ev.type == SDL_KEYDOWN) { switch (ev.key.keysym.sym) { case SDLK_END: flubSimpleEditSet(edit, "comp"); flubSimpleEditActive(edit, 1); state = eThemerStateName; break; case SDLK_INSERT: comp = tsCompStateAddFrame(comp); break; case SDLK_EQUALS: comp = tsCompFrameNext(comp); break; case SDLK_BACKSLASH: tsCompAnimToggle(comp); break; case SDLK_PAGEUP: if(ev.key.keysym.mod & KMOD_SHIFT) { tsCompAnimAdjust(comp, 10); } else { tsCompAnimAdjust(comp, 1); } break; case SDLK_PAGEDOWN: if(ev.key.keysym.mod & KMOD_SHIFT) { tsCompAnimAdjust(comp, -10); } else { tsCompAnimAdjust(comp, -1); } if(comp->delay < 0) { comp->delay = 0; } break; case SDLK_UP: tsCompPosUpdate(comp, 0, -1, ((ev.key.keysym.mod & KMOD_SHIFT) ? 1 : 0), ((ev.key.keysym.mod & KMOD_CTRL) ? 1 : 0), &curx, &cury); break; case SDLK_DOWN: tsCompPosUpdate(comp, 0, 1, ((ev.key.keysym.mod & KMOD_SHIFT) ? 1 : 0), ((ev.key.keysym.mod & KMOD_CTRL) ? 1 : 0), &curx, &cury); break; case SDLK_LEFT: tsCompPosUpdate(comp, -1, 0, ((ev.key.keysym.mod & KMOD_SHIFT) ? 1 : 0), ((ev.key.keysym.mod & KMOD_CTRL) ? 1 : 0), &curx, &cury); break; case SDLK_RIGHT: tsCompPosUpdate(comp, 1, 0, ((ev.key.keysym.mod & KMOD_SHIFT) ? 1 : 0), ((ev.key.keysym.mod & KMOD_CTRL) ? 1 : 0), &curx, &cury); break; case SDLK_RETURN: tsCompNextPoint(comp, &curx, &cury); break; } } break; case eThemerStateName: if(flubSimpleEditInput(edit, &ev)) { // Save the entry if(comp->type == eCompSlice) { fprintf(fp,"%s %d %d %d %d %d %d %d %d\n", edit->buf, comp->pos[0][0], comp->pos[0][1], comp->pos[1][0], comp->pos[1][1], comp->pos[2][0], comp->pos[2][1], comp->pos[3][0], comp->pos[3][1]); } else if(comp->type == eCompAnimation) { fprintf(fp, "%s %d %d ", edit->buf, (comp->pos[1][0] - comp->pos[0][0] + 1), (comp->pos[1][1] - comp->pos[0][1])); if(comp->parent == NULL) { walk = comp; } else { walk = comp->parent; } for(; walk != NULL; walk = walk->next) { fprintf(fp, "%d %d %d ", walk->pos[0][0], walk->pos[0][1], walk->delay); } } else { fprintf(fp,"%s %d %d %d %d\n", edit->buf, comp->pos[0][0], comp->pos[0][1], comp->pos[1][0], comp->pos[1][1]); } state = eThemerStateType; break; } break; case eThemerStateConfirm: if(ev.type == SDL_KEYDOWN) { switch (ev.key.keysym.sym) { case SDLK_END: keepGoing = 0; break; case SDLK_RETURN: state = eThemerStateType; break; } break; } break; } if(eventCount >= BULK_EVENT_LIMIT) { break; } } videoClear(); videoPushGLState(); videoOrthoMode(); glLoadIdentity(); glColor3f(1.0, 1.0, 1.0); // Title gfxSliceBlit(dlg_title, 0, 0, 639, 20); fontMode(); fontPos(5, 5); fontSetColor(0.0, 0.0, 0.0); fontBlitStr(font, "Flub Themer"); // Image glLoadIdentity(); drawTexture(texture, 10, 30); // State name fontMode(); fontSetColor(1.0, 1.0, 1.0); fontPos(300, 25); switch(state) { default: case eThemerStateType: fontBlitStr(font, "Select component type:"); tsMenuDraw(&menuState); break; case eThemerStatePoints: fontBlitStr(font, "Select points:"); drawFragment(texture, dlg_body, comp); drawCrosshair(misc, curx + 10, cury + 30); fontMode(); fontPos(5, 300); fontSetColor(1.0, 1.0, 1.0); fontBlitStrf(font, "X: %3d Y: %3d", curx, cury); tsCompPointInfo(comp, font, 310, 50); if((comp->type == eCompAnimation) && (((comp->parent != NULL) && (comp->parent->animGo)) || (comp->animGo))) { fontPos(310, 250); fontSetColor(1.0, 1.0, 1.0); fontBlitStrf(font, "Animating"); } break; case eThemerStateName: fontBlitStr(font, "Select component type:"); fontMode(); fontPos(310, 50); fontSetColor(1.0, 1.0, 1.0); fontBlitStr(font, "Enter component name"); flubSimpleEditDraw(edit); break; case eThemerStateConfirm: fontBlitStr(font, "Are you sure you want to quit?"); gfxBlitKeyStr(font, "Press [End] to exit, [Return] to continue.", 310, 50, NULL, NULL); break; } if(!appUpdate(current)) { keepGoing = 0; } } fclose(fp); return 0; }
/*************************************************************************//** *****************************************************************************/ static void APP_TaskHandler(void) { switch (appState) { case APP_STATE_INITIAL: { appInit(); } break; case APP_STATE_SEND: { appSendData(); } break; case APP_STATE_SENDING_DONE: { #if APP_ENDDEVICE appState = APP_STATE_PREPARE_TO_SLEEP; #else SYS_TimerStart(&appDataSendingTimer); appState = APP_STATE_WAIT_SEND_TIMER; #endif } break; case APP_STATE_PREPARE_TO_SLEEP: { if (!NWK_Busy()) { NWK_SleepReq(); appState = APP_STATE_SLEEP; } } break; case APP_STATE_SLEEP: { sm_sleep(APP_SENDING_INTERVAL/1000); appState = APP_STATE_WAKEUP; } break; case APP_STATE_WAKEUP: { NWK_WakeupReq(); LED_On(LED_NETWORK); appState = APP_STATE_SEND; } break; default: break; } #if APP_COORDINATOR if(sio2host_rx(rx_data,APP_RX_BUF_SIZE) > 0) { LED_Toggle(LED_BLINK); } #endif }
/******************************************************************//** * @brief Programm entrypoint * * @retval EXIT_FAILURE * @retval err_not_init **********************************************************************/ int main(int argc, char *argv[]) { memset(&equipAddr,0,sizeof(in_addr)); /// 1. Process command line arguments \b argc and \b argv[] in ::process_cmdLine errType ret=process_cmdLine(argc, argv); /// - if arguments parsing is unsuccessfull exiting from programm if (ret!=err_result_ok) return ret; /// 2. Check arguments: /// - check for missing one of exact argument if ((eq_udp_sending_port==0) || (eq_udp_listen_port==0) || (equipAddr.s_addr==0)) { printf("Пропущен один из обязательных параметров:\n"); printf( " -u - сокет для сервисного общения с верхней иерархией системы\n" ); printf( " -s - сокет для посылки сообщений на нижнюю иерархию системы\n"); printf( " -r - сокет для приёма сообщений от нижней иерархии системы\n"); printf( " -i - адрес подсистемы обслуживания нижней иерархии\n\n"); return err_not_init; } /// - check for equipment communication settings: /// - sending port need to be not equal to listen port values /// - sending or listen port neet to be not equal to client listen port if ((eq_udp_sending_port==eq_udp_listen_port) || (eq_udp_sending_port==wUdp) || (eq_udp_listen_port==wUdp)) { printf("Ошибка параметров введены совпадающие номера сокетов\n"); return err_not_init; } /// - check for sending port number or listening port number was far from client port number on one port number /// that reserved for client sending port. if ((eq_udp_sending_port==wUdp+1) || (eq_udp_listen_port==wUdp+1)) { printf("Ошибка параметров: номер сокета оборудования взят из уже занятого пространства\n"); return err_not_init; } commonFuncsMgr *cf; specFuncsMgr *sf; /// 3. Install system signals handlers ::installSIGhandlers() installSIGhandlers(appDeinit); app=new srvAppLayer(wUdp); /// 4. Initialize application ::appInit() if (appInit()!=err_result_ok) AppTerminated=true; else { cf=new commonFuncsMgr(app); sf=new specFuncsMgr(app); ///4. Start functions generate from declarations ///- for common functions commonFuncsMgr::startCommonFuncs() cf->startCommonFuncs(); ///- for special functions specFuncsMgr::startSpecFuncs() sf->startSpecFuncs(); /// 5. Main programm loop srvAppLayer::ProcessMessages() while not terminated by signal srvAppLayer::terminated() while(!app->terminated()) { app->ProcessMessages(); } /// 6. Deinitialize application ::appDeinit() appDeinit(); if (app->terminated()==2) reboot(RB_AUTOBOOT); delete app; } printf("Работа программного средства завершена\n\n"); return (EXIT_FAILURE); }
int main(const int argc, const char * argv[]) { AppContext ctx; if (!appInit(argc, argv, "NTB GeometryBatch Tests", 1024, 768, &ctx)) { std::fprintf(stderr, "[APP_ERROR]: Failed to initialize sample app!\n"); return EXIT_FAILURE; } ntb::initialize(ctx.shellInterface, ctx.renderInterface); { bool done = false; ntb::GeometryBatch geoBatch; ntb::TextureHandle sampleTex = ctx.renderInterface->createCheckerboardTexture(64, 64, 4); ntb::PODArray scrProjectedVerts{ sizeof(ntb::VertexPTC) }; ntb::PODArray scrProjectedIndexes{ sizeof(ntb::UInt16) }; ntb::Float32 rotationDegreesX = 0.0f; ntb::Float32 rotationDegreesZ = 0.0f; ntb::Mat4x4 modelToWorldMatrix; modelToWorldMatrix.setIdentity(); while (!done) { ctx.frameUpdate(&ctx, &done); geoBatch.beginDraw(); // // Draw a textured quad without batching: // const ntb::Float32 batchZ = geoBatch.getNextZ(); const ntb::UInt16 indexes[] = { 0, 1, 2, 2, 3, 0 }; const ntb::VertexPTC verts[] = { { 10, 10, batchZ, 0.0f, 0.0f, ntb::packColor(255, 0, 0) }, { 10, 200, batchZ, 0.0f, 1.0f, ntb::packColor(0, 255, 0) }, { 200, 200, batchZ, 1.0f, 1.0f, ntb::packColor(0, 0, 255) }, { 200, 10, batchZ, 0.0f, 1.0f, ntb::packColor(255, 255, 255) } }; ctx.renderInterface->draw2DTriangles(verts, ntb::lengthOfArray(verts), indexes, ntb::lengthOfArray(indexes), sampleTex, ctx.renderInterface->getMaxZ()); // // Now add some items to the GeometryBatch: // // Simple rectangles: geoBatch.drawRectOutline(ntb::Rectangle{ 10, 250, 210, 450 }, ntb::packColor(255, 0, 0)); geoBatch.drawRectFilled(ntb::Rectangle{ 10, 500, 210, 700 }, ntb::packColor(0, 255, 0)); // Simple text string with a background box and outline: const char * hello = "Hello World!"; const int helloLength = ntb::lengthOfString(hello); ntb::Rectangle textAlignBox{ 10, 850, 500, 950 }; geoBatch.drawRectOutline(textAlignBox, ntb::packColor(255, 255, 0)); geoBatch.drawRectFilled(textAlignBox.shrunk(10, 10), ntb::packColor(128, 200, 0)); textAlignBox.moveBy(0, 25); geoBatch.drawTextConstrained(hello, helloLength, textAlignBox, textAlignBox, 2.0f, ntb::packColor(255, 255, 255), ntb::TextAlign::Center); // Block with all available characters in the built-in font: static const char allChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n" "abcdefghijklmnopqrstuvwxyz\n" "1234567890\n" "\"!`?\'.,;:()[]{}<>|/@\\^$-%+=#_&~*\n" "¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»\n" "¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙ\n" "ÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷\n" "øùúûüýþÿ\n"; const int allCharsLength = ntb::lengthOfString(allChars); textAlignBox = ntb::Rectangle{ 550, 50, 1500, 1000 }; // Large block of text: geoBatch.drawTextConstrained(allChars, allCharsLength, textAlignBox, textAlignBox, 2.0f, ntb::packColor(255, 255, 255), ntb::TextAlign::Center); // Small block of text: geoBatch.drawTextConstrained(allChars, allCharsLength, textAlignBox.moveBy(0, 600), textAlignBox.moveBy(0, 600), 1.0f, ntb::packColor(0, 200, 200), ntb::TextAlign::Center); // Text outline box: textAlignBox = ntb::Rectangle{ 550, 50, 1500, 1000 }; geoBatch.drawRectOutline(textAlignBox.moveBy(0, -25), ntb::packColor(255, 255, 0)); // Some screen-projected 3D geometry: ntb::Rectangle clipViewport; clipViewport.xMins = textAlignBox.xMins + 20; clipViewport.yMins = textAlignBox.yMaxs + 30; clipViewport.xMaxs = clipViewport.xMins + 500; clipViewport.yMaxs = clipViewport.yMins + 500; const ntb::Mat4x4 projMatrix = ntb::Mat4x4::perspective(ntb::degToRad(60.0f), clipViewport.getAspect(), 0.5f, 100.0f); const ntb::Mat4x4 viewMatrix = ntb::Mat4x4::lookAt(ntb::Vec3{ 0.0f, 0.0f, +1.0f }, ntb::Vec3{ 0.0f, 0.0f, -1.0f }, ntb::Vec3{ 0.0f, 1.0f, 0.0f }); const ntb::Mat4x4 viewProjMatrix = ntb::Mat4x4::multiply(viewMatrix, projMatrix); scrProjectedVerts.clear(); scrProjectedIndexes.clear(); makeScreenProjectedBox(&scrProjectedVerts, &scrProjectedIndexes, modelToWorldMatrix, viewProjMatrix); // Rotate it: rotationDegreesX = ntb::normalizeAngle360(rotationDegreesX + 0.07f); rotationDegreesZ = ntb::normalizeAngle360(rotationDegreesZ + 0.07f); const ntb::Mat4x4 matRx = ntb::Mat4x4::rotationX(ntb::degToRad(rotationDegreesX)); const ntb::Mat4x4 matRz = ntb::Mat4x4::rotationZ(ntb::degToRad(rotationDegreesZ)); modelToWorldMatrix = ntb::Mat4x4::multiply(matRz, matRx); geoBatch.drawRectFilled(clipViewport, ntb::packColor(200, 200, 200)); geoBatch.drawClipped2DTriangles(scrProjectedVerts.getData<ntb::VertexPTC>(), scrProjectedVerts.getSize(), scrProjectedIndexes.getData<ntb::UInt16>(), scrProjectedIndexes.getSize(), clipViewport, clipViewport); geoBatch.drawRectOutline(clipViewport.expanded(10, 10), ntb::packColor(255, 0, 0)); // Finally, test some overlapping draws to make sure depth testing is working as expected. ntb::Rectangle box = ntb::Rectangle{ 1200, 1000, 1400, 1200 }; geoBatch.drawRectFilled(box, ntb::packColor(255, 0, 0)); geoBatch.drawRectFilled(box.moveBy(40, 40), ntb::packColor(0, 255, 0)); geoBatch.drawRectFilled(box.moveBy(40, 40), ntb::packColor(0, 0, 255)); geoBatch.drawRectFilled(box.moveBy(40, 40), ntb::packColor(255, 255, 255)); geoBatch.drawRectOutline(box.shrunk(50, 50), ntb::packColor(0, 0, 0)); geoBatch.drawArrowFilled(box.shrunk(80, 80), ntb::packColor(0, 200, 0), ntb::packColor(0, 0, 0), 1); geoBatch.endDraw(); ctx.framePresent(&ctx); } } ctx.shutdown(&ctx); ntb::shutdown(); }