/ games / endlauncher / src / main.cpp
main.cpp
  1  
  2  #include <enginend/engine.h>
  3  #include "netio.h"
  4  #include <thread>
  5  #include <atomic>
  6  #include <chrono>
  7  #include"themes.h"
  8  using namespace enginend;
  9  using namespace enginend::nodes::twod;
 10  netio nete{};
 11  /*
 12  
 13   */
 14  struct background: public virtual textured {
 15  	background(Texture2D* texture,float x,float y,float w, float h) {
 16  		this->pos=Vector2{x,y};this->size=Vector2{w,h};
 17  		this->texture=texture;
 18  		this->justclicked=false;
 19  	}
 20  	void boot()override{
 21  		img=LoadImageFromTexture(*this->texture);
 22  	}
 23  	void tick()override {
 24  		Vector2 mp=Vector2(GetMousePositionDesktop());
 25  		Vector2 wp=GetWindowPosition();
 26  		Vector2 rp=Vector2{mp.x-wp.x,mp.y-wp.y};
 27  		if (IsMouseButtonDown(0)) {
 28  			if (rp.x>=0&&rp.y>=0&&rp.x<600&&rp.y<300) {
 29  				Color pix=GetImageColor(img, (int)rp.x, (int)(300-rp.y));
 30  				if (pix.a!=0) {
 31  					if (clicked==false) {
 32  						clicked=true;
 33  						relmouse=rp;
 34  					}
 35  				}
 36  			}
 37  		}else {
 38  			clicked=false;
 39  		}
 40  		if (clicked) {
 41  			Vector2 nwp{
 42  				mp.x-relmouse.x, mp.y-relmouse.y
 43  			};
 44  			int cm=GetCurrentMonitor();
 45  			Vector2 mop=GetMonitorPosition(cm);
 46  			int newwpx=nwp.x-mop.x;
 47  			int newwpy=nwp.y-mop.y;
 48  			int maxwpx=GetMonitorWidth(cm)-GetScreenWidth();
 49  			int maxwpy=GetMonitorHeight(cm)-GetScreenHeight();
 50  			newwpx=newwpx>maxwpx?maxwpx:newwpx<0?0:newwpx;
 51  			newwpy=newwpy>maxwpy?maxwpy:newwpy<0?0:newwpy;
 52  			SetWindowPosition(newwpx,newwpy);
 53  		}
 54  	}
 55  	void draw()override{this->textured::draw();}
 56  	void exit()override{}
 57  private:
 58  	Image img;bool justclicked;bool clicked=false;
 59  	Vector2 relmouse;
 60  };
 61  
 62  struct logi: public virtual textfield {
 63  	logi(Texture2D* texture,enginend::theme* theme,float x,float y,float w,float h,float fs,std::string txt) {
 64  		this->pos=Vector2{x,y};this->size=Vector2{w,h};this->content=txt;this->theme=theme;
 65  		this->texture=texture;
 66  		this->fs=fs;
 67  	}
 68  	void draw() override {
 69  		Vector2 p=pos;
 70  		float spacing=fs/2.0f;
 71  		std::stringstream ss(content);
 72  		std::string line;
 73  		int lines=0;
 74  
 75  		while (std::getline(ss, line)) {
 76  			if (lines%2==0) {
 77  				Vector2 charPos=p;
 78  				for (char& c : line) {
 79  					char str[2]={c, '\0'};
 80  					Color fc=Color{255,0,255,255};
 81  					if (c=='/'||c==':') {
 82  						fc=Color{255,255,0,255};
 83  					}
 84  
 85  					DrawTextEx(this->theme->font, str, charPos, (float)fs, spacing, fc);
 86  					charPos.x+=MeasureTextEx(this->theme->font, str, (float)fs, spacing).x;
 87  				}
 88  			} else {
 89  				DrawTextEx(this->theme->font, line.c_str(), p, (float)fs, spacing, Color{0,255,255,255});
 90  			}
 91  
 92  			p.y+=(fs+2);
 93  			lines++;
 94  		}
 95  	}
 96  };
 97  void playbuttonfunc();
 98  void quit(){exit(0);}
 99  #include <boost/process.hpp>
100  class launcher:public program {
101  public:
102  	Texture2D bg;
103  	Texture2D buttonfore;
104  	Texture2D buttonlock;
105  	Texture2D playbtn[2];
106  	Texture2D menubtn[3];
107  	button* buttons[8];
108  	button* playbutton;
109  	Texture2D buttonslabel[8];
110  	Font gamename,changelog,information;
111  	bool vsync=true;
112  	RenderTexture2D target;
113  	text version;
114  	std::string selectedversion="";
115  	Image img;
116  	bool captured=true;
117  	const char* CONF() final{return "test.tdf";}
118  	launcher(){};
119  	void boot() override {
120  		currentscene = new scene{};
121  		
122  		tickrate=15;
123  		framerate=15;
124  		SetConfigFlags(FLAG_WINDOW_UNDECORATED|FLAG_WINDOW_TRANSPARENT|FLAG_WINDOW_TOPMOST);
125  		tiny::error("is transparent lol");
126  		InitWindow(600,300,"test");target=LoadRenderTexture(600, 300);
127  		img=GenImageColor(600, 300, rl::BLANK);
128  		SetTargetFPS(GetMonitorRefreshRate(GetCurrentMonitor()));
129  		this->tickrate=GetMonitorRefreshRate(GetCurrentMonitor());
130  		bg=LoadTexture("res/launcher.png");
131  		buttonfore=LoadTexture("res/forebuttonon.png");
132  		buttonlock=LoadTexture("res/lockbutton.png");
133  		gamename=LoadFont("res/showcase.ttf");
134  		changelog=LoadFont("res/log.ttf");
135  		information=LoadFont("res/info.ttf");
136  		menubtn[0]=LoadTexture("res/btn.png");
137  		menubtn[1]=LoadTexture("res/btnhover.png");
138  		menubtn[2]=LoadTexture("res/btnpress.png");
139  		selectedversion=nete.currentversion;
140  		enginend::DEFAULT->font=information;
141  		GAMENAME.font=gamename;
142  		CHANGELOG.font=changelog;
143  		version= text (nullptr,enginend::DEFAULT,96,16*17,1,1,20,"version: "+selectedversion);
144  		SetTraceLogLevel(LOG_ERROR);
145  		buttons[0]=new button(&menubtn[0], enginend::DEFAULT,468,58,96,16,nullptr);
146  		buttonslabel[0]=LoadTexture("res/options.png");
147  		buttons[1]=new button(&menubtn[0], enginend::DEFAULT,468,58+(18*1),96,16,std::function<void()>([]() {
148  			OpenURL("http://kosumi.ddns.net:60000/");
149  			
150  		}));
151  		buttonslabel[1]=LoadTexture("res/website.png");
152  		buttons[2]=new button(&menubtn[0], enginend::DEFAULT,468,58+(18*2),96,16,std::function<void()>([]() {
153  			OpenURL("http://kosumi.ddns.net:60001/");
154  		}));
155  		buttonslabel[2]=LoadTexture("res/forums.png");
156  		buttons[3]=new button(&menubtn[0], enginend::DEFAULT,468,58+(18*3),96,16,std::function<void()>([]() {
157  			OpenURL("https://github.com/kin-fuyuki/allgames/issues");
158  		}));
159  		buttonslabel[3]=LoadTexture("res/help.png");
160  		buttons[4]=new button(&menubtn[0], enginend::DEFAULT,468,58+(18*4),96,16,std::function<void()>([]() {
161  			nete.download();
162  		}));
163  		buttonslabel[4]=LoadTexture("res/update.png");
164  		buttons[5]=new button(&menubtn[0], enginend::DEFAULT,468,58+(18*5),96,16,nullptr);
165  		buttonslabel[5]=LoadTexture("res/verify.png");
166  		buttons[6]=new button(&menubtn[0], enginend::DEFAULT,468,58+(18*6)+15,96,16,nullptr);
167  		buttonslabel[6]=LoadTexture("res/versions.png");
168  		buttons[7]=new button(&menubtn[0], enginend::DEFAULT,468,58+(18*7)+17,96,16,std::function<void()>([]() {
169  			quit();
170  		}));
171  		buttonslabel[7]=LoadTexture("res/exit.png");
172  		playbtn[0]=LoadTexture("res/playoff.png");
173  		playbtn[1]=LoadTexture("res/playon.png");
174  		playbutton= new button(&playbtn[0], enginend::DEFAULT,406,(18*11)+17+9,153,59,std::function<void()>(playbuttonfunc));
175  		currentscene->nodes=std::list<nodes::node*>{
176  			new background(&bg,0,0,600,300),
177  			new textured(&buttonfore,3,36,62,62),
178  			new textured(&buttonlock,3,36+((62+4)*1),62,62),
179  			new textured(&buttonlock,3,36+((62+4)*2),62,62),
180  			new textured(&buttonlock,3,36+((62+4)*3),62,62),
181  			new text(nullptr,&GAMENAME,232,19,1,1,16,"FORESPEND"),
182  			buttons[0],new textured(&buttonslabel[0],468,58,96,16),
183  			buttons[1],new textured(&buttonslabel[1],468,58+(18*1),96,16),
184  			buttons[2],new textured(&buttonslabel[2],468,58+(18*2),96,16),
185  			buttons[3],new textured(&buttonslabel[3],468,58+(18*3),96,16),
186  			buttons[4],new textured(&buttonslabel[4],468,58+(18*4),96,16),
187  			buttons[5],new textured(&buttonslabel[5],468,58+(18*5),96,16),
188  			buttons[6],new textured(&buttonslabel[6],468,58+(18*6)+15,96,16),
189  			buttons[7],new textured(&buttonslabel[7],468,58+(18*7)+17,96,16),
190  			playbutton,
191  			new logi(nullptr,&CHANGELOG,90,58,466,159,8,nete.changelog),
192  			new text(nullptr,enginend::DEFAULT,96+16,(16*14)-3,1,1,20,"downloaded        verified"),
193  			&version,
194  		};
195  		currentscene->boot();
196  	}
197  	int buttondelay=0;
198  	void tick() override {
199  		if (nete.currentversion!=selectedversion) {
200  			selectedversion=nete.currentversion;
201  			this->version.content="version: "+selectedversion;
202  			tiny::echo("selecting version: %s",selectedversion.c_str());
203  		}
204  		{
205  			for (button* b : buttons) {
206  				if (b->hover) {
207  					if (b->pressed) {
208  						b->texture=&menubtn[2];
209  						buttondelay=5;
210  					}else {
211  						if (b->texture->id==menubtn[2].id) {
212  							if(buttondelay<0) {
213  								b->texture=&menubtn[1];
214  							}
215  						}else {
216  							b->texture=&menubtn[1];
217  						}
218  					}
219  				}else {
220  					if (b->texture->id==menubtn[2].id) {
221  						if(buttondelay<0) {
222  							b->texture=&menubtn[0];
223  						}
224  					}else {
225  						b->texture=&menubtn[0];
226  					}
227  				}
228  			}
229  		}
230  		{
231  			if (playbutton->pressed) {
232  				playbutton->texture=&playbtn[1];
233  				buttondelay=5;
234  			}else {
235  			if(buttondelay<0) {
236  				playbutton->texture=&playbtn[0];
237  			}
238  			}
239  		}
240  		currentscene->tick();
241  		buttondelay--;
242  	}
243  	bool changedmenu=true;
244  	bool itemchanged=true;
245  	void draw() override {
246  		BeginTextureMode(target);
247  		currentscene->draw();
248  		EndTextureMode();
249  		BeginDrawing();
250  		ClearBackground(rl::BLANK);
251  		DrawTexturePro(target.texture, {0, 0, 600, -300}, {0, 0, 600, 300}, {0, 0}, 0, rl::WHITE);
252  		EndDrawing();
253  		Vector2 mp=Vector2(GetMousePositionDesktop());
254  		Vector2 wp=GetWindowPosition();
255  		Vector2 rp=Vector2{mp.x-wp.x,mp.y-wp.y};
256  		if (rp.x>=0&&rp.y>=0&&rp.x<600&&rp.y<300) {
257  			if (changedmenu) {
258  				UnloadImage(img);
259  				img=LoadImageFromTexture(target.texture);
260  				changedmenu=false;
261  			}
262  			Color pix=GetImageColor(img, (int)rp.x, (int)(300-rp.y));
263  			if (pix.a==0) {
264  				SetWindowState(FLAG_WINDOW_MOUSE_PASSTHROUGH);
265  				captured=false;
266  			} else {
267  				ClearWindowState(FLAG_WINDOW_MOUSE_PASSTHROUGH);
268  				captured=true;
269  			}
270  		}
271  	}
272  	void exit() override {
273  		currentscene->exit();
274  	}
275  };
276  
277  launcher* launch;
278  tiny::ErrorLevel tiny::level{8};
279  
280  int main(int argc, char *argv[]) {
281  	tiny::startup((char*)"enginend test",(char*)"1.0");
282  		tiny::echo ("checking if cfg.tdf exists, if not create");
283  		std::ofstream tdffile("cfg.tdf");
284  		tdffile.close();
285  	
286  	tiny::echo ("read cfg.tdf");
287  	tiny::TDF_FILE config;config.filepath="cfg.tdf";config.read();
288  	std::string version;
289  	tiny::echo ("getting version");
290  	try {version=config.getstring({"version"});}
291  	catch (tiny::TDF_ERR e) {version="NULL";}
292  	if (version!="NULL") {
293  		nete.currentversion=version;
294  		config.setstring({"version"},nete.currentversion);
295  	}
296  	launcher e;
297  	launch=&e;
298  	tiny::echo ("starting net");
299  	nete.start();
300  	tiny::echo ("downloading github info");
301  	nete.github();
302  	tiny::echo ("starting launcher");
303  	e.boot();
304  	std::atomic<bool> running{true};
305  
306  	std::thread tickthread([&e, &running]() {
307  		double tickrate=1.0/e.tickrate;
308  		auto lasttick=std::chrono::high_resolution_clock::now();
309  		
310  		while (running) {
311  			auto now=std::chrono::high_resolution_clock::now();
312  			double elapsed=std::chrono::duration_cast<std::chrono::duration<double>>(now-lasttick).count();
313  
314  			if (elapsed>=tickrate) {
315  				e.tick();
316  				lasttick=now;
317  			} else {
318  				std::this_thread::sleep_for(std::chrono::duration<double>(tickrate-elapsed));
319  			}
320  		}
321  	});
322  
323  	double framerate=1.0/e.framerate;
324  	auto lastframe=std::chrono::high_resolution_clock::now();
325  
326  	while (!WindowShouldClose()) {
327  		auto now=std::chrono::high_resolution_clock::now();
328  		double elapsed=std::chrono::duration_cast<std::chrono::duration<double>>(now-lastframe).count();
329  
330  		if (elapsed>=framerate) {
331  			e.draw();
332  			lastframe=now;
333  		} else {
334  			WaitTime(framerate-elapsed);
335  		}
336  	}
337  
338  	running=false;
339  	tickthread.join();
340  
341  	e.exit();
342  	config.setstring({"version"},nete.currentversion);
343  	config.save();
344  	config.close();
345  	return 0;
346  }
347  void playbuttonfunc() {
348  	if (nete.currentversion!="NULL") {
349  		FILE* gameexe = fopen(("forespend/versions/"+nete.currentversion+"/bin/game").c_str(), "r");
350  		if (gameexe) {
351  			fclose(gameexe);
352  			
353  			std::thread thread([]() {
354  				boost::process::system("bin/game",boost::process::start_dir=("forespend/versions/"+nete.currentversion));
355  			});
356  			exit(0);
357  		}
358  		
359  	}
360  }