From f6fee0982f5e92a0f062c5b726b105e4d6789a18 Mon Sep 17 00:00:00 2001 From: kin fuyuki Date: Sun, 21 Dec 2025 18:03:24 -0300 Subject: [PATCH] chaaangelog! --- engine/src/scenes/node2d.h | 528 ++++++++++++++++----------------- games/endlauncher/src/main.cpp | 233 ++++++++++----- games/endlauncher/src/netio.h | 123 ++++++-- versions.tdf | 8 +- 4 files changed, 539 insertions(+), 353 deletions(-) diff --git a/engine/src/scenes/node2d.h b/engine/src/scenes/node2d.h index a624a55..07fa934 100644 --- a/engine/src/scenes/node2d.h +++ b/engine/src/scenes/node2d.h @@ -4,281 +4,281 @@ #include "nodes.h" namespace enginend { - struct node2d :public node { - Vector2 pos; - node2d(){} - node2d(float x,float y):pos(Vector2{x,y}){} - }; - struct rect :virtual public node2d{ - Vector2 size; - rect(){} - rect(float x,float y,float w, float h):size(Vector2{w,h}){ - this->pos=Vector2{x,y}; - } - }; - struct textured :virtual public rect{ - Texture2D* texture; - textured(){} - textured(Texture2D* texture,float x,float y,float w, float h):texture(texture){ - this->pos=Vector2{x,y};this->size=Vector2{w,h}; - } - void boot()override{} - void tick()override{} - void draw()override{if (texture!=nullptr)DrawTexture(*texture,pos.x,pos.y,WHITE);} - void exit()override{} - }; - struct colored :virtual public rect{ - Color c; - colored(){} - colored(Color color,float x,float y,float w, float h):c(color){ - this->pos=Vector2{x,y};this->size=Vector2{w,h}; - } - void boot()override{} - void tick()override{} - void draw()override{DrawRectangle(pos.x,pos.y,size.x,size.y,c);} - void exit()override{} - }; - struct tinted :virtual public colored, virtual public textured{ - tinted(){} - tinted(Texture2D* texture,Color color,float x,float y,float w, float h): - node2d(x, y), - rect(x, y, w, h), - colored(color, x, y, w, h), - textured(texture, x, y, w, h) - {} - void boot()override{this->colored::boot();this->textured::boot();} - void tick()override{this->colored::tick();this->textured::tick();} - void draw()override{if (texture!=nullptr)DrawTexture(*texture,pos.x,pos.y,c);} - void exit()override{this->colored::exit();this->textured::exit();} - }; - struct text :public tinted { - protected: - std::string result; - public: - Font font; - float fontsize; - Color textcolor; - std::string content; - text(){ fontsize = 20; } - text(Texture2D* texture,Color textcol,Color color,float x,float y,float w,float h,Font f,float fs,std::string txt): - font(f),fontsize(fs),content(txt) - { - this->pos=Vector2{x,y};this->size=Vector2{w,h};this->texture=texture;this->c=color;this->textcolor=textcol; - - result=content; - size_t initpos = 0; - while((initpos = result.find("\n", initpos)) != std::string::npos) { - result.replace(initpos, 1, "\\n"); - initpos += 2; - } - } - void boot()override{this->tinted::boot();} - void tick()override { - this->tinted::tick(); - if (result!=content) { - result=content; - size_t initpos = 0; - while((initpos = result.find("\n", initpos)) != std::string::npos) { - result.replace(initpos, 1, "\\n"); - initpos += 2; - } - } - } - void draw()override { - Vector2 minsize=MeasureTextEx(font, content.c_str(), fontsize, 1); - Vector2 charsize=MeasureTextEx(font, " ", fontsize, 1); - float p=charsize.x>charsize.y?charsize.x/minsize.x:charsize.y/minsize.y; - p=p*2; - int minh=(minsize.y>size.y)?minsize.y:size.y; - int minw=(minsize.x>size.x)?minsize.x:size.x; - DrawRectangle(pos.x-charsize.x,pos.y-charsize.y,minw+p,minh+p,c); - DrawTextEx(font, content.c_str(), pos, fontsize, 1, textcolor); - } - void exit()override{this->tinted::exit();} - }; - struct button :virtual public tinted{ - std::function function; - bool pressed; - button():pressed(false){} - button(Texture2D* texture,Color color,float x,float y,float w,float h,std::function func):function(func),pressed(false){ - this->pos=Vector2{x,y};this->size=Vector2{w,h};this->texture=texture;this->c=color; - } - void boot()override{this->tinted::boot();} - void tick()override{ - this->tinted::tick(); - Vector2 mouse=GetMousePosition(); - if(CheckCollisionPointRec(mouse,{pos.x,pos.y,size.x,size.y})&&IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){ - if(function)function(); - } - } - void draw()override { - if (this->texture!=nullptr)DrawTexture(*texture,pos.x,pos.y,c); - else - DrawRectangle(pos.x,pos.y,size.x,size.y,c); - } - void exit()override{this->tinted::exit();} - }; + struct node2d :public node { + Vector2 pos; + node2d(){} + node2d(float x,float y):pos(Vector2{x,y}){} + }; + struct rect :virtual public node2d{ + Vector2 size; + rect(){} + rect(float x,float y,float w,float h):size(Vector2{w,h}){ + this->pos=Vector2{x,y}; + } + }; + struct textured :virtual public rect{ + Texture2D* texture; + textured(){} + textured(Texture2D* texture,float x,float y,float w,float h):texture(texture){ + this->pos=Vector2{x,y};this->size=Vector2{w,h}; + } + void boot()override{} + void tick()override{} + void draw()override{if(texture!=nullptr)DrawTexture(*texture,pos.x,pos.y,WHITE);} + void exit()override{} + }; + struct colored :virtual public rect{ + Color c; + colored(){} + colored(Color color,float x,float y,float w,float h):c(color){ + this->pos=Vector2{x,y};this->size=Vector2{w,h}; + } + void boot()override{} + void tick()override{} + void draw()override{DrawRectangle(pos.x,pos.y,size.x,size.y,c);} + void exit()override{} + }; + struct tinted :virtual public colored,virtual public textured{ + tinted(){} + tinted(Texture2D* texture,Color color,float x,float y,float w,float h): + node2d(x,y), + rect(x,y,w,h), + colored(color,x,y,w,h), + textured(texture,x,y,w,h) + {} + void boot()override{this->colored::boot();this->textured::boot();} + void tick()override{this->colored::tick();this->textured::tick();} + void draw()override{if(texture!=nullptr)DrawTexture(*texture,pos.x,pos.y,c);} + void exit()override{this->colored::exit();this->textured::exit();} + }; + struct text :public tinted { + protected: + std::string result; + public: + Font font; + float fs; + Color txc; + std::string content; + text(){fs=20;} + text(Texture2D* texture,Color txcol,Color color,float x,float y,float w,float h,Font f,float fsize,std::string txt): + font(f),fs(fsize),content(txt) + { + this->pos=Vector2{x,y};this->size=Vector2{w,h};this->texture=texture;this->c=color;this->txc=txcol; + + result=content; + size_t initp=0; + while((initp=result.find("\n",initp))!=std::string::npos){ + result.replace(initp,1,"\\n"); + initp+=2; + } + } + void boot()override{this->tinted::boot();} + void tick()override { + this->tinted::tick(); + if(result!=content){ + result=content; + size_t initp=0; + while((initp=result.find("\n",initp))!=std::string::npos){ + result.replace(initp,1,"\\n"); + initp+=2; + } + } + } + void draw()override { + Vector2 minsize=MeasureTextEx(font,content.c_str(),fs,1); + Vector2 charsize=MeasureTextEx(font," ",fs,1); + float p=charsize.x>charsize.y?charsize.x/minsize.x:charsize.y/minsize.y; + p=p*2; + int minh=(minsize.y>size.y)?minsize.y:size.y; + int minw=(minsize.x>size.x)?minsize.x:size.x; + DrawRectangle(pos.x-charsize.x,pos.y-charsize.y,minw+p,minh+p,c); + DrawTextEx(font,content.c_str(),pos,fs,1,txc); + } + void exit()override{this->tinted::exit();} + }; + struct button :virtual public tinted{ + std::function func; + bool pressed; + bool hover; + button():pressed(false){} + button(Texture2D* texture,Color color,float x,float y,float w,float h,std::function f):func(f),pressed(false){ + this->pos=Vector2{x,y};this->size=Vector2{w,h};this->texture=texture;this->c=color; + } + void boot()override{this->tinted::boot();} + void tick()override{ + this->tinted::tick(); + Vector2 mouse=GetMousePosition(); + if(CheckCollisionPointRec(mouse,{pos.x,pos.y,size.x,size.y})){hover=true; + if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){ + pressed=true; + if(func)func(); + }else{ + pressed=false; + } + }else{ + hover=false; + } + } + void draw()override { + if(this->texture!=nullptr)DrawTexture(*texture,pos.x,pos.y,c); + else DrawRectangle(pos.x,pos.y,size.x,size.y,c); + } + void exit()override{this->tinted::exit();} + }; struct labeledbutton :virtual public button { std::string label; Font font; - int fontsize; - Color textcolor; + int fs; + Color txc; labeledbutton(std::string name,Texture2D* texture,Color color,Color text, - float x,float y,float w,float h,std::function func, - Font f,int size):font(f), fontsize(size),textcolor(text){ + float x,float y,float w,float h,std::function f, + Font fnt,int size):font(fnt),fs(size),txc(text){ this->pos=Vector2{x,y};this->size=Vector2{w,h};this->texture=texture;this->c=color; - this->function=func;this->pressed=false; + this->func=f;this->pressed=false; this->label=name; - } - void boot()override{this->button::boot();} - void tick()override{ - this->button::tick(); - } + void tick()override{this->button::tick();} void draw()override{ this->button::draw(); - - Vector2 textsize = MeasureTextEx(font, label.c_str(), fontsize, 1); - Vector2 textpos = { - pos.x + (size.x - textsize.x)/2, - pos.y + (size.y - textsize.y)/2 - }; - DrawTextEx(font, label.c_str(), textpos, fontsize, 1, textcolor); + Vector2 tsize=MeasureTextEx(font,label.c_str(),fs,1); + Vector2 tpos={ + pos.x+(size.x-tsize.x)/2, + pos.y+(size.y-tsize.y)/2 + }; + DrawTextEx(font,label.c_str(),tpos,fs,1,txc); } void exit()override{this->button::exit();} }; - struct slider :virtual public tinted{ - float value; - float minvalue; - float maxvalue; - slider():value(0),minvalue(0),maxvalue(1){} - slider(Texture2D* texture,Color color,float x,float y,float w,float h,float min,float max,float val):value(val),minvalue(min),maxvalue(max){ - this->pos=Vector2{x,y};this->size=Vector2{x,y};this->texture=texture;this->c=color; - } - void boot()override{this->tinted::boot();} - void tick()override{ - this->tinted::tick(); - Vector2 mouse=GetMousePosition(); - if(CheckCollisionPointRec(mouse,{pos.x,pos.y,size.x,size.y})&&IsMouseButtonDown(MOUSE_LEFT_BUTTON)){ - float t=(mouse.x-pos.x)/size.x; - value=minvalue+t*(maxvalue-minvalue); - if(valuemaxvalue)value=maxvalue; - } - } - void draw()override{ - DrawRectangle(pos.x,pos.y,size.x,size.y,DARKGRAY); - float t=(value-minvalue)/(maxvalue-minvalue); - DrawRectangle(pos.x,pos.y,size.x*t,size.y,c); - } - void exit()override{this->tinted::exit();} - }; - struct textfield :public text{ - textfield(){} - textfield(Texture2D* texture,Color textcol,Color color,float x,float y,float w,float h,Font f,float fs,std::string txt): - text(texture,textcol,color,x,y,w,h,f,fs,txt){} - void boot()override{this->text::boot();} - void tick()override{this->text::tick();} - void draw()override{ - Vector2 p=pos; - float lineheight=fontsize+2; - std::string line=""; - Vector2 charsize=MeasureTextEx(font, " ", fontsize, 0); - Vector2 minsize=MeasureTextEx(font, content.c_str(), fontsize, charsize.x/2); - float po=charsize.x>charsize.y?charsize.x/charsize.y:charsize.y/charsize.x;po=po*5; - int minh=(minsize.y>size.y)?minsize.y:size.y; - int minw=(minsize.x>size.x)?minsize.x:size.x; - DrawRectangle(pos.x-(po/2),pos.y-(po/2),minw+(po*1.1),minh+(po*1.1),c); - DrawTextEx(font,content.c_str(),p,fontsize,charsize.x/2,this->textcolor); - } - void exit()override{this->text::exit();} - }; - struct textinput :public text{ - bool active; - int cursorpos; - textinput():active(false),cursorpos(0){} - textinput(Texture2D* texture,Color textcol,Color color,float x,float y,float w,float h,Font f,float fs):active(false),cursorpos(0){ - this->pos=Vector2{x,y};this->size=Vector2{x,y};this->texture=texture;this->c=color;this->font=f;this->content=""; - this->textcolor=textcol;this->fontsize=fs; - } - void boot()override{this->text::boot();} - void tick()override{ - this->text::tick(); - Vector2 mouse=GetMousePosition(); - if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){ - active=CheckCollisionPointRec(mouse,{pos.x,pos.y,size.x,size.y}); - } - if(active){ - int key=GetCharPressed(); - while(key>0){ - if(key>=32&&key<=125){ - content+=static_cast(key); - cursorpos++; - } - key=GetCharPressed(); - } - if(IsKeyPressed(KEY_BACKSPACE)&&content.length()>0){ - content.pop_back(); - cursorpos--; - } - } - } - void draw()override{ - this->text::draw(); - if(active)DrawRectangle(pos.x+MeasureText(content.c_str(),fontsize),pos.y,2,fontsize,{0,0,0,127}); - } - void exit()override{this->text::exit();} - }; - struct textinputfield :public textfield{ - bool active; - int cursorpos; - textinputfield():active(false),cursorpos(0){} - textinputfield(Texture2D* texture,Color textcol,Color color,float x,float y,float w,float h,Font f,float fs):active(false),cursorpos(0), - textfield(texture,textcol,color,x,y,w,h,f,fs,""){} - void boot()override{this->textfield::boot();} - void tick()override{ - this->textfield::tick(); - Vector2 mouse=GetMousePosition(); - if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){ - active=CheckCollisionPointRec(mouse,{pos.x,pos.y,size.x,size.y}); - } - if(active){ - int key=GetCharPressed(); - while(key>0){ - if(key>=32&&key<=125){ - content+=static_cast(key); - cursorpos++; - } - key=GetCharPressed(); - } - if(IsKeyPressed(KEY_BACKSPACE)&&content.length()>0){ - content.pop_back(); - cursorpos--; - } - if(IsKeyPressed(KEY_ENTER)){ - content+='\n'; - cursorpos++; - } - } - } - void draw()override{ - this->textfield::draw(); - if(active){ - Vector2 p=pos; - float lineheight=fontsize+2; - std::string line=""; - for(char ch:content){ - if(ch=='\n'){ - p.y+=lineheight; - line=""; - }else{ - line+=ch; - } - } - DrawRectangle(p.x+MeasureText(line.c_str(),fontsize),p.y,2,fontsize,BLACK); - } - } - void exit()override{this->textfield::exit();} - }; + struct slider :virtual public tinted{ + float val; + float minv; + float maxv; + slider():val(0),minv(0),maxv(1){} + slider(Texture2D* texture,Color color,float x,float y,float w,float h,float min,float max,float v):val(v),minv(min),maxv(max){ + this->pos=Vector2{x,y};this->size=Vector2{x,y};this->texture=texture;this->c=color; + } + void boot()override{this->tinted::boot();} + void tick()override{ + this->tinted::tick(); + Vector2 mouse=GetMousePosition(); + if(CheckCollisionPointRec(mouse,{pos.x,pos.y,size.x,size.y})&&IsMouseButtonDown(MOUSE_LEFT_BUTTON)){ + float t=(mouse.x-pos.x)/size.x; + val=minv+t*(maxv-minv); + if(valmaxv)val=maxv; + } + } + void draw()override{ + DrawRectangle(pos.x,pos.y,size.x,size.y,DARKGRAY); + float t=(val-minv)/(maxv-minv); + DrawRectangle(pos.x,pos.y,size.x*t,size.y,c); + } + void exit()override{this->tinted::exit();} + }; + struct textfield :public text{ + textfield(){} + textfield(Texture2D* texture,Color txcol,Color color,float x,float y,float w,float h,Font f,float fsize,std::string txt): + text(texture,txcol,color,x,y,w,h,f,fsize,txt){} + void boot()override{this->text::boot();} + void tick()override{this->text::tick();} + void draw()override{ + Vector2 p=pos; + Vector2 charsize=MeasureTextEx(font," ",fs,0); + Vector2 minsize=MeasureTextEx(font,content.c_str(),fs,charsize.x/2); + float po=charsize.x>charsize.y?charsize.x/charsize.y:charsize.y/charsize.x;po=po*5; + int minh=(minsize.y>size.y)?minsize.y:size.y; + int minw=(minsize.x>size.x)?minsize.x:size.x; + DrawRectangle(pos.x-(po/2),pos.y-(po/2),minw+(po*1.1),minh+(po*1.1),c); + DrawTextEx(font,content.c_str(),p,fs,charsize.x/2,this->txc); + } + void exit()override{this->text::exit();} + }; + struct textinput :public text{ + bool active; + int cpos; + textinput():active(false),cpos(0){} + textinput(Texture2D* texture,Color txcol,Color color,float x,float y,float w,float h,Font f,float fsize):active(false),cpos(0){ + this->pos=Vector2{x,y};this->size=Vector2{x,y};this->texture=texture;this->c=color;this->font=f;this->content=""; + this->txc=txcol;this->fs=fsize; + } + void boot()override{this->text::boot();} + void tick()override{ + this->text::tick(); + Vector2 mouse=GetMousePosition(); + if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){ + active=CheckCollisionPointRec(mouse,{pos.x,pos.y,size.x,size.y}); + } + if(active){ + int key=GetCharPressed(); + while(key>0){ + if(key>=32&&key<=125){ + content+=static_cast(key); + cpos++; + } + key=GetCharPressed(); + } + if(IsKeyPressed(KEY_BACKSPACE)&&content.length()>0){ + content.pop_back(); + cpos--; + } + } + } + void draw()override{ + this->text::draw(); + if(active)DrawRectangle(pos.x+MeasureText(content.c_str(),fs),pos.y,2,fs,{0,0,0,127}); + } + void exit()override{this->text::exit();} + }; + struct textinputfield :public textfield{ + bool active; + int cpos; + textinputfield():active(false),cpos(0){} + textinputfield(Texture2D* texture,Color txcol,Color color,float x,float y,float w,float h,Font f,float fsize):active(false),cpos(0), + textfield(texture,txcol,color,x,y,w,h,f,fsize,""){} + void boot()override{this->textfield::boot();} + void tick()override{ + this->textfield::tick(); + Vector2 mouse=GetMousePosition(); + if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){ + active=CheckCollisionPointRec(mouse,{pos.x,pos.y,size.x,size.y}); + } + if(active){ + int key=GetCharPressed(); + while(key>0){ + if(key>=32&&key<=125){ + content+=static_cast(key); + cpos++; + } + key=GetCharPressed(); + } + if(IsKeyPressed(KEY_BACKSPACE)&&content.length()>0){ + content.pop_back(); + cpos--; + } + if(IsKeyPressed(KEY_ENTER)){ + content+='\n'; + cpos++; + } + } + } + void draw()override{ + this->textfield::draw(); + if(active){ + Vector2 p=pos; + float lh=fs+2; + std::string line=""; + for(char ch:content){ + if(ch=='\n'){ + p.y+=lh; + line=""; + }else{ + line+=ch; + } + } + DrawRectangle(p.x+MeasureText(line.c_str(),fs),p.y,2,fs,BLACK); + } + } + void exit()override{this->textfield::exit();} + }; } \ No newline at end of file diff --git a/games/endlauncher/src/main.cpp b/games/endlauncher/src/main.cpp index 97d7f0b..b6157d3 100644 --- a/games/endlauncher/src/main.cpp +++ b/games/endlauncher/src/main.cpp @@ -2,61 +2,52 @@ #include #include #include "netio.h" +#include +#include +#include + using namespace enginend; + +netio nete{}; + struct background: public virtual textured { background(Texture2D* texture,float x,float y,float w, float h) { this->pos=Vector2{x,y};this->size=Vector2{w,h}; this->texture=texture; this->justclicked=false; - } void boot()override{ img=LoadImageFromTexture(*this->texture); } void tick()override { - - Vector2 mp = Vector2(GetMousePositionDesktop()); - Vector2 wp = GetWindowPosition(); + Vector2 mp=Vector2(GetMousePositionDesktop()); + Vector2 wp=GetWindowPosition(); Vector2 rp=Vector2{mp.x-wp.x,mp.y-wp.y}; - if (IsMouseButtonDown(0)) { - if (rp.x >= 0 && rp.y >= 0 && rp.x < 600 && rp.y < 300) { - Color pix = GetImageColor(img, (int)rp.x, (int)(300 - rp.y)); - if (pix.a != 0) { - + if (IsMouseButtonDown(0)) { + if (rp.x>=0&&rp.y>=0&&rp.x<600&&rp.y<300) { + Color pix=GetImageColor(img, (int)rp.x, (int)(300-rp.y)); + if (pix.a!=0) { if (clicked==false) { clicked=true; - relmouse = rp; + relmouse=rp; } } } - }else { - clicked=false; - } + }else { + clicked=false; + } if (clicked) { - Vector2 nwp{ mp.x-relmouse.x, mp.y-relmouse.y }; - //todo: implement proper multi-monitor lmaooo - int it =GetMonitorCount(); - RenderTexture rt; - for (int i=0;i=mtp.x && mp.y>=mtp.y && mp.xmaxwpx?maxwpx:newwpx; - newwpy=newwpy>maxwpy?maxwpy:newwpy; + newwpx=newwpx>maxwpx?maxwpx:newwpx<0?0:newwpx; + newwpy=newwpy>maxwpy?maxwpy:newwpy<0?0:newwpy; SetWindowPosition(newwpx,newwpy); } } @@ -67,6 +58,44 @@ private: Vector2 relmouse; }; +struct logi: public virtual textfield { + logi(Texture2D* texture,Color textcol,Color color,float x,float y,float w,float h,Font f,float fs,std::string txt) { + this->pos=Vector2{x,y};this->size=Vector2{w,h};this->content=txt; + this->texture=texture;this->txc=textcol;this->c=color; + this->font=f; + this->fs=fs; + } + void draw() override { + Vector2 p=pos; + float spacing=fs/2.0f; + std::stringstream ss(content); + std::string line; + int lines=0; + + while (std::getline(ss, line)) { + if (lines%2==0) { + Vector2 charPos=p; + for (char& c : line) { + char str[2]={c, '\0'}; + Color fc=Color{255,0,255,255}; + if (c=='/'||c==':') { + fc=Color{255,255,0,255}; + } + + DrawTextEx(font, str, charPos, (float)fs, spacing, fc); + charPos.x+=MeasureTextEx(font, str, (float)fs, spacing).x; + } + } else { + DrawTextEx(font, line.c_str(), p, (float)fs, spacing, Color{0,255,255,255}); + } + + p.y+=(fs+2); + lines++; + } + } +}; + +void quit(){exit(0);} class test:public program { public: @@ -77,8 +106,8 @@ public: Texture2D menubtn[3]; button* buttons[8]; Texture2D buttonslabel[8]; - Font gamename; - bool vsync = true; + Font gamename,changelog,information; + bool vsync=true; scene s; RenderTexture2D target; Image img; @@ -86,12 +115,12 @@ public: const char* CONF() final{return "test.tdf";} test(){}; void boot() override { - tickrate=10; - framerate=10; - SetConfigFlags(FLAG_VSYNC_HINT|FLAG_WINDOW_UNDECORATED|FLAG_WINDOW_TRANSPARENT); + tickrate=15; + framerate=15; + SetConfigFlags(FLAG_WINDOW_UNDECORATED|FLAG_WINDOW_TRANSPARENT|FLAG_WINDOW_TOPMOST); tiny::error("is transparent lol"); - InitWindow(600,300,"test");target = LoadRenderTexture(600, 300); - img = GenImageColor(600, 300, BLANK); + InitWindow(600,300,"test");target=LoadRenderTexture(600, 300); + img=GenImageColor(600, 300, BLANK); SetTargetFPS(GetMonitorRefreshRate(GetCurrentMonitor())); this->tickrate=GetMonitorRefreshRate(GetCurrentMonitor()); bg=LoadTexture("res/launcher.png"); @@ -101,23 +130,33 @@ public: menubtn[0]=LoadTexture("res/btn.png"); menubtn[1]=LoadTexture("res/btnhover.png"); menubtn[2]=LoadTexture("res/btnpress.png"); + changelog=LoadFont("res/log.ttf"); SetTraceLogLevel(LOG_ERROR); - //468 - //58 - buttons[0]= new button(&menubtn[0], {255,255,255,255},468,58,96,16,nullptr); + buttons[0]=new button(&menubtn[0], {255,255,255,255},468,58,96,16,nullptr); buttonslabel[0]=LoadTexture("res/options.png"); - buttons[1]= new button(&menubtn[0], {255,255,255,255},468,58+(18*1),96,16,nullptr); + buttons[1]=new button(&menubtn[0], {255,255,255,255},468,58+(18*1),96,16,std::function([]() { + OpenURL("http://kosumi.ddns.net:60000/"); + })); buttonslabel[1]=LoadTexture("res/website.png"); - buttons[2]= new button(&menubtn[0], {255,255,255,255},468,58+(18*2),96,16,nullptr); + buttons[2]=new button(&menubtn[0], {255,255,255,255},468,58+(18*2),96,16,std::function([]() { + OpenURL("http://kosumi.ddns.net:60001/"); + })); buttonslabel[2]=LoadTexture("res/forums.png"); - buttons[3]= new button(&menubtn[0], {255,255,255,255},468,58+(18*3),96,16,nullptr); - buttons[4]= new button(&menubtn[0], {255,255,255,255},468,58+(18*4),96,16,nullptr); + buttons[3]=new button(&menubtn[0], {255,255,255,255},468,58+(18*3),96,16,std::function([]() { + OpenURL("https://github.com/kin-fuyuki/allgames/issues"); + })); + buttonslabel[3]=LoadTexture("res/help.png"); + buttons[4]=new button(&menubtn[0], {255,255,255,255},468,58+(18*4),96,16,std::function([]() { + nete.download(); + })); buttonslabel[4]=LoadTexture("res/update.png"); - buttons[5]= new button(&menubtn[0], {255,255,255,255},468,58+(18*5),96,16,nullptr); + buttons[5]=new button(&menubtn[0], {255,255,255,255},468,58+(18*5),96,16,nullptr); buttonslabel[5]=LoadTexture("res/verify.png"); - buttons[6]= new button(&menubtn[0], {255,255,255,255},468,58+(18*6)+15,96,16,nullptr); + buttons[6]=new button(&menubtn[0], {255,255,255,255},468,58+(18*6)+15,96,16,nullptr); buttonslabel[6]=LoadTexture("res/versions.png"); - buttons[7]= new button(&menubtn[0], {255,255,255,255},468,58+(18*7)+17,96,16,nullptr); + buttons[7]=new button(&menubtn[0], {255,255,255,255},468,58+(18*7)+17,96,16,std::function([]() { + quit(); + })); buttonslabel[7]=LoadTexture("res/exit.png"); playbtn[0]=LoadTexture("res/playoff.png"); playbtn[1]=LoadTexture("res/playon.png"); @@ -131,48 +170,71 @@ public: buttons[0],new textured(&buttonslabel[0],468,58,96,16), buttons[1],new textured(&buttonslabel[1],468,58+(18*1),96,16), buttons[2],new textured(&buttonslabel[2],468,58+(18*2),96,16), - buttons[3],//new textured(&buttonslabel[3],468,58+(18*3),96,16), + buttons[3],new textured(&buttonslabel[3],468,58+(18*3),96,16), buttons[4],new textured(&buttonslabel[4],468,58+(18*4),96,16), buttons[5],new textured(&buttonslabel[5],468,58+(18*5),96,16), buttons[6],new textured(&buttonslabel[6],468,58+(18*6)+15,96,16), buttons[7],new textured(&buttonslabel[7],468,58+(18*7)+17,96,16), new button(&playbtn[0], {255,255,255,255},406,(18*11)+17+9,153,59,nullptr), - + new logi(nullptr,Color{255,0,255,255},Color{0,0,0,0},90,58,466,159,changelog,8,nete.changelog), }; s.boot(); - } + int buttondelay=0; void tick() override { - if (shouldtick()) { - s.tick(); + for (button* b : buttons) { + if (b->hover) { + if (b->pressed) { + b->texture=&menubtn[2]; + buttondelay=5; + }else { + if (b->texture->id==menubtn[2].id) { + if(buttondelay<0) { + b->texture=&menubtn[1]; + } + }else { + b->texture=&menubtn[1]; + } + } + }else { + if (b->texture->id==menubtn[2].id) { + if(buttondelay<0) { + b->texture=&menubtn[0]; + } + }else { + b->texture=&menubtn[0]; + } + } } - + s.tick(); + buttondelay--; } + bool changedmenu=true; + bool itemchanged=true; void draw() override { BeginTextureMode(target); s.draw(); EndTextureMode(); - BeginDrawing(); ClearBackground(BLANK); DrawTexturePro(target.texture, {0, 0, 600, -300}, {0, 0, 600, 300}, {0, 0}, 0, WHITE); EndDrawing(); - - Vector2 mp = Vector2(GetMousePositionDesktop()); - Vector2 wp = GetWindowPosition(); + Vector2 mp=Vector2(GetMousePositionDesktop()); + Vector2 wp=GetWindowPosition(); Vector2 rp=Vector2{mp.x-wp.x,mp.y-wp.y}; - tiny::error("%f %f",rp.x,rp.y); - - if (rp.x >= 0 && rp.y >= 0 && rp.x < 600 && rp.y < 300) { - UnloadImage(img); - img = LoadImageFromTexture(target.texture); - Color pix = GetImageColor(img, (int)rp.x, (int)(300 - rp.y)); - if (pix.a == 0) { + if (rp.x>=0&&rp.y>=0&&rp.x<600&&rp.y<300) { + if (changedmenu) { + UnloadImage(img); + img=LoadImageFromTexture(target.texture); + changedmenu=false; + } + Color pix=GetImageColor(img, (int)rp.x, (int)(300-rp.y)); + if (pix.a==0) { SetWindowState(FLAG_WINDOW_MOUSE_PASSTHROUGH); - captured = false; + captured=false; } else { ClearWindowState(FLAG_WINDOW_MOUSE_PASSTHROUGH); - captured = true; + captured=true; } } } @@ -182,16 +244,51 @@ public: }; tiny::ErrorLevel tiny::level{6}; + int main(int argc, char *argv[]) { - netio nete{}; - nete.download(); + nete.start(); + nete.github(); tiny::startup((char*)"enginend test",(char*)"1.0"); test e; e.boot(); + + std::atomic running{true}; + + std::thread tickthread([&e, &running]() { + double tickrate=1.0/e.tickrate; + auto lasttick=std::chrono::high_resolution_clock::now(); + + while (running) { + auto now=std::chrono::high_resolution_clock::now(); + double elapsed=std::chrono::duration_cast>(now-lasttick).count(); + + if (elapsed>=tickrate) { + e.tick(); + lasttick=now; + } else { + std::this_thread::sleep_for(std::chrono::duration(tickrate-elapsed)); + } + } + }); + + double framerate=1.0/e.framerate; + auto lastframe=std::chrono::high_resolution_clock::now(); + while (!WindowShouldClose()) { - e.tick(); - e.draw(); + auto now=std::chrono::high_resolution_clock::now(); + double elapsed=std::chrono::duration_cast>(now-lastframe).count(); + + if (elapsed>=framerate) { + e.draw(); + lastframe=now; + } else { + WaitTime(framerate-elapsed); + } } + + running=false; + tickthread.join(); + e.exit(); return 0; } \ No newline at end of file diff --git a/games/endlauncher/src/netio.h b/games/endlauncher/src/netio.h index c41e730..9150e92 100644 --- a/games/endlauncher/src/netio.h +++ b/games/endlauncher/src/netio.h @@ -5,21 +5,41 @@ #include #include #include +#include +#ifndef GAMEPLATFORM +#define GAMEPLATFORM "l5.64" +#endif extern size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream); - +inline void makedirs(std::string path) { + size_t pos = 0; + while ((pos = path.find_first_of('/', pos)) != std::string::npos) { + std::string dir = path.substr(0, pos); + if (!dir.empty()) { +#ifdef _WIN32 + mkdir(dir.c_str(), 0); +#else + mkdir(dir.c_str(), 0755); +#endif + } + pos++; + } +} struct netio { netio()= default; std::string url="https://github.com/kin-fuyuki/forespend_cpp/releases/download/"; std::vector *versionhistory; - void download() { - CURL* curl = curl_easy_init(); + std::string changelog="could not connect to github\nplease check your internet connection"; + void start() { + CURL* curltdf = curl_easy_init(); CURLcode ret; - if (curl) { + if (curltdf) { FILE* history = fopen("versions.tdf", "wb"); - curl_easy_setopt(curl, CURLOPT_URL, "https://raw.githubusercontent.com/kin-fuyuki/allgames/refs/heads/master/versions.tdf"); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, history); - ret = curl_easy_perform(curl); + curl_easy_setopt(curltdf, CURLOPT_URL, "https://raw.githubusercontent.com/kin-fuyuki/allgames/refs/heads/master/versions.tdf"); + curl_easy_setopt(curltdf, CURLOPT_WRITEFUNCTION, write_data); + curl_easy_setopt(curltdf, CURLOPT_WRITEDATA, history); + ret = curl_easy_perform(curltdf); + curl_easy_cleanup(curltdf); + fclose(history); tiny::TDF_FILE fetchversions; fetchversions.filepath = "versions.tdf"; @@ -27,6 +47,7 @@ struct netio { boost::unordered_map* foreversions= fetchversions.getclass({"forespend"}); std::vector versions; for (auto version:*foreversions) { + tiny::error("path: %s",version.first.c_str()); if (version.second.type==tiny::TDF_Type::TDF_DEFINES) { versions=*(std::vector*)version.second.datapointer; } @@ -36,41 +57,106 @@ struct netio { float va = 0.0f, vb = 0.0f; char pa = ' ', pb = ' '; char rea = ' ', reb = ' '; - sscanf(a.c_str(), "%d.%f.%c.%c", &ra, &va, &pa, &rea); sscanf(b.c_str(), "%d.%f.%c.%c", &rb, &vb, &pb, &reb); - if (ra != rb) return ra > rb; if (va != vb) return va > vb; if (pa != pb) return pa > pb; return rea < reb; }); -#ifndef GAMEPLATFORM -#define GAMEPLATFORM "l5.64" -#endif + tiny::success("\n\nforespend versions:"); + for (auto version:versions) { + + tiny::warning("%s",version.c_str()); + } + tiny::success("found\n\n"); versionhistory=&versions; + } + + } + void github() { + CURL* curl; + CURLcode res; + FILE* commitsjson = fopen("commitsjson", "wb"); + curl = curl_easy_init(); + if (curl) { + std::string u = "https://api.github.com/repos/kin-fuyuki/allgames/commits"; + struct curl_slist* headers = NULL; + headers = curl_slist_append(headers, "User-Agent: C++-App"); // Required by GitHub + curl_easy_setopt(curl, CURLOPT_URL, u.c_str()); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, commitsjson); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10L); + res = curl_easy_perform(curl); + fclose(commitsjson); + changelog="changelog download error"; + if (res == CURLE_OK) { + try { + changelog="json read error"; + FILE* thecommits=fopen("commitsjson","rb"); + changelog="json parse error"; + nlohmann::json commits = nlohmann::json::parse(thecommits); + std::ostringstream oss; + std::vector monthNames = { + "", "jan", "feb", "mar", "apr", "may", "jun", + "jul", "aug", "sep", "oct", "nov", "dec" + }; + std::string lastMonth = ""; + std::string currentYear = ""; + int limit = std::min((int)commits.size(), 8); + for (int i = 0; i < limit; ++i) { + auto& item = commits[i]; + std::string message = item["commit"]["message"]; + std::string date = item["commit"]["author"]["date"]; // Format: 2025-12-21T13:08:50Z + // Extract components: YYYY-MM-DD and HH:MM:SS + std::string y = date.substr(0, 4); + std::string m = date.substr(5, 2); + std::string d = date.substr(8, 2); + std::string t = date.substr(11, 8); + // Format: MM/DD/YYYY HH:MM:SS + std::string first_line = message.substr(0, message.find('\n')); + oss << m << "/" << d << "/" << y << " " << t << "\n" << " " << first_line << "\n"; + } + changelog = oss.str(); + tiny::fatal("%s", changelog.c_str() ); + } catch (nlohmann::json::parse_error& e) { + tiny::fatal("JSON Parse Error: %s", e.what()); + } + } + + } + } + void download() { + CURLcode ret; std::string version=versionhistory->at(0); + tiny::success("using version: %s\ndownloading from: %s",version.c_str(),(url+version+"/"+GAMEPLATFORM+"."+version+".zip").c_str()); + + CURL*curl = curl_easy_init(); FILE* file = fopen(("fore."+version+".zip").c_str(), "wb"); - curl_easy_setopt(curl, CURLOPT_URL, (url+version+"/"+GAMEPLATFORM+"."+version+".zip").c_str()); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10L); + curl_easy_setopt(curl, CURLOPT_URL, "https://github.com/kin-fuyuki/forespend_cpp/releases/download/0.03.a.g/l5.64.0.03.a.g.zip"); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, file); ret = curl_easy_perform(curl); curl_easy_cleanup(curl); fclose(file); - + + makedirs("forespend/versions/"+version+"/"); int err=0; zip *z=zip_open("fore.0.03.a.g.zip",0,&err); if (z) { + zip_int64_t it=zip_get_num_entries(z, 0); for (zip_int64_t i = 0; i < it; ++i) { struct zip_stat st; zip_stat_init(&st); if (zip_stat_index(z, i, 0, &st) != 0) continue; - std::string name = st.name; std::string full = "forespend/versions/"+version+"/" + name; - if (name.back() == '/') { #ifdef _WIN32 mkdir(full.c_str(), 0); @@ -79,7 +165,6 @@ struct netio { #endif continue; } - size_t pos = full.find_last_of('/'); if (pos != std::string::npos) { std::string dir = full.substr(0, pos); @@ -89,7 +174,6 @@ struct netio { mkdir(dir.c_str(), 0755); #endif } - zip_file_t *zf = zip_fopen_index(z, i, 0); if (zf) { std::ofstream ofs(full, std::ios::binary); @@ -105,6 +189,5 @@ struct netio { zip_close(z); } } - } }; \ No newline at end of file diff --git a/versions.tdf b/versions.tdf index 1bf617d..5acfe81 100644 --- a/versions.tdf +++ b/versions.tdf @@ -1,3 +1,9 @@ { forespend 0.03.a.g -} \ No newline at end of file +#0.04.a.g +#0.4.a.g +#0.40.a.g +#4.0.a.g +} + +