int main(int argc, char*argv[]) { // ████████ INITS 1 ████████ #ifndef COMMON_INITS1 cfg.init("bedlab.cfg"); ui2::init_ui(); Vec2i windowsize; Vec2i screen_resolution = { int(VideoMode::getDesktopMode().width), int(VideoMode::getDesktopMode().height) }; if (cfg.getvar<int>("auto_winsize")) { auto window_scale = cfg.getvar<Vec2>("window_scale"); windowsize = Vec2i(scal(Vec2(screen_resolution), window_scale)); } else { windowsize = cfg.getvar<Vec2i>("windowsize"); } winsize = Vec2(windowsize); //UI.init_console(); // ALWAYS AFTER SO IT CAN GET WINDOW SIZE ui2::init_console(); // ALWAYS AFTER SO IT CAN GET WINDOW SIZE wincenter = 0.5f*Vec2(windowsize); Vec2i windowpos; VideoMode::getDesktopMode().height; if (cfg.getvar<int>("stick_left")) { windowpos = Vec2i( screen_resolution.x - windowsize.x - 10, screen_resolution.y - windowsize.y - 40 ); } else windowpos = (Vec2i(5, 25)); sf::RenderWindow window(sf::VideoMode(windowsize.x, windowsize.y), "bedlab!", 7 //,sf::ContextSettings(0, 0, 1) ); window.setFramerateLimit(cfg.getvar<int>("fps_max")); frame_duration = 1.0f / cfg.getvar<int>("fps_max"); window.setPosition(windowpos); vector<string> keys; auto choice = cfg.getstr("app"); // show_keys(cfg.getstr("app"), keys); #endif // ████████ INITS2 ████████ #ifndef COMMON_INITS2 // we don't have a class/interface/struct with data, everything is local to this function, like a classic stack that all programs are anyway. // Texture cursor_tx; // if (!cursor_tx.loadFromFile(cfg.getstr("cursor"))) // cout << "did not load cursor" << endl; // Sprite cursor; // cursor.setTexture(cursor_tx); // cursor.setOrigin(3, 3); CircleShape cursor = mkcircle({ 0,0 }, Color::Transparent, 3, 1); Color background = cfg.getvar<Color>("background"); window.setMouseCursorVisible(false); Vec2 mpos; bool leftclicked = false, rightclicked = false; // view and zoom View view, ui_view; ui_view = view = window.getDefaultView(); float zoomlevel = 1; Vec2 mpos_abs; float frame_duration = 1.0f / cfg.getvar<int>("fps_max"); #endif // COMMON_INITS2 // ████████ APP ACTUAL ████████ float smaller_size = min(windowsize.y, windowsize.x); string descriptor; Transform transf; transf.translate(10, 10); transf.scale(Vec2(smaller_size, smaller_size)); transf_glob = transf; auto addvt_col = [&](Vec2 v, Color col) { glob_vert_single.append(Vertex(transf.transformPoint(v), col)); }; auto va_to_va_col = [&](mesh2d&idxd_v, Color col) { for (unsigned int i = 0; i < idxd_v.size(); ++i) { // if (i<) addvt_col(idxd_v[i].first, col); addvt_col(idxd_v[i].second, col); //addpt(idxd_v[i].first, Orange, 5); //addpt(idxd_v[i].second, Cyan, 5); } for (auto&a : idxd_v.verts) { addpt_col(a, col, 2); } }; auto stripify = [&](vector<Vec2> strip, Color col) { glob_vert_single = VertexArray(LineStrip); for (auto&a : strip) { glob_vert_single.append(Vertex(transf.transformPoint(a), col)); addpt_col(a, col, 2); } }; size_t edit_mode = 1; // ████████████████████████████████████████ sf::Sound sound; auto make_segment = [](int size, int amplitude) { vector<Int16> sample; for (int i = 0; i < size; ++i) { sample.push_back(amplitude*sin(float(i)*PI*2.0f)); } return sample; }; /* <Jonny> duration will be sample count * sample rate <Jonny> so at 44khz you'll have 44k samples per second <Jonny> if you have 88k samples that will last 2 second */ plot_bare pl; float sample_rate = 22050; auto make_tone = [&](float duration, float frequency, int amplitude_exp) { float sample_quantity = sample_rate * duration; vector<Int16> sample; int amplitude = 1 << amplitude_exp; float increment = frequency / sample_rate; float x = 0; for (int i = 0; i < sample_quantity; ++i){ sample.push_back(amplitude*sin(float(x)*PI*2.0f)); x += increment; } return sample; }; // http://sol.gfxile.net/interpolation/ auto make_tone_progressive_2 = [&](float duration, float frequency, int amplitude_exp) { float sample_quantity = sample_rate * duration; vector<Int16> sample; int amplitude = 1 << amplitude_exp; float increment = frequency / sample_rate; float x = 0; for (int i = 0; i < sample_quantity; ++i) { float soft = float(i) / sample_quantity; //soft = 1 - (1 - 2 * soft)*(1 - 2 * soft)*(1 - 2 * soft)*(1 - 2 * soft); soft = 1 - (1 - 2 * soft)*(1 - 2 * soft); soft *= amplitude; sample.push_back(soft*sin(float(x)*PI*2.0f)); x += increment; } return sample; }; auto make_tone_progressive_4 = [&](float duration, float frequency, int amplitude_exp) { float sample_quantity = sample_rate * duration; vector<Int16> sample; int amplitude = 1 << amplitude_exp; float increment = frequency / sample_rate; float x = 0; for (int i = 0; i < sample_quantity; ++i) { float soft = float(i) / sample_quantity; soft = 1 - (1 - 2 * soft)*(1 - 2 * soft)*(1 - 2 * soft)*(1 - 2 * soft); soft *= amplitude; sample.push_back(soft*sin(float(x)*PI*2.0f)); x += increment; } return sample; }; auto make_tone_progressive_6 = [&](float duration, float frequency, int amplitude_exp) { float sample_quantity = sample_rate * duration; vector<Int16> sample; int amplitude = 1 << amplitude_exp; float increment = frequency / sample_rate; float x = 0; for (int i = 0; i < sample_quantity; ++i) { float soft = float(i) / sample_quantity; soft = 1 - (1 - 2 * soft)*(1 - 2 * soft)*(1 - 2 * soft)*(1 - 2 * soft)*(1 - 2 * soft)*(1 - 2 * soft); soft *= amplitude; sample.push_back(soft*sin(float(x)*PI*2.0f)); x += increment; } return sample; }; auto sample_string2 = cfg.getstr("sound1"); auto spl1 = splitdelim(sample_string2, ','); auto params2 = splitdelim(spl1[0]); //float freq = parse<float>(params[1]); //float duration = parse<float>(params[2]); //float amplitude_exp = parse<float>(params[3]); float freq, duration, amplitude_exp, pause; int times, smoothstep_exp; dip_bars dbars(FONT, FONTSIZE, {400,20}); //dbars.add("sampling", &sampling,5, 10000); dbars.add("sample_rate", &sample_rate, 1000, 45000); dbars.add("freq", &freq,50,5000); dbars.add("duration", &duration, 0.5, 5); dbars.add("amplitude_exp", &litude_exp, 1, 14); SoundBuffer buffer; // always lived! auto load_sample2 = [&](){ auto delaystr = splitdelim(spl1[1]); vector<float> segment_sizes; float total = 0; for (auto&a : delaystr) { total += parse<float>(a); segment_sizes.push_back(parse<float>(a)); } int i = 0; vector<Int16> sample; vector<vector<Int16>> samples; for (auto&a : segment_sizes) a /= total; //for (auto&a : segment_sizes) msg(a*total); for (auto&a : segment_sizes){ auto scaled_back = duration * freq * a; int amplitude = i % 2 ? 0 : 1 << int(amplitude_exp); msg(scaled_back); samples.push_back(make_segment(scaled_back, amplitude)); ++i; } for (auto&a : samples){ concatenate(sample, a); } SoundBuffer buffer; // \param sampleRate Sample rate (number of samples to play per second) buffer.loadFromSamples(&sample[0], sample.size(), 1, sample.size()/duration); { // plut josting just plotting vector<Vec2> plot_this; int i = 0; for (auto&a : sample) { //plot_this.push_back({ float(i), 200 * float(a) / (1 << 12) }); plot_this.push_back({ float(i), float(a) }); i++; } pl.clear(); pl.from_data_normalized(plot_this); } return buffer; }; auto load_sample = [&]() { auto delaystr = splitdelim(spl1[1]); vector<float> segment_sizes; float total = 0; for (auto&a : delaystr) { total += parse<float>(a); segment_sizes.push_back(parse<float>(a)); } int i = 0; vector<Int16> sample; vector<vector<Int16>> samples; for (auto&a : segment_sizes) a /= total; //for (auto&a : segment_sizes) msg(a*total); if (smoothstep_exp == 2) { for (auto&a : segment_sizes) { samples.push_back(make_tone_progressive_2(duration*a, freq, i % 2 ? 0 : int(amplitude_exp))); ++i; } } else if (smoothstep_exp == 4){ for (auto&a : segment_sizes) { samples.push_back(make_tone_progressive_4(duration*a, freq, i % 2 ? 0 : int(amplitude_exp))); ++i; } } for (auto&a : samples) { concatenate(sample, a); } SoundBuffer buffer; // \param sampleRate Sample rate (number of samples to play per second) //sample = make_tone(2, 400, 8); //buffer.loadFromSamples(&sample[0], sample.size(), 1, sample.size() / duration); buffer.loadFromSamples(&sample[0], sample.size(), 1, sample.size() / duration); if (true) { // plut josting just plotting vector<Vec2> plot_this; int i = 0; for (auto&a : sample) { //plot_this.push_back({ float(i), 200 * float(a) / (1 << 12) }); plot_this.push_back({ float(i), float(a) }); i++; } pl.clear(); pl.from_data_normalized(plot_this); } return buffer; }; auto load_from_cfg = [ &freq, &duration, &litude_exp, &pause, ×, &descriptor, &smoothstep_exp]() { auto temp_cfg = configfile(); temp_cfg.init("bedlab.cfg"); auto sample_string = temp_cfg.getstr("sound2"); auto things = split2(sample_string, ","); auto params = split2(things[0], " "); auto segments = split2(things[1], " "); string segments_dashed = things[1]; if (segments_dashed[0] == ' ') segments_dashed = segments_dashed.substr(1); if (things[1][0] == ' ') things[1] = things[1].substr(1); if (things[2][0] == ' ') things[2] = things[2].substr(1); if (things[3][0] == ' ') things[3] = things[3].substr(1); if (things[4][0] == ' ') things[4] = things[4].substr(1); for (auto&c : segments_dashed) { if (c == ' ') c = '-'; } freq = parse<float>(params[0]); duration = parse<float>(params[1]); amplitude_exp = parse<float>(params[2]); pause = parse<float>(things[2]); times = parse<int>(things[3]); smoothstep_exp = parse<int>(things[4]); msgs(smoothstep_exp); descriptor = params[0] // freq + "_" + params[1] // duration + "_" + params[2] // amplitude_exp + "_" + segments_dashed + "_" + things[2] // pause + "_" + things[3] // times + "_" + things[4] // smoothstep_exp ; msgs(descriptor); return segments; }; auto segments = load_from_cfg(); auto flexible_expanse = [&]() { vector<float> segment_sizes, segment_concat; for (auto&a : segments) { segment_sizes.push_back(parse<float>(a)); } segment_sizes.push_back(pause); for (int i = 0; i < times; ++i) { concatenate(segment_concat, segment_sizes); } float total = 0; for (auto&a : segment_concat) total+=a; for (auto&a : segment_concat) a /= total; vector<vector<Int16>> samples; int i = 0; if (smoothstep_exp == 2) { for (auto&a : segment_concat) { samples.push_back(make_tone_progressive_2(duration*a, freq, i % 2 ? 0 : int(amplitude_exp))); ++i; } } else if (smoothstep_exp == 4) { for (auto&a : segment_concat) { samples.push_back(make_tone_progressive_4(duration*a, freq, i % 2 ? 0 : int(amplitude_exp))); ++i; } } else if (smoothstep_exp == 6) { for (auto&a : segment_concat) { samples.push_back(make_tone_progressive_6(duration*a, freq, i % 2 ? 0 : int(amplitude_exp))); ++i; } } vector<Int16> sample; for (auto&a : samples) { concatenate(sample, a); } SoundBuffer buffer; //buffer.loadFromSamples(&sample[0], sample.size(), 1, sample.size() / duration); buffer.loadFromSamples(&sample[0], sample.size(), 1, sample_rate); if (true) { // plut josting just plotting vector<Vec2> plot_this; int i = 0; for (auto&a : sample) { //plot_this.push_back({ float(i), 200 * float(a) / (1 << 12) }); plot_this.push_back({ float(i), float(a) }); i++; } pl.clear(); pl.from_data_normalized(plot_this); } return buffer; }; //buffer = load_sample(sample_string); auto make_sound = [&]() { //buffer = load_sample(); segments = load_from_cfg(); buffer = flexible_expanse(); sound.setBuffer(buffer); string filename = "rngtn_" + descriptor+".wav"; //buffer.saveToFile("file.wav"); buffer.saveToFile(filename); sound.play(); }; make_sound(); dbars.read_from_pointers(); // ████████ callbacks ████████ #ifndef LOOP_LAMBDAS draw = [&]() { window.setView(view); //////////////// OBJECTS THAT CAN ZOOMED //////////////// window.draw(glob_vert_single); for (auto&a : glob_pts)window.draw(a); for (auto&a : glob_rects)window.draw(a); for (auto&a : glob_vert)window.draw(a); for (auto&a : glob_texts)window.draw(a); // UI draw, AFTER ui view and BEFORE other draw window.setView(ui_view); //////////////// OBJECTS THAT CANNOT ZOOMED, MEANING UI //////////////// pl.draw(window); dbars.draw(window); //br.drawwithtext(window); UI.draw(window); window.draw(cursor); }; update = [&]() { }; treatkeyevent = [&](Keyboard::Key k) { switch (k) { case Keyboard::E: break; case Keyboard::I: break; case Keyboard::Q: break; case Keyboard::BackSpace: glob_pts.clear(); glob_texts.clear(); glob_rects.clear(); glob_vert.clear(); break; case Keyboard::Space: make_sound(); sound.play(); sound.setLoop(false); break; case Keyboard::S: screenshot(window); break; case Keyboard::Num1: case Keyboard::Num2: case Keyboard::Num3: case Keyboard::Num4: case Keyboard::Num5: break; } }; mousemoved = [&](Vec2 pos) { cursor.setPosition(pos); if (leftclicked); dbars.mouse_moved(pos); }; mouseclick = [&](sf::Mouse::Button button) { if (button == Mouse::Button::Left) leftclicked = true; if (button == Mouse::Button::Right) rightclicked = true; if (button == Mouse::Button::Left) dbars.mouse_click(mpos); }; mouserelease = [&](sf::Mouse::Button button) { if (button == Mouse::Button::Left) leftclicked = false; if (button == Mouse::Button::Right) rightclicked = false; if (button == Mouse::Button::Left) { dbars.mouse_release(); make_sound(); } }; loop = [&]() { while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { switch (event.type) { case sf::Event::KeyPressed: if (event.key.code == sf::Keyboard::Escape) window.close(); treatkeyevent(event.key.code); break; case sf::Event::Closed: window.close(); break; case sf::Event::MouseButtonPressed: mouseclick(event.mouseButton.button); break; case sf::Event::MouseButtonReleased: mouserelease(event.mouseButton.button); break; case sf::Event::MouseMoved: mpos = Vec2(event.mouseMove.x, event.mouseMove.y); mpos_abs = window.mapPixelToCoords(Vec2i(mpos), view); mousemoved(mpos); break; default: treatotherevent(event); break; } } window.clear(background); update(); draw(); window.display(); } }; treatotherevent = [&](Event&e) { if (e.type == Event::MouseWheelMoved && e.mouseWheel.delta) { mpos_abs = window.mapPixelToCoords(Vec2i(mpos), view); //view = window.getView(); if (e.mouseWheel.delta < 0) { zoomlevel *= 2.f; view.setSize(view.getSize()*2.f); view.setCenter(interp(mpos_abs, view.getCenter(), 2.f)); //view.setCenter(interp(mpos_abs, view.getCenter(), 2.f)); } if (e.mouseWheel.delta > 0) { zoomlevel *= 0.5; view.setSize(view.getSize()*.5f); view.setCenter(.5f*(view.getCenter() + mpos_abs)); //view.setCenter(.5f*(view.getCenter() + mpos_abs)); } window.setView(view); } }; #endif // LOOP_LAMBDAS loop(); }
//map<color, Color> colors = { // { Black, Color::Black }, // { White, Color::White }, // { Red, Color::Red }, // { Green, Color::Green }, // { Blue, Color::Blue }, // { Yellow, Color::Yellow }, // { Magenta, Color::Magenta }, // { Cyan, Color::Cyan }, // { Transparent, Color::Transparent }, // { Orange, Color(255, 128, 0) } //}; ////////////////////////// this returns a lambda ////////////////////////// function<void()> ////////////////////////// TYPE APP NAME ON LINE BELOW ////////////////////////// mine_solver (RenderWindow&window, ui &UI) { return [&window, &UI]() { #ifndef COMMON_INITS //void smoothmouse(RenderWindow&window, ui &UI){ // tidy code organization, here we predeclare methods just like a header would, it's redundant but necessary function<void()> draw, loop, init, update; function<void(Vec2 pos)> mousemoved; function<void(sf::Mouse::Button button)> mouseclick, mouserelease; function<void(Event&e)> treatotherevent; function<void(Keyboard::Key k)> treatkeyevent; // we don't have a class/interface/struct with data, everything is local to this function, like a classic stack that all programs are anyway. Texture cursor_tx; Sprite cursor; configfile cfg; cfg.init("bedlab.cfg"); Color background = cfg.getvar<Color>("background"); if (!cursor_tx.loadFromFile(cfg.getstr("cursor"))) cout << "did not load cursor" << endl; cursor.setTexture(cursor_tx); cursor.setOrigin(3, 3); window.setMouseCursorVisible(false); Vec2 mpos; bool leftclicked = false, rightclicked = false; // view and zoom View view, ui_view; ui_view = view = window.getDefaultView(); float zoomlevel = 1; Vec2 mpos_abs; #endif // COMMON_INITS // ************************ CODE BEGIN ************************ barstack bst(FONT, FONTSIZE); slider_finder sl; randgenfloat cell_rnd(0, 16); //grd. vector<string> mines_str = { " ", " 21114X411 ", " 3X22XX212 ", " X3--4433X ", " 23--4XX3X ", " 1X4---433 ", " 12X4--4X2 ", " 123X3XX3X ", " 2X2122221 ", " " }; int w = mines_str[0].length(); int h = mines_str.size(); vector<int> mine_states(h*w); grid grd; grd.screen_init(Vec2u(window.getSize()), Vec2u( w,h ), true); /* 1-8: surrounding mines 0 no mine, "clear" -1: unknown -2 mine */ map<char, int> lookup = { { '-',-1 }, { 'X',-2 }, { ' ',0 } }; int i = 0; logfile lg("minelog.txt"); lg.logw(to_str("i", "j", "index", "value")); for (auto&a : mines_str) { int j = 0; for (auto&b : a) { int value = -10; //value = // lookup.count(b) ? // lookup[b] // : (b > '0' || b <= '9') ? // int(b - '0') // : value; //msg(value); if (lookup.count(b)) value = lookup[b]; else if (b > '0' || b <= '9')value = int(b - '0'); int index = getat(j, i, w); mine_states[index] = value; //msgm(i,j,index, value); lg.logw(to_str(i,j,index, value)); ++j; } ++i; } map<int, Color> mine_colors = { { -2,Color::Red }, { -1,Color::Cyan }, { 0,Color::Black } }; msg(mine_states); i = 0; for (auto&a : mine_states) { if(a > 0) grd.texts[i].setString(to_str(a)); else grd.cells[i].setFillColor(mine_colors[a]); //grd.texts2[i].setString(to_str(i)); //grd.texts3[i].setString(to_str(getat(i,w))); ++i; } auto analyse = [&mine_states, w, h, &grd]() { vector<Vec2i> offsets = { { -1,-1 }, { 1,-1 }, { -1,1 }, { 1,1 }, { 0,-1 }, { -1,0 }, { 0,1 }, { 1,0 } }; int i = 0; for (auto&a : mine_states) { auto pos = getat(i, w); int unknown = 0, is_mine = 0; for (auto&off : offsets) { auto cell = pos + off; int cell_index = getat(cell,w); if (cell_index < 0 || cell_index >= mine_states.size() || cell.x < 0 || cell.x > w) continue; switch (mine_states[cell_index]) { case -1: ++is_mine; break; //unknown case -2: ++unknown; break; //mine } } int mine_left = a - is_mine; float prob = mine_left / unknown; ++i; } }; auto nearest_pt = mkcircle({ 0, 0 }, Color::Transparent, 10); nearest_pt.setOutlineThickness(2); // ************************ INITS END ********************** //then we actually define the functions, note how all function captures the local context by reference #ifndef LOOP_LAMBDAS draw = [&]() { window.setView(view); // object draw, AFTER normal view //////////////// obj draw START //////////////// for (auto&a : glob_pts)window.draw(a); for (auto&a : glob_rects)window.draw(a); for (auto&a : glob_vert)window.draw(a); for (auto&a : glob_texts)window.draw(a); window.draw(nearest_pt); grd.draw(window); //////////////// obj draw END //////////////// // UI draw, AFTER ui view and BEFORE other draw window.setView(ui_view); bst.draw(window); // nothing after here please UI.draw(window); window.draw(cursor); }; update = [&]() { }; treatkeyevent = [&](Keyboard::Key k) { switch (k) { case Keyboard::BackSpace: glob_pts.clear(); glob_texts.clear(); glob_rects.clear(); glob_vert.clear(); break; case Keyboard::Space: break; case Keyboard::Q: break; } }; mousemoved = [&](Vec2 pos) { cursor.setPosition(pos); if (leftclicked) sl.mouse_callback(pos); }; mouseclick = [&](sf::Mouse::Button button) { if (button == Mouse::Button::Left) leftclicked = true; if (button == Mouse::Button::Right) rightclicked = true; }; mouserelease = [&](sf::Mouse::Button button) { if (button == Mouse::Button::Left) leftclicked = false; if (button == Mouse::Button::Right) rightclicked = false; sl.release(); }; loop = [&]() { while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { switch (event.type) { case sf::Event::KeyPressed: if (event.key.code == sf::Keyboard::Escape) window.close(); treatkeyevent(event.key.code); break; case sf::Event::Closed: window.close(); break; case sf::Event::MouseButtonPressed: mouseclick(event.mouseButton.button); break; case sf::Event::MouseButtonReleased: mouserelease(event.mouseButton.button); break; case sf::Event::MouseMoved: mpos = Vec2(event.mouseMove.x, event.mouseMove.y); mousemoved(mpos); break; default: treatotherevent(event); break; } } window.clear(background); update(); draw(); window.display(); } }; treatotherevent = [&](Event&e) { if (e.type == Event::MouseWheelMoved && e.mouseWheel.delta) { mpos_abs = window.mapPixelToCoords(Vec2i(mpos), view); //view = window.getView(); if (e.mouseWheel.delta < 0) { zoomlevel *= 2.f; view.setSize(view.getSize()*2.f); view.setCenter(interp(mpos_abs, view.getCenter(), 2.f)); //view.setCenter(interp(mpos_abs, view.getCenter(), 2.f)); } if (e.mouseWheel.delta > 0) { zoomlevel *= 0.5; view.setSize(view.getSize()*.5f); view.setCenter(.5f*(view.getCenter() + mpos_abs)); //view.setCenter(.5f*(view.getCenter() + mpos_abs)); } window.setView(view); } }; loop(); #endif // LOOP_LAMBDAS }; }
function<void()> ////////////////////////// TYPE APP NAME ON LINE BELOW ////////////////////////// delaun_distr (RenderWindow&window, ui &UI) { return [&window, &UI]() { #ifndef COMMON_INITS //void smoothmouse(RenderWindow&window, ui &UI){ // tidy code organization, here we predeclare methods just like a header would, it's redundant but necessary function<void()> draw, loop, init, update; function<void(Vec2 pos)> mousemoved; function<void(sf::Mouse::Button button)> mouseclick, mouserelease; function<void(Event&e)> treatotherevent; function<void(Keyboard::Key k)> treatkeyevent; // we don't have a class/interface/struct with data, everything is local to this function, like a classic stack that all programs are anyway. Texture cursor_tx; Sprite cursor; configfile cfg; cfg.init("bedlab.cfg"); Color background = cfg.getvar<Color>("background"); if (!cursor_tx.loadFromFile(cfg.getstr("cursor"))) cout << "did not load cursor" << endl; cursor.setTexture(cursor_tx); cursor.setOrigin(3, 3); window.setMouseCursorVisible(false); Vec2 mpos; bool leftclicked = false, rightclicked = false; // view and zoom View view, ui_view; ui_view = view = window.getDefaultView(); float zoomlevel = 1; Vec2 mpos_abs; #endif // COMMON_INITS // ************************ CODE BEGIN ************************ auto random_graph = [](int pick_count, float distrib_radius) { vector<pair<int,Vec2>> points; vector<pair<int, int>> graph; //float distrib_radius;// = cfg.getvar<float>("distrib_radius"); paused_distr paus_distr(distrib_radius, 5, 321); //int winheight = cfg.getvar<Vec2i>("windowsize").y; //scaler scl(winheight*0.9f, { 0,0 }); DelaunayTriangulation dela(1, 1); //int pick_count = cfg.getvar<int>("pick_count"); for (int i = 0; i < pick_count; ++i) { Vec2 cand; int retcode = -1; do { retcode = paus_distr.pick5(cand); } while (retcode == 2); if (retcode != -1 && retcode != 0) { dela.AddPoint(Point(cand.x, cand.y)); //glob_pts.push_back(mkcircle(scl(cand), Color::White, .5f)); //glob_pts.push_back(mkcircle(scl(cand), Color::White, 3.f)); points.push_back({ points.size(),cand }); } } //msg(glob_pts.size()); for (auto&triangle : dela.triangles) { int a = triangle.get()->v[0], b = triangle.get()->v[1], c = triangle.get()->v[2]; Point A = dela.points[a], B = dela.points[b], C = dela.points[c]; if ( A.x == 0 || A.x == 1 || A.y == 0 || A.y == 1 || B.x == 0 || B.x == 1 || B.y == 0 || B.y == 1 || C.x == 0 || C.x == 1 || C.y == 0 || C.y == 1 ) { continue; } graph.push_back({a,b}); graph.push_back({b,c}); graph.push_back({a,c}); // those are the ones! //segment(scl(Vec2(A.x, A.y)), scl(Vec2(B.x, B.y))); //segment(scl(Vec2(C.x, C.y)), scl(Vec2(B.x, B.y))); //segment(scl(Vec2(A.x, A.y)), scl(Vec2(C.x, C.y))); //segment(Vec2(A.x, A.y), Vec2(B.x, B.y)); //segment(Vec2(C.x, C.y), Vec2(B.x, B.y)); //segment(Vec2(A.x, A.y), Vec2(C.x, C.y)); //segment(pts[a], pts[b]); //segment(pts[a], pts[c]); //segment(pts[c], pts[b]); } return make_pair(points, graph); }; float distrib_radius = cfg.getvar<float>("distrib_radius"); paused_distr paus_distr(distrib_radius, 5, 321); int winheight = cfg.getvar<Vec2i>("windowsize").y; scaler scl(winheight*0.9f, { 0,0 }); DelaunayTriangulation dela(1, 1); int pick_count = cfg.getvar<int>("pick_count"); for(int i = 0; i < pick_count; ++i) { Vec2 cand; int retcode = -1; do { retcode = paus_distr.pick5(cand); } while (retcode == 2); if (retcode != -1 && retcode != 0) { dela.AddPoint(Point(cand.x, cand.y)); //glob_pts.push_back(mkcircle(scl(cand), Color::White, .5f)); glob_pts.push_back(mkcircle(scl(cand), Color::White, 3.f)); } } msg(glob_pts.size()); for (auto&triangle : dela.triangles) { int a = triangle.get()->v[0], b = triangle.get()->v[1], c = triangle.get()->v[2]; Point A = dela.points[a], B = dela.points[b], C = dela.points[c]; if ( A.x == 0 || A.x == 1 || A.y == 0 || A.y == 1 || B.x == 0 || B.x == 1 || B.y == 0 || B.y == 1 || C.x == 0 || C.x == 1 || C.y == 0 || C.y == 1 ) { continue; } segment(scl(Vec2(A.x, A.y)), scl(Vec2(B.x, B.y))); segment(scl(Vec2(C.x, C.y)), scl(Vec2(B.x, B.y))); segment(scl(Vec2(A.x, A.y)), scl(Vec2(C.x, C.y))); //segment(Vec2(A.x, A.y), Vec2(B.x, B.y)); //segment(Vec2(C.x, C.y), Vec2(B.x, B.y)); //segment(Vec2(A.x, A.y), Vec2(C.x, C.y)); //segment(pts[a], pts[b]); //segment(pts[a], pts[c]); //segment(pts[c], pts[b]); } barstack bst(FONT, FONTSIZE); slider_finder sl; size_t edit_mode = 1; // ************************ INITS END ************************ //then we actually define the functions, note how all function captures the local context by reference #ifndef LOOP_LAMBDAS draw = [&]() { window.setView(view); // object draw, AFTER normal view //Vec2 cand; //int retcode = -1; //do //{ // retcode = paus_distr.pick4(cand); //} while (retcode == 2); //if (retcode != -1 && retcode != 0) //{ // //glob_pts.push_back(mkcircle(scl(cand), Color::White, .5f)); // glob_pts.push_back(mkcircle(scl(cand), Color::White, .5f)); //} //////////////// obj draw START //////////////// for (auto&a : glob_pts)window.draw(a); for (auto&a : glob_rects)window.draw(a); for (auto&a : glob_vert)window.draw(a); for (auto&a : glob_texts)window.draw(a); //window.draw(nearest_pt); //////////////// obj draw END //////////////// // UI draw, AFTER ui view and BEFORE other draw window.setView(ui_view); bst.draw(window); // nothing after here please UI.draw(window); window.draw(cursor); }; update = [&]() { }; treatkeyevent = [&](Keyboard::Key k) { switch (k) { case Keyboard::BackSpace: glob_pts.clear(); glob_texts.clear(); glob_rects.clear(); glob_vert.clear(); break; case Keyboard::Space: break; case Keyboard::Q: break; } }; mousemoved = [&](Vec2 pos) { cursor.setPosition(pos); if (leftclicked) sl.mouse_callback(pos); }; mouseclick = [&](sf::Mouse::Button button) { if (button == Mouse::Button::Left) leftclicked = true; if (button == Mouse::Button::Right) rightclicked = true; }; mouserelease = [&](sf::Mouse::Button button) { if (button == Mouse::Button::Left) leftclicked = false; if (button == Mouse::Button::Right) rightclicked = false; sl.release(); }; loop = [&]() { while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { switch (event.type) { case sf::Event::KeyPressed: if (event.key.code == sf::Keyboard::Escape) window.close(); treatkeyevent(event.key.code); break; case sf::Event::Closed: window.close(); break; case sf::Event::MouseButtonPressed: mouseclick(event.mouseButton.button); break; case sf::Event::MouseButtonReleased: mouserelease(event.mouseButton.button); break; case sf::Event::MouseMoved: mpos = Vec2(event.mouseMove.x, event.mouseMove.y); mousemoved(mpos); break; default: treatotherevent(event); break; } } window.clear(background); update(); draw(); window.display(); } }; treatotherevent = [&](Event&e) { if (e.type == Event::MouseWheelMoved && e.mouseWheel.delta) { mpos_abs = window.mapPixelToCoords(Vec2i(mpos), view); //view = window.getView(); if (e.mouseWheel.delta < 0) { zoomlevel *= 2.f; view.setSize(view.getSize()*2.f); view.setCenter(interp(mpos_abs, view.getCenter(), 2.f)); //view.setCenter(interp(mpos_abs, view.getCenter(), 2.f)); } if (e.mouseWheel.delta > 0) { zoomlevel *= 0.5; view.setSize(view.getSize()*.5f); view.setCenter(.5f*(view.getCenter() + mpos_abs)); //view.setCenter(.5f*(view.getCenter() + mpos_abs)); } window.setView(view); } }; loop(); #endif // LOOP_LAMBDAS }; }
int main(int argc, char*argv[]) { #ifndef COMMON_INITS1 cfg.init("bedlab.cfg"); Vec2i windowsize; Vec2i screen_resolution = { int(VideoMode::getDesktopMode().width), int(VideoMode::getDesktopMode().height) }; if (cfg.getvar<int>("auto_winsize")) { auto winscale_which = cfg.getstr("winscale_which"); auto window_scale = cfg.getvar<Vec2>(winscale_which); windowsize = Vec2i(scal(Vec2(screen_resolution), window_scale)); } else { windowsize = cfg.getvar<Vec2i>("windowsize"); } winsize = Vec2(windowsize); UI.init_console(); // ALWAYS AFTER SO IT CAN GET WINDOW SIZE wincenter = 0.5f*Vec2(windowsize); Vec2i windowpos; VideoMode::getDesktopMode().height; if (cfg.getvar<int>("stick_left")) { windowpos = Vec2i( screen_resolution.x - windowsize.x - 10, screen_resolution.y - windowsize.y - 40 ); } else windowpos = (Vec2i(5, 25)); sf::RenderWindow window(sf::VideoMode(windowsize.x, windowsize.y), "bedlab!", 7 //,sf::ContextSettings(0, 0, 1) ); window.setFramerateLimit(cfg.getvar<int>("fps_max")); frame_duration = 1.0f / cfg.getvar<int>("fps_max"); window.setPosition(windowpos); vector<string> keys; auto choice = cfg.getstr("app"); // show_keys(cfg.getstr("app"), keys); #endif // COMMON_INITS1 #ifndef COMMON_INITS2 // we don't have a class/interface/struct with data, everything is local to this function, like a classic stack that all programs are anyway. // Texture cursor_tx; // if (!cursor_tx.loadFromFile(cfg.getstr("cursor"))) // cout << "did not load cursor" << endl; // Sprite cursor; // cursor.setTexture(cursor_tx); // cursor.setOrigin(3, 3); CircleShape cursor = mkcircle({ 0,0 }, Color::Transparent, 3, 1); Color background = cfg.getvar<Color>("background"); window.setMouseCursorVisible(false); Vec2 mpos; bool leftclicked = false, rightclicked = false; // view and zoom View view, ui_view; ui_view = view = window.getDefaultView(); float zoomlevel = 1; Vec2 mpos_abs; float frame_duration = 1.0f / cfg.getvar<int>("fps_max"); float smaller_size = 0.95*min(windowsize.y, windowsize.x); auto all_pt_mult = cfg.getvar<float>("all_pt_mult"); all_pt_size = all_pt_mult * smaller_size; //Transform transf; //transf_glob.translate(smaller_size*0.1, smaller_size*0.5); transf_glob.translate(smaller_size*0.02, smaller_size*0.02); transf_glob.scale(Vec2(smaller_size, smaller_size)); //transf_glob = transf; glob_vert_single = VertexArray(Lines); #endif // COMMON_INITS2 #ifndef COMMON_INITS3 bool point_text = cfg.getvar<int>("street_gen_point_text"); bool alternate_font = cfg.getvar<int>("alternate_font"); glob_vert = vector<VertexArray>(10, VertexArray(LineStrip)); string bar_font; Vec2 barsize; auto winscale_which = cfg.getstr("winscale_which"); if (winscale_which == "winscale_smallest" || winscale_which == "winscale_laptop") { bar_font = UI.small_font;; barsize = { 40,7 }; } else if (winscale_which == "winscale_largest" || winscale_which == "winscale_large") { bar_font = UI.default_font; barsize = { 100,15 }; } else { bar_font = UI.default_font; barsize = { 100,15 }; } //dip_bars dbars(UI.fonts["unaligned"], UI.fontsizes[UI.default_font], { 100,15 }); dip_bars dbars(UI.fonts[bar_font], UI.fontsizes[UI.default_font], barsize, { 1,1 }); // tests in lambdas map<string, function<void(void)>> test_lambdas; VertexArray grid(Lines); auto make_grid = [&](float resolution) { // dummy grid grid.clear(); Color col(64, 64, 64, 32); // glob_vert = vector<VertexArray>(10, VertexArray(Lines)); for (int i = 0; i <= int(resolution); ++i) for (int j = 0; j <= int(resolution); ++j) { grid.append(Vertex(tr(Vec2(i / resolution, 0)), col)); grid.append(Vertex(tr(Vec2(i / resolution, 1)), col)); grid.append(Vertex(tr(Vec2(0, i / resolution)), col)); grid.append(Vertex(tr(Vec2(1, i / resolution)), col)); } }; // actual tests diag_draw ddraw; function<void(void)> test_current = [&] {msg("no test configured"); }; auto street_gen_test = cfg.getstr("street_gen_test"); if (test_lambdas.count(street_gen_test)) { test_current = test_lambdas[street_gen_test]; msgm("ok, using test", street_gen_test); test_current(); } else { msg("invalid test choice string thing bing ding king ping ring sing wing wing"); } #endif // COMMON_INITS3 // █████████████████████ APP ACTUAL █████████████████████ // █████████████████████ callbacks █████████████████████ #ifndef LOOP_LAMBDAS draw = [&]() { window.setView(view); //////////////// OBJECTS THAT CAN ZOOMED //////////////// window.draw(grid); window.draw(glob_vert_single); for (auto&a : glob_pts)window.draw(a); for (auto&a : glob_rects)window.draw(a); for (auto&a : glob_vert)window.draw(a); if (point_text) for (auto&a : glob_texts)window.draw(a); ddraw.draw(window); // UI draw, AFTER ui view and BEFORE other draw window.setView(ui_view); //////////////// OBJECTS THAT CANNOT ZOOMED, MEANING UI //////////////// dbars.draw(window); //br.drawwithtext(window); UI.draw(window); window.draw(cursor); }; update = [&]() { }; treatkeyevent = [&](Keyboard::Key k) { switch (k) { case Keyboard::E: break; case Keyboard::T: point_text ^= 1; break; case Keyboard::Q: break; case Keyboard::BackSpace: glob_pts.clear(); glob_texts.clear(); glob_rects.clear(); glob_vert.clear(); break; case Keyboard::Space: break; case Keyboard::S: screenshot(window); break; case Keyboard::Num1: case Keyboard::Num2: case Keyboard::Num3: case Keyboard::Num4: case Keyboard::Num5: break; } }; mousemoved = [&](Vec2 pos) { dbars.mouse_moved(mpos); cursor.setPosition(pos); if (leftclicked); }; mouseclick = [&](sf::Mouse::Button button) { if (button == Mouse::Button::Left) leftclicked = true; if (button == Mouse::Button::Right) rightclicked = true; if (button == Mouse::Button::Left) { dbars.mouse_click(mpos); //test_search(); //test_inter(); } if (button == Mouse::Button::Right) { //test_inter(); } }; mouserelease = [&](sf::Mouse::Button button) { if (button == Mouse::Button::Left) leftclicked = false; if (button == Mouse::Button::Right) rightclicked = false; dbars.mouse_release(); test_current(); }; loop = [&]() { while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { switch (event.type) { case sf::Event::KeyPressed: if (event.key.code == sf::Keyboard::Escape) window.close(); treatkeyevent(event.key.code); break; case sf::Event::Closed: window.close(); break; case sf::Event::MouseButtonPressed: mouseclick(event.mouseButton.button); break; case sf::Event::MouseButtonReleased: mouserelease(event.mouseButton.button); break; case sf::Event::MouseMoved: mpos = Vec2(event.mouseMove.x, event.mouseMove.y); mpos_abs = window.mapPixelToCoords(Vec2i(mpos), view); mousemoved(mpos); break; default: treatotherevent(event); break; } } window.clear(background); update(); draw(); //static bool once = true; //if (once) { // screenshot(window); // once = false; //} window.display(); } }; treatotherevent = [&](Event&e) { if (e.type == Event::MouseWheelMoved && e.mouseWheel.delta) { mpos_abs = window.mapPixelToCoords(Vec2i(mpos), view); //view = window.getView(); if (e.mouseWheel.delta < 0) { zoomlevel *= 2.f; view.setSize(view.getSize()*2.f); view.setCenter(interp(mpos_abs, view.getCenter(), 2.f)); //view.setCenter(interp(mpos_abs, view.getCenter(), 2.f)); } if (e.mouseWheel.delta > 0) { zoomlevel *= 0.5; view.setSize(view.getSize()*.5f); view.setCenter(.5f*(view.getCenter() + mpos_abs)); //view.setCenter(.5f*(view.getCenter() + mpos_abs)); } window.setView(view); } }; #endif // LOOP_LAMBDAS loop(); }
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static DWORD st = 0; static DWORD dt = 0; static Point ptMouse; const int count = 100; static int radius = 20; static ui user_interface; static bool bDrawLine = false; if (uMsg == WM_CREATE) { Rect rc; ::GetClientRect(hWnd, &rc); ::InflateRect(&rc, -radius, -radius); user_interface.attach(hWnd); for (int i = 1; i < 4; i++){ character_inform* pchar = new character_inform; pchar->SetPosition(Point(30 * i, 30 * i)); pchar->set_ATK(10); char_man_depot.AddEntry(i-1, pchar); } //ptclinet가 rc 의 가운데에 오게끔해야됨... ::SetTimer(hWnd, 0, 10, NULL); return 0; } else if (uMsg == WM_DESTROY) { ::KillTimer(hWnd, 0); ::PostQuitMessage(0); return 0; } else if (uMsg == WM_PAINT) { PAINTSTRUCT ps; HDC hdc = ::BeginPaint(hWnd, &ps); // TODO..... Rect rc; ::GetClientRect(hWnd, &rc); LONG a = (rc.left + rc.right)/2; user_interface.draw(hdc); std::wostringstream oss; oss << _T("rc. w: ") << rc.right / 2 << _T("rc.h : ") << rc.bottom / 2 << std::endl ; ::DrawText(hdc, oss.str().c_str(), -1, &rc, DT_TOP); ::EndPaint(hWnd, &ps); return 0; } else if (uMsg == WM_LBUTTONUP){ ::GetCursorPos(&ptMouse); ptMouse = ptMouse.ToClient(hWnd); //test.set_drag(false); // redraw RECT rc; ::GetClientRect(hWnd, &rc); ::InvalidateRect(hWnd, &rc, TRUE); return 0; } else if (uMsg == WM_MOUSEMOVE){ ::GetCursorPos(&ptMouse); ptMouse = ptMouse.ToClient(hWnd); RECT rc; ::GetClientRect(hWnd, &rc); ::InvalidateRect(hWnd, &rc, TRUE); return 0; } else if (uMsg == WM_TIMER){ dt = ::GetTickCount() - st; st = ::GetTickCount(); RECT rc; ::GetClientRect(hWnd, &rc); ::InvalidateRect(hWnd, &rc, TRUE); } return ::DefWindowProc(hWnd,uMsg,wParam,lParam); }
function<void()> smoothmouse(RenderWindow&window, ui &UI){ return [&window, &UI](){ //void smoothmouse(RenderWindow&window, ui &UI){ // tidy code organization, here we predeclare methods just like a header would, it's redundant but necessary function<void()> draw, loop, init, update; function<void(Vec2 pos)> mousemoved; function<void(sf::Mouse::Button button)> mouseclick, mouserelease; function<void(Event&e)> treatotherevent; function<void(Keyboard::Key k)> treatkeyevent; // we don't have a class/interface/struct with data, everything is local to this function, like a classic stack that all programs are anyway. Texture cursor_tx; Sprite cursor; configfile cfg; cfg.init("bedlab.cfg"); if (!cursor_tx.loadFromFile(cfg.getstr("cursor"))) cout << "did not load cursor" << endl; cursor.setTexture(cursor_tx); cursor.setOrigin(3, 3); window.setMouseCursorVisible(false); float lag; SET(lag); CircleShape cursorlag(10); //cursor.setFillColor(Color::White); cursorlag.setFillColor(Color(255,0,0,128)); recenter(cursorlag); Vec2 mpos; //then we actually define the functions, note how all function captures the local context by reference draw = [&](){ UI.draw(window); window.draw(cursor); window.draw(cursorlag); }; update = [&](){ Vec2 trans = cursorlag.getPosition() - cursor.getPosition(); auto dist = vectlen(trans); //cursorlag.move(-(trans)*lag); // equivalent of getposition()+-trans*.01f //cursorlag.move(-normalized(trans)*max(dist*dist, 100.f)*lag); // equivalent of getposition()+-trans*.01f Vec2 move = vectlen(trans) > 0 ? -normalized(trans)*dist*lag :Vec2{0,0}; cursorlag.move(move); // equivalent of getposition()+-trans*.01f show(cursorlag.getPosition()); show(dist); show(trans); }; loop = [&](){ while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { switch (event.type) { case sf::Event::KeyPressed: if (event.key.code == sf::Keyboard::Escape) window.close(); treatkeyevent(event.key.code); break; case sf::Event::Closed: window.close(); break; case sf::Event::MouseButtonPressed: mouseclick(event.mouseButton.button); break; case sf::Event::MouseButtonReleased: mouserelease(event.mouseButton.button); break; case sf::Event::MouseMoved: mpos = Vec2(event.mouseMove.x, event.mouseMove.y); mousemoved(mpos); break; default: treatotherevent(event); break; } } window.clear(); update(); draw(); //window.draw(shape); UI.draw(window); window.display(); } }; treatkeyevent = [&](Keyboard::Key k){ switch (k) { case Keyboard::Space: cursorlag.setPosition(mpos); cursor.setPosition(mpos); } }; mousemoved = [&](Vec2 pos){ //msg(pos); cursor.setPosition(pos); //UI.put(mpos); show(mpos); }; treatotherevent = [&](Event&e){ }; mouseclick = [&](sf::Mouse::Button button){ }; mouserelease = [&](sf::Mouse::Button button){ }; loop(); }; }