From ea1f4364f1a9a9aab4870852cccd250cb6448e13 Mon Sep 17 00:00:00 2001 From: kin-fuyuki Date: Sat, 21 Feb 2026 14:16:46 -0300 Subject: [PATCH] licensing the project --- LICENSE | 41 + engine/src/scenes/node2d.h | 666 +++++++------ engine/src/scenes/node2drelative.h | 927 +++++++++--------- engine/src/scenes/node3d.h | 128 +++ games/endlauncher/src/main.cpp | 7 +- .../src/client/scenes/configmenu.cpp | 15 +- games/forespend/src/client/scenes/mainmenu.h | 13 +- 7 files changed, 980 insertions(+), 817 deletions(-) create mode 100644 LICENSE create mode 100644 engine/src/scenes/node3d.h diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..add2ee3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,41 @@ +enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series +Copyright (C) 2021-2026 Kin Fuyuki + +enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series is free software; You can redistribute it and/or modify it under the terms of: + - the GNU Affero General Public License version 3 as published by the Free Software Foundation. +You don't have to do anything special to accept the license and you don’t have to notify anyone which that you have made that decision. + +enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See your chosen license for more details. + +You should have received a copy of both licenses along with enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series. +If not, see . + + +There is a strong belief within us that the license we have chosen provides not only the best solution for providing you with the essential freedom necessary to use enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series within your projects, but also for maintaining enough copyleft strength for us to feel confident and secure with releasing our hard work to the public. For your convenience we've included our own interpretation of the license we chose, which can be seen below. + +Our interpretation of the GNU Affero General Public License version 3: (Quoted words are words in which there exists a definition within the license to avoid ambiguity.) + 1. You must always provide the source code, copyright and license information of enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series whenever you "convey" any part of enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series; + be it a verbatim copy or a modified copy. + 2. enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series was developed as a library and has therefore been designed without knowledge of your work; as such the following should be implied: + a) enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series was developed without knowledge of your work; as such the following should be implied: + i) enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series should not fall under a work which is "based on" your work. + ii) You should be free to use enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series in a work covered by the: + - GNU General Public License version 2 + - GNU Lesser General Public License version 2.1 + This is due to those licenses classifying enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series as a work which would fall under an "aggregate" work by their terms and definitions; + as such it should not be covered by their terms and conditions. The relevant passages start at: + - Line 129 of the GNU General Public License version 2 + - Line 206 of the GNU Lesser General Public License version 2.1 + b) If you have not "modified", "adapted" or "extended" enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series then your work should not be bound by this license, + as you are using enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series under the definition of an "aggregate" work. + c) If you have "modified", "adapted" or "extended" enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series then any of those modifications/extensions/adaptations which you have made + should indeed be bound by this license, as you are using enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series under the definition of a "based on" work. + +Our hopes is that our own interpretation of license aligns perfectly with your own values and goals for using our work freely and securely. If you have any questions at all about the licensing chosen for enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series you can email us directly at or you can get in touch with the license authors (the Free Software Foundation) at licensing@fsf.org to gain their opinion too. + +Alternatively you can provide feedback and acquire the support you need at our support forum. We'll definitely try and help you as soon as possible, and to the best of our ability; as we understand that user experience is everything, so we want to make you as happy as possible! So feel free to get in touch via our support forum and chat with other users of enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series here at: +https://github.com/kin-fuyuki/allgames/issues + +Thanks, and we hope you enjoy using enginend (the engine), forespend, descend, pretend (the .END game series) and the animatronical game series and that it's everything you ever hoped it could be. diff --git a/engine/src/scenes/node2d.h b/engine/src/scenes/node2d.h index 62bc66e..604b681 100644 --- a/engine/src/scenes/node2d.h +++ b/engine/src/scenes/node2d.h @@ -3,120 +3,130 @@ #include #include "nodes.h" -namespace enginend { - namespace nodes { - 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,rl::WHITE);} - void exit()override{delete texture;} - }; - struct animated : virtual public textured { - Image animimage; - int frames; - int currentframe; - int framedelay; - int framecounter; - unsigned int nextframeoffset; - int prevframe; +namespace enginend::nodes::twod { + 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,rl::WHITE);} + void exit()override{} + }; + struct animated : virtual public textured { + Image animimage; + int frames; + int currentframe; + int framedelay; + int framecounter; + unsigned int nextframeoffset; + int prevframe; - animated() : frames(0), currentframe(0), framedelay(6), framecounter(0), nextframeoffset(0) { - animimage.data = nullptr; - } + animated() : frames(0), currentframe(0), framedelay(6), framecounter(0), nextframeoffset(0) { + animimage.data = nullptr; + } - animated(const char* gifpath, Vector2 position, Vector2 size, int delay = 6) - : textured(nullptr, position.x, position.y, size.x, size.y), - framedelay(delay), currentframe(0), framecounter(0), frames(0), nextframeoffset(0) - { - animimage = LoadImageAnim(gifpath, &frames); - if (frames > 0) { - texture = new Texture2D(LoadTextureFromImage(animimage)); - } + animated(const char* gifpath, Vector2 position, Vector2 size, int delay = 6) + : textured(nullptr, position.x, position.y, size.x, size.y), + framedelay(delay), currentframe(0), framecounter(0), frames(0), nextframeoffset(0) + { + animimage = LoadImageAnim(gifpath, &frames); + if (frames > 0) { + texture = new Texture2D(LoadTextureFromImage(animimage)); } + } - void tick() override { - textured::tick(); - if (frames <= 1) return; + void tick() override { + textured::tick(); + if (frames <= 1) return; - framecounter++; - if (framecounter >= framedelay) { - framecounter = 0; - currentframe++; - if (currentframe >= frames) currentframe = 0; - nextframeoffset = animimage.width * animimage.height * 4 * currentframe; - } + framecounter++; + if (framecounter >= framedelay) { + framecounter = 0; + currentframe++; + if (currentframe >= frames) currentframe = 0; + nextframeoffset = animimage.width * animimage.height * 4 * currentframe; } - void draw() override { - - if (prevframe!=currentframe){ - prevframe=currentframe; - UpdateTexture(*this->texture,((unsigned char*)animimage.data)+nextframeoffset); - } - textured::draw(); + } + void draw() override { + + if (prevframe!=currentframe){ + prevframe=currentframe; + UpdateTexture(*this->texture,((unsigned char*)animimage.data)+nextframeoffset); } - void exit() override { - if (animimage.data) UnloadImage(animimage); - if (texture) { - UnloadTexture(*texture); - delete texture; - texture = nullptr; - } + textured::draw(); + } + void exit() override { + if (animimage.data) UnloadImage(animimage); + if (texture) { + UnloadTexture(*texture); + delete texture; + texture = nullptr; } - }; - 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}; + } + }; + 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: + float fs; + Color txc; + std::string content; + text(){fs=20;} + text(Texture2D* texture,enginend::theme* theme,float x,float y,float w,float h,float fsize,std::string txt): + fs(fsize),content(txt) + { + this->pos=Vector2{x,y};this->size=Vector2{w,h};this->texture=texture;this->theme=theme; + + 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{} - 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: - float fs; - Color txc; - std::string content; - text(){fs=20;} - text(Texture2D* texture,enginend::theme* theme,float x,float y,float w,float h,float fsize,std::string txt): - fs(fsize),content(txt) - { - this->pos=Vector2{x,y};this->size=Vector2{w,h};this->texture=texture;this->theme=theme; - + } + 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){ @@ -124,251 +134,239 @@ namespace enginend { 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(this->theme->font,content.c_str(),fs,1); - Vector2 charsize=MeasureTextEx(this->theme->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,this->theme->background); - DrawTextEx(this->theme->font,content.c_str(),pos,fs,1,this->theme->text); - } - void exit()override{this->tinted::exit();} - }; - struct button :virtual public tinted{ - std::function func; - bool pressed; - bool hover; - const bool isboolean; - bool boolean=false; - button():pressed(false),isboolean(false){} - button(Texture2D* texture,enginend::theme* theme,float x,float y,float w,float h,std::function f):func(f),pressed(false),isboolean(false){ - this->pos=Vector2{x,y};this->size=Vector2{w,h};this->texture=texture;this->c=theme->tint;this->theme=theme; - } - button(Texture2D* texture,enginend::theme* theme,float x,float y,float w,float h,std::function f,bool isboolean):func(f),pressed(false),isboolean(isboolean){ - this->pos=Vector2{x,y};this->size=Vector2{w,h};this->texture=texture;this->c=theme->tint;this->theme=theme; - } - void boot()override{this->tinted::boot();} - void tick()override{ - } - void draw()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; - } + } + void draw()override { + Vector2 minsize=MeasureTextEx(this->theme->font,content.c_str(),fs,1); + Vector2 charsize=MeasureTextEx(this->theme->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,this->theme->background); + DrawTextEx(this->theme->font,content.c_str(),pos,fs,1,this->theme->text); + } + void exit()override{this->tinted::exit();} + }; + struct button :virtual public tinted{ + std::function func; + bool pressed; + bool hover; + const bool isboolean; + bool boolean=false; + button():pressed(false),isboolean(false){} + button(Texture2D* texture,enginend::theme* theme,float x,float y,float w,float h,std::function f):func(f),pressed(false),isboolean(false){ + this->pos=Vector2{x,y};this->size=Vector2{w,h};this->texture=texture;this->c=theme->tint;this->theme=theme; + } + button(Texture2D* texture,enginend::theme* theme,float x,float y,float w,float h,std::function f,bool isboolean):func(f),pressed(false),isboolean(isboolean){ + this->pos=Vector2{x,y};this->size=Vector2{w,h};this->texture=texture;this->c=theme->tint;this->theme=theme; + } + void boot()override{this->tinted::boot();} + void tick()override{ + } + void draw()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{ - hover=false; + pressed=false; } - if (hover) { - if (pressed) { - c=isboolean?boolean? - this->theme->booleanbutton[5]:this->theme->booleanbutton[2]: - this->theme->button[2]; - }else { - c=isboolean?boolean? - this->theme->booleanbutton[4]:this->theme->booleanbutton[1]: - this->theme->button[1]; - } + }else{ + hover=false; + } + if (hover) { + if (pressed) { + c=isboolean?boolean? + this->theme->booleanbutton[5]:this->theme->booleanbutton[2]: + this->theme->button[2]; }else { c=isboolean?boolean? - this->theme->booleanbutton[3]:this->theme->booleanbutton[0]: - this->theme->button[0]; + this->theme->booleanbutton[4]:this->theme->booleanbutton[1]: + this->theme->button[1]; } - if(this->texture!=nullptr)DrawTexture(*texture,pos.x,pos.y,this->theme->tint); - else DrawRectangle(pos.x,pos.y,size.x,size.y,this->theme->tint); - + }else { + c=isboolean?boolean? + this->theme->booleanbutton[3]:this->theme->booleanbutton[0]: + this->theme->button[0]; } - void exit()override{this->tinted::exit();} - }; - struct labeledbutton :virtual public button { - std::string label; - Font font; - int fs; - Color txc; - labeledbutton(std::string name,Texture2D* texture,enginend::theme* theme, - float x,float y,float w,float h,std::function f,int size):fs(size){ - this->pos=Vector2{x,y};this->size=Vector2{w,h};this->texture=texture;this->theme=theme; - this->func=f;this->pressed=false; - this->label=name; - } - void boot()override{this->button::boot();} - void tick()override{this->button::tick();} - void draw()override{ - this->button::draw(); - - if (hover) { - if (pressed) { - txc=isboolean?boolean? - this->theme->booleantext[5]:this->theme->booleantext[2]: - this->theme->buttontext[2]; - }else { - txc=isboolean?boolean? - this->theme->booleantext[4]:this->theme->booleantext[1]: - this->theme->buttontext[1]; - } + if(this->texture!=nullptr)DrawTexture(*texture,pos.x,pos.y,this->theme->tint); + else DrawRectangle(pos.x,pos.y,size.x,size.y,this->theme->tint); + + } + void exit()override{this->tinted::exit();} + }; + struct labeledbutton :virtual public button { + std::string label; + Font font; + int fs; + Color txc; + labeledbutton(std::string name,Texture2D* texture,enginend::theme* theme, + float x,float y,float w,float h,std::function f,int size):fs(size){ + this->pos=Vector2{x,y};this->size=Vector2{w,h};this->texture=texture;this->theme=theme; + this->func=f;this->pressed=false; + this->label=name; + } + void boot()override{this->button::boot();} + void tick()override{this->button::tick();} + void draw()override{ + this->button::draw(); + + if (hover) { + if (pressed) { + txc=isboolean?boolean? + this->theme->booleantext[5]:this->theme->booleantext[2]: + this->theme->buttontext[2]; }else { txc=isboolean?boolean? - this->theme->booleantext[3]:this->theme->booleantext[0]: - this->theme->buttontext[0]; + this->theme->booleantext[4]:this->theme->booleantext[1]: + this->theme->buttontext[1]; } - 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); + }else { + txc=isboolean?boolean? + this->theme->booleantext[3]:this->theme->booleantext[0]: + this->theme->buttontext[0]; } - void exit()override{this->button::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; + 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 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 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,rl::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,enginend::theme* theme,float x,float y,float w,float h,float fsize,std::string txt): + text(texture,theme,x,y,w,h,fsize,txt){} + void boot()override{this->text::boot();} + void tick()override{this->text::tick();} + void draw()override{ + Vector2 p=pos; + Vector2 charsize=MeasureTextEx(this->theme->font," ",fs,0); + Vector2 minsize=MeasureTextEx(this->theme->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(this->theme->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,enginend::theme* theme,float x,float y,float w,float h,float fsize):active(false),cpos(0){ + this->pos=Vector2{x,y};this->size=Vector2{x,y};this->texture=texture;this->theme=theme;this->content=""; + 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}); } - void draw()override{ - DrawRectangle(pos.x,pos.y,size.x,size.y,rl::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,enginend::theme* theme,float x,float y,float w,float h,float fsize,std::string txt): - text(texture,theme,x,y,w,h,fsize,txt){} - void boot()override{this->text::boot();} - void tick()override{this->text::tick();} - void draw()override{ - Vector2 p=pos; - Vector2 charsize=MeasureTextEx(this->theme->font," ",fs,0); - Vector2 minsize=MeasureTextEx(this->theme->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(this->theme->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,enginend::theme* theme,float x,float y,float w,float h,float fsize):active(false),cpos(0){ - this->pos=Vector2{x,y};this->size=Vector2{x,y};this->texture=texture;this->theme=theme;this->content=""; - 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,enginend::theme* theme,float x,float y,float w,float h,float fsize):active(false),cpos(0), - textfield(texture,theme,x,y,w,h,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'; + 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->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; - } + } + 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,enginend::theme* theme,float x,float y,float w,float h,float fsize):active(false),cpos(0), + textfield(texture,theme,x,y,w,h,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++; } - DrawRectangle(p.x+MeasureText(line.c_str(),fs),p.y,2,fs,rl::BLACK); + key=GetCharPressed(); + } + if(IsKeyPressed(KEY_BACKSPACE)&&content.length()>0){ + content.pop_back(); + cpos--; + } + if(IsKeyPressed(KEY_ENTER)){ + content+='\n'; + cpos++; } } - void exit()override{this->textfield::exit();} - }; - } -} \ No newline at end of file + } + 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,rl::BLACK); + } + } + void exit()override{this->textfield::exit();} + }; +} diff --git a/engine/src/scenes/node2drelative.h b/engine/src/scenes/node2drelative.h index 572f5e3..06cc329 100644 --- a/engine/src/scenes/node2drelative.h +++ b/engine/src/scenes/node2drelative.h @@ -3,469 +3,466 @@ #include "nodes.h" #include -namespace enginend{ - namespace nodes{ - namespace relative { - struct node2d :public node { - double x; - double y; - double w; - double h; - node2d(){x=0;y=0;w=0;h=0;} - node2d(double x,double y,double w=0,double h=0):x(x),y(y),w(w),h(h){} - }; - struct rect :virtual public node2d{ - rect(){} - rect(double x,double y,double w,double h):node2d(x,y,w,h){} - }; - struct textured :virtual public rect{ - Texture2D* texture; - textured(){texture=nullptr;} - textured(Texture2D* texture,double x,double y,double w,double h):texture(texture),rect(x,y,w,h){} - void boot() override{} - void tick() override{} - void draw()override{ - if(texture==nullptr)return; - float sw=GetScreenWidth(); - float sh=GetScreenHeight(); - float ax=x*sw; - float ay=y*sh; - float aw=w*sw; - float ah=h*sh; - tiny::echo("og: %f %f %f %f", x,y,w,h); - tiny::echo("transformed: %f %f %f %f", ax, ay, aw, ah); - DrawTexturePro(*texture,{0,0,(float)texture->width,(float)texture->height},{ax,ay,aw,ah},{0,0},0,rl::WHITE); - } - void exit()override { - if(texture){ - UnloadTexture(*texture); - delete texture; - texture=nullptr; - } - } - }; - struct animated :virtual public textured{ - Image animimage; - int frames; - int currentframe; - int framedelay; - int framecounter; - int prevframe; - unsigned int nextframeoffset; - animated():frames(0),currentframe(1),framedelay(6),framecounter(0),nextframeoffset(0){ - animimage.data=nullptr; - prevframe=currentframe; - } - animated(const char* gifpath,double x,double y,double w,double h,int delay=6): - textured(nullptr,x,y,w,h),framedelay(delay),currentframe(1),framecounter(0),frames(0),nextframeoffset(0) - { - prevframe=currentframe; - this->x=x; this->y=y; this->w=w; this->h=h; - animimage=LoadImageAnim(gifpath,&frames); - if(frames>0){ - texture=new Texture2D(LoadTextureFromImage(animimage)); - } - } - void tick()override{ - if(frames<=1)return; - framecounter++; - if(framecounter>=framedelay){ - framecounter=0; - currentframe++; - if(currentframe>=frames)currentframe=0; - nextframeoffset=animimage.width*animimage.height*4*currentframe; - tiny::echo("updating node\nframes: %i\n current frame: %i",frames,currentframe); - tiny::echo("%i",nextframeoffset); - } - } - void draw()override { - if (prevframe!=currentframe){ - prevframe=currentframe; - UpdateTexture(*this->texture,((unsigned char*)animimage.data)+nextframeoffset); - } - textured::draw(); - } - void exit()override{ - if(animimage.data)UnloadImage(animimage); - textured::exit(); - } - }; - struct colored :virtual public rect{ - Color c; - colored(){} - colored(Color color,double x,double y,double w,double h):c(color),rect(x,y,w,h){} - void boot()override{} - void tick()override{} - void draw()override{ - float sw=GetScreenWidth(); - float sh=GetScreenHeight(); - float ax=x*sw; - float ay=y*sh; - float aw=w*sw; - float ah=h*sh; - DrawRectangle(ax,ay,aw,ah,c); - } - void exit()override{} - }; - struct tinted :virtual public colored,virtual public textured{ - tinted(){} - tinted(Texture2D* texture,Color color,double x,double y,double w,double h): - node2d(x,y,w,h), - rect(x,y,w,h), - colored(color,x,y,w,h), - textured(texture,x,y,w,h) - {} - void boot()override{} - void tick()override{} - void draw()override{ - if(texture==nullptr) { - colored::draw(); - return; - } - float sw=GetScreenWidth(); - float sh=GetScreenHeight(); - float ax=x*sw; - float ay=y*sh; - float aw=w*sw; - float ah=h*sh; - DrawTexturePro(*texture,{0,0,(float)texture->width,(float)texture->height},{ax,ay,aw,ah},{0,0},0,c); - } - void exit()override{ - textured::exit(); - } - }; - struct text :public tinted { - protected: - std::string result; - public: - float fs; - std::string content; - text(){fs=20;} - text(Texture2D* texture,enginend::theme* theme,double x,double y,double w,double h,float fsize,std::string txt): - //tinted(texture,color,x,y,w,h), - fs(fsize),content(txt) - { - this->x=x;this->y=y;this->w=w;this->h=h; - this->texture=texture;this->theme=theme; - 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{} - void tick()override { - 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 { - float sw=GetScreenWidth(); - float sh=GetScreenHeight(); - float ax=x*sw; - float ay=y*sh; - - float aw=w*sw; - float ah=h*sh; - tiny::echo("og: %f %f %f %f", x,y,w,h); - tiny::echo("drawing text: %s", content.c_str()); - tiny::echo("transformed: %f %f %f %f", ax, ay, aw, ah); - Vector2 minsize=MeasureTextEx(this->theme->font,content.c_str(),fs,1); - Vector2 charsize=MeasureTextEx(this->theme->font," ",fs,1); - float p=charsize.x>charsize.y?charsize.x/minsize.x:charsize.y/minsize.y; - p=p*2; - int minh=(minsize.y>ah)?minsize.y:ah; - int minw=(minsize.x>aw)?minsize.x:aw; - DrawRectangle(ax-charsize.x,ay-charsize.y,minw+p,minh+p,this->theme->background); - DrawTextEx(this->theme->font,content.c_str(),{ax,ay},fs,1,this->theme->text); - DrawRectangleLines(ax, ay, aw, ah, this->theme->border); - } - void exit()override{ - tinted::exit(); - } - }; - struct button :virtual public tinted{ - std::function func; - bool pressed; - bool hover; - const bool isboolean; - bool boolean=false; - button():func(nullptr),pressed(false),hover(false),isboolean(false){} - button(Texture2D* texture,enginend::theme* theme,double x,double y,double w,double h,std::function f):func(f),pressed(false),hover(false),isboolean(false) { - this->theme=theme;this->texture=texture;this->x=x;this->y=y;this->w=w;this->h=h; - }button(Texture2D* texture,enginend::theme* theme,double x,double y,double w,double h,std::function f,bool isboolean):func(f),pressed(false),hover(false),isboolean(isboolean) { - this->theme=theme;this->texture=texture;this->x=x;this->y=y;this->w=w;this->h=h; - } - void boot()override{} - void tick()override{ - } - void draw()override { - - Vector2 mouse=GetMousePosition(); - float sw=GetScreenWidth(); - float sh=GetScreenHeight(); - Rectangle r={float(x*sw),float(y*sh),float(w*sw),float(h*sh)}; - if(CheckCollisionPointRec(mouse,r)){hover=true; - if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){ - pressed=true; - c=isboolean?boolean? - this->theme->booleanbutton[5]:this->theme->booleanbutton[2]: - this->theme->button[2]; - if(func)func(); - }else{ - pressed=false; - c=isboolean?boolean? - this->theme->booleanbutton[4]:this->theme->booleanbutton[1]: - this->theme->button[1]; - } - }else{ - hover=false; - pressed=false; - c=isboolean?boolean? - this->theme->booleanbutton[3]:this->theme->booleanbutton[0]: - this->theme->button[0]; - } - float ax=x*sw; - float ay=y*sh; - float aw=w*sw; - float ah=h*sh; - DrawRectangle(ax,ay,aw,ah,c); - DrawRectangleLines(ax, ay, aw, ah, this->theme->border); - } - void exit()override{ - tinted::exit(); - } - }; - struct labeledbutton :virtual public button { - std::string label; - int fs; - Color txc; - labeledbutton(std::string name,Texture2D* texture,enginend::theme*theme, - double x,double y,double w,double h,std::function f,int size):fs(size),label(name), - button(texture,theme,x,y,w,h,f) - {} - labeledbutton(std::string name,Texture2D* texture,enginend::theme*theme, - double x,double y,double w,double h,std::function f, - int size,bool isboolean):fs(size),label(name), - button(texture,theme,x,y,w,h,f,isboolean) - {} - void boot()override{} - void tick()override{ - button::tick(); - } - void draw()override{ - button::draw(); - float sw=GetScreenWidth(); - float sh=GetScreenHeight(); - float ax=x*sw; - float ay=y*sh; - float aw=w*sw; - float ah=h*sh; - tiny::echo("ax %f x %f sw %f",ax,x,sw); - tiny::echo("ay %f y %f sh %f",ay,y,sh); - tiny::echo("aw %f w %f sw %f",aw,w,sw); - tiny::echo("ah %f h %f sh %f",ah,h,sh); - Vector2 tsize=MeasureTextEx(this->theme->font,label.c_str(),fs,1); - Vector2 tpos={ - ax+(aw-tsize.x)/2, - ay+(ah-tsize.y)/2 - }; - tiny::echo("tsize\nw %f h %f",tsize.x,tsize.y); - tiny::echo("tpos\nx %f y %f",tpos.x,tpos.y); - if (hover) { - if (pressed) { - txc=isboolean?boolean? - this->theme->booleantext[5]:this->theme->booleantext[2]: - this->theme->buttontext[2]; - }else { - txc=isboolean?boolean? - this->theme->booleantext[4]:this->theme->booleantext[1]: - this->theme->buttontext[1]; - } - }else { - txc=isboolean?boolean? - this->theme->booleantext[3]:this->theme->booleantext[0]: - this->theme->buttontext[0]; - } - DrawTextEx(this->theme->font,label.c_str(),tpos,fs,1,txc); - DrawRectangleLinesEx({ax, ay, aw, ah},5., this->theme->border); - } - void exit()override{ - button::exit(); - } - }; - struct slider :virtual public tinted{ - float val; - float minv; - float maxv; - slider():val(0),minv(0),maxv(1){} - slider(Texture2D* texture,Color color,double x,double y,double w,double h,float min,float max,float v):val(v),minv(min),maxv(max),tinted(texture,color,x,y,w,h){} - void boot()override{} - void tick()override{ - Vector2 mouse=GetMousePosition(); - float sw=GetScreenWidth(); - float sh=GetScreenHeight(); - Rectangle r={float(x*sw),float(y*sh),float(w*sw),float(h*sh)}; - if(CheckCollisionPointRec(mouse,r)&&IsMouseButtonDown(MOUSE_LEFT_BUTTON)){ - float t=(mouse.x-(x*sw))/(w*sw); - val=minv+t*(maxv-minv); - if(valmaxv)val=maxv; - } - } - void draw()override{ - float sw=GetScreenWidth(); - float sh=GetScreenHeight(); - float ax=x*sw; - float ay=y*sh; - float aw=w*sw; - float ah=h*sh; - DrawRectangle(ax,ay,aw,ah,rl::DARKGRAY); - float t=(val-minv)/(maxv-minv); - DrawRectangle(ax,ay,aw*t,ah,c); - } - void exit()override{ - tinted::exit(); - } - }; - struct textfield :public text{ - textfield(){} - textfield(Texture2D* texture,enginend::theme *theme,double x,double y,double w,double h,float fsize,std::string txt): - text(texture,theme,x,y,w,h,fsize,txt){} - void boot()override{} - void tick()override{ - text::tick(); - } - void draw()override{ - float sw=GetScreenWidth(); - float sh=GetScreenHeight(); - float ax=x*sw; - float ay=y*sh; - float aw=w*sw; - float ah=h*sh; - Vector2 charsize=MeasureTextEx(this->theme->font," ",fs,0); - Vector2 minsize=MeasureTextEx(this->theme->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>ah)?minsize.y:ah; - int minw=(minsize.x>aw)?minsize.x:aw; - DrawRectangle(ax-(po/2),ay-(po/2),minw+(po*1.1),minh+(po*1.1),this->theme->textfieldbg); - DrawTextEx(this->theme->font,content.c_str(),{ax,ay},fs,charsize.x/2,this->theme->text); - } - void exit()override{ - text::exit(); - } - }; - struct textinput :public text{ - bool active; - int cpos; - textinput():active(false),cpos(0){} - textinput(Texture2D* texture,enginend::theme *theme,double x,double y,double w,double h,float fsize):active(false),cpos(0), - text(texture,theme,x,y,w,h,fsize,""){} - void boot()override{} - void tick()override{ - text::tick(); - Vector2 mouse=GetMousePosition(); - float sw=GetScreenWidth(); - float sh=GetScreenHeight(); - Rectangle r={float(x*sw),float(y*sh),float(w*sw),float(h*sh)}; - if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){ - active=CheckCollisionPointRec(mouse,r); - } - 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{ - text::draw(); - if(active){ - float sw=GetScreenWidth(); - float sh=GetScreenHeight(); - float ax=x*sw; - float ay=y*sh; - DrawRectangle(ax+MeasureTextEx(this->theme->font,content.c_str(),fs,1).x,ay,2,fs,{0,0,0,127}); - } - } - void exit()override{ - text::exit(); - } - }; - struct textinputfield :public textfield{ - bool active; - int cpos; - textinputfield():active(false),cpos(0){} - textinputfield(Texture2D* texture,enginend::theme *theme,double x,double y,double w,double h,float fsize):active(false),cpos(0), - textfield(texture,theme,x,y,w,h,fsize,""){} - void boot()override{} - void tick()override{ - textfield::tick(); - Vector2 mouse=GetMousePosition(); - float sw=GetScreenWidth(); - float sh=GetScreenHeight(); - Rectangle r={float(x*sw),float(y*sh),float(w*sw),float(h*sh)}; - if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){ - active=CheckCollisionPointRec(mouse,r); - } - 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{ - textfield::draw(); - if(active){ - float sw=GetScreenWidth(); - float sh=GetScreenHeight(); - float ax=x*sw; - float ay=y*sh; - float lh=fs+2; - Vector2 p={ax,ay}; - std::string line=""; - for(char ch:content){ - if(ch=='\n'){ - p.y+=lh; - line=""; - }else{ - line+=ch; - } - } - DrawRectangle(p.x+MeasureTextEx(this->theme->font,line.c_str(),fs,1).x,p.y,2,fs,rl::BLACK); - } - } - void exit()override{ - textfield::exit(); - } - }; +namespace enginend::nodes::twod::relative { + struct node2d :public node { + double x; + double y; + double w; + double h; + node2d(){x=0;y=0;w=0;h=0;} + node2d(double x,double y,double w=0,double h=0):x(x),y(y),w(w),h(h){} + }; + struct rect :virtual public node2d{ + rect(){} + rect(double x,double y,double w,double h):node2d(x,y,w,h){} + }; + struct textured :virtual public rect{ + Texture2D* texture; + textured(){texture=nullptr;} + textured(Texture2D* texture,double x,double y,double w,double h):texture(texture),rect(x,y,w,h){} + void boot() override{} + void tick() override{} + void draw()override{ + if(texture==nullptr)return; + float sw=GetScreenWidth(); + float sh=GetScreenHeight(); + float ax=x*sw; + float ay=y*sh; + float aw=w*sw; + float ah=h*sh; + tiny::echo("og: %f %f %f %f", x,y,w,h); + tiny::echo("transformed: %f %f %f %f", ax, ay, aw, ah); + DrawTexturePro(*texture,{0,0,(float)texture->width,(float)texture->height},{ax,ay,aw,ah},{0,0},0,rl::WHITE); } - } -} \ No newline at end of file + void exit()override { + if(texture){ + UnloadTexture(*texture); + delete texture; + texture=nullptr; + } + } + }; + struct animated :virtual public textured{ + Image animimage; + int frames; + int currentframe; + int framedelay; + int framecounter; + int prevframe; + unsigned int nextframeoffset; + animated():frames(0),currentframe(1),framedelay(6),framecounter(0),nextframeoffset(0){ + animimage.data=nullptr; + prevframe=currentframe; + } + animated(const char* gifpath,double x,double y,double w,double h,int delay=6): + textured(nullptr,x,y,w,h),framedelay(delay),currentframe(1),framecounter(0),frames(0),nextframeoffset(0) + { + prevframe=currentframe; + this->x=x; this->y=y; this->w=w; this->h=h; + animimage=LoadImageAnim(gifpath,&frames); + if(frames>0){ + texture=new Texture2D(LoadTextureFromImage(animimage)); + } + } + void tick()override{ + if(frames<=1)return; + framecounter++; + if(framecounter>=framedelay){ + framecounter=0; + currentframe++; + if(currentframe>=frames)currentframe=0; + nextframeoffset=animimage.width*animimage.height*4*currentframe; + tiny::echo("updating node\nframes: %i\n current frame: %i",frames,currentframe); + tiny::echo("%i",nextframeoffset); + } + } + void draw()override { + if (prevframe!=currentframe){ + prevframe=currentframe; + UpdateTexture(*this->texture,((unsigned char*)animimage.data)+nextframeoffset); + } + textured::draw(); + } + void exit()override{ + if(animimage.data)UnloadImage(animimage); + textured::exit(); + } + }; + struct colored :virtual public rect{ + Color c; + colored(){} + colored(Color color,double x,double y,double w,double h):c(color),rect(x,y,w,h){} + void boot()override{} + void tick()override{} + void draw()override{ + float sw=GetScreenWidth(); + float sh=GetScreenHeight(); + float ax=x*sw; + float ay=y*sh; + float aw=w*sw; + float ah=h*sh; + DrawRectangle(ax,ay,aw,ah,c); + } + void exit()override{} + }; + struct tinted :virtual public colored,virtual public textured{ + tinted(){} + tinted(Texture2D* texture,Color color,double x,double y,double w,double h): + node2d(x,y,w,h), + rect(x,y,w,h), + colored(color,x,y,w,h), + textured(texture,x,y,w,h) + {} + void boot()override{} + void tick()override{} + void draw()override{ + if(texture==nullptr) { + colored::draw(); + return; + } + float sw=GetScreenWidth(); + float sh=GetScreenHeight(); + float ax=x*sw; + float ay=y*sh; + float aw=w*sw; + float ah=h*sh; + DrawTexturePro(*texture,{0,0,(float)texture->width,(float)texture->height},{ax,ay,aw,ah},{0,0},0,c); + } + void exit()override{ + textured::exit(); + } + }; + struct text :public tinted { + protected: + std::string result; + public: + float fs; + std::string content; + text(){fs=20;} + text(Texture2D* texture,enginend::theme* theme,double x,double y,double w,double h,float fsize,std::string txt): + //tinted(texture,color,x,y,w,h), + fs(fsize),content(txt) + { + this->x=x;this->y=y;this->w=w;this->h=h; + this->texture=texture;this->theme=theme; + 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{} + void tick()override { + 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 { + float sw=GetScreenWidth(); + float sh=GetScreenHeight(); + float ax=x*sw; + float ay=y*sh; + + float aw=w*sw; + float ah=h*sh; + tiny::echo("og: %f %f %f %f", x,y,w,h); + tiny::echo("drawing text: %s", content.c_str()); + tiny::echo("transformed: %f %f %f %f", ax, ay, aw, ah); + Vector2 minsize=MeasureTextEx(this->theme->font,content.c_str(),fs,1); + Vector2 charsize=MeasureTextEx(this->theme->font," ",fs,1); + float p=charsize.x>charsize.y?charsize.x/minsize.x:charsize.y/minsize.y; + p=p*2; + int minh=(minsize.y>ah)?minsize.y:ah; + int minw=(minsize.x>aw)?minsize.x:aw; + DrawRectangle(ax-charsize.x,ay-charsize.y,minw+p,minh+p,this->theme->background); + DrawTextEx(this->theme->font,content.c_str(),{ax,ay},fs,1,this->theme->text); + DrawRectangleLines(ax, ay, aw, ah, this->theme->border); + } + void exit()override{ + tinted::exit(); + } + }; + struct button :virtual public tinted{ + std::function func; + bool pressed; + bool hover; + const bool isboolean; + bool boolean=false; + button():func(nullptr),pressed(false),hover(false),isboolean(false){} + button(Texture2D* texture,enginend::theme* theme,double x,double y,double w,double h,std::function f):func(f),pressed(false),hover(false),isboolean(false) { + this->theme=theme;this->texture=texture;this->x=x;this->y=y;this->w=w;this->h=h; + }button(Texture2D* texture,enginend::theme* theme,double x,double y,double w,double h,std::function f,bool isboolean):func(f),pressed(false),hover(false),isboolean(isboolean) { + this->theme=theme;this->texture=texture;this->x=x;this->y=y;this->w=w;this->h=h; + } + void boot()override{} + void tick()override{ + } + void draw()override { + + Vector2 mouse=GetMousePosition(); + float sw=GetScreenWidth(); + float sh=GetScreenHeight(); + Rectangle r={float(x*sw),float(y*sh),float(w*sw),float(h*sh)}; + if(CheckCollisionPointRec(mouse,r)){hover=true; + if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){ + pressed=true; + c=isboolean?boolean? + this->theme->booleanbutton[5]:this->theme->booleanbutton[2]: + this->theme->button[2]; + if(func)func(); + }else{ + pressed=false; + c=isboolean?boolean? + this->theme->booleanbutton[4]:this->theme->booleanbutton[1]: + this->theme->button[1]; + } + }else{ + hover=false; + pressed=false; + c=isboolean?boolean? + this->theme->booleanbutton[3]:this->theme->booleanbutton[0]: + this->theme->button[0]; + } + float ax=x*sw; + float ay=y*sh; + float aw=w*sw; + float ah=h*sh; + DrawRectangle(ax,ay,aw,ah,c); + DrawRectangleLines(ax, ay, aw, ah, this->theme->border); + } + void exit()override{ + tinted::exit(); + } + }; + struct labeledbutton :virtual public button { + std::string label; + int fs; + Color txc; + labeledbutton(std::string name,Texture2D* texture,enginend::theme*theme, + double x,double y,double w,double h,std::function f,int size):fs(size),label(name), + button(texture,theme,x,y,w,h,f) + {} + labeledbutton(std::string name,Texture2D* texture,enginend::theme*theme, + double x,double y,double w,double h,std::function f, + int size,bool isboolean):fs(size),label(name), + button(texture,theme,x,y,w,h,f,isboolean) + {} + void boot()override{} + void tick()override{ + button::tick(); + } + void draw()override{ + button::draw(); + float sw=GetScreenWidth(); + float sh=GetScreenHeight(); + float ax=x*sw; + float ay=y*sh; + float aw=w*sw; + float ah=h*sh; + tiny::echo("ax %f x %f sw %f",ax,x,sw); + tiny::echo("ay %f y %f sh %f",ay,y,sh); + tiny::echo("aw %f w %f sw %f",aw,w,sw); + tiny::echo("ah %f h %f sh %f",ah,h,sh); + Vector2 tsize=MeasureTextEx(this->theme->font,label.c_str(),fs,1); + Vector2 tpos={ + ax+(aw-tsize.x)/2, + ay+(ah-tsize.y)/2 + }; + tiny::echo("tsize\nw %f h %f",tsize.x,tsize.y); + tiny::echo("tpos\nx %f y %f",tpos.x,tpos.y); + if (hover) { + if (pressed) { + txc=isboolean?boolean? + this->theme->booleantext[5]:this->theme->booleantext[2]: + this->theme->buttontext[2]; + }else { + txc=isboolean?boolean? + this->theme->booleantext[4]:this->theme->booleantext[1]: + this->theme->buttontext[1]; + } + }else { + txc=isboolean?boolean? + this->theme->booleantext[3]:this->theme->booleantext[0]: + this->theme->buttontext[0]; + } + DrawTextEx(this->theme->font,label.c_str(),tpos,fs,1,txc); + DrawRectangleLinesEx({ax, ay, aw, ah},5., this->theme->border); + } + void exit()override{ + button::exit(); + } + }; + struct slider :virtual public tinted{ + float val; + float minv; + float maxv; + slider():val(0),minv(0),maxv(1){} + slider(Texture2D* texture,Color color,double x,double y,double w,double h,float min,float max,float v):val(v),minv(min),maxv(max),tinted(texture,color,x,y,w,h){} + void boot()override{} + void tick()override{ + Vector2 mouse=GetMousePosition(); + float sw=GetScreenWidth(); + float sh=GetScreenHeight(); + Rectangle r={float(x*sw),float(y*sh),float(w*sw),float(h*sh)}; + if(CheckCollisionPointRec(mouse,r)&&IsMouseButtonDown(MOUSE_LEFT_BUTTON)){ + float t=(mouse.x-(x*sw))/(w*sw); + val=minv+t*(maxv-minv); + if(valmaxv)val=maxv; + } + } + void draw()override{ + float sw=GetScreenWidth(); + float sh=GetScreenHeight(); + float ax=x*sw; + float ay=y*sh; + float aw=w*sw; + float ah=h*sh; + DrawRectangle(ax,ay,aw,ah,rl::DARKGRAY); + float t=(val-minv)/(maxv-minv); + DrawRectangle(ax,ay,aw*t,ah,c); + } + void exit()override{ + tinted::exit(); + } + }; + struct textfield :public text{ + textfield(){} + textfield(Texture2D* texture,enginend::theme *theme,double x,double y,double w,double h,float fsize,std::string txt): + text(texture,theme,x,y,w,h,fsize,txt){} + void boot()override{} + void tick()override{ + text::tick(); + } + void draw()override{ + float sw=GetScreenWidth(); + float sh=GetScreenHeight(); + float ax=x*sw; + float ay=y*sh; + float aw=w*sw; + float ah=h*sh; + Vector2 charsize=MeasureTextEx(this->theme->font," ",fs,0); + Vector2 minsize=MeasureTextEx(this->theme->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>ah)?minsize.y:ah; + int minw=(minsize.x>aw)?minsize.x:aw; + DrawRectangle(ax-(po/2),ay-(po/2),minw+(po*1.1),minh+(po*1.1),this->theme->textfieldbg); + DrawTextEx(this->theme->font,content.c_str(),{ax,ay},fs,charsize.x/2,this->theme->text); + } + void exit()override{ + text::exit(); + } + }; + struct textinput :public text{ + bool active; + int cpos; + textinput():active(false),cpos(0){} + textinput(Texture2D* texture,enginend::theme *theme,double x,double y,double w,double h,float fsize):active(false),cpos(0), + text(texture,theme,x,y,w,h,fsize,""){} + void boot()override{} + void tick()override{ + text::tick(); + Vector2 mouse=GetMousePosition(); + float sw=GetScreenWidth(); + float sh=GetScreenHeight(); + Rectangle r={float(x*sw),float(y*sh),float(w*sw),float(h*sh)}; + if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){ + active=CheckCollisionPointRec(mouse,r); + } + 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{ + text::draw(); + if(active){ + float sw=GetScreenWidth(); + float sh=GetScreenHeight(); + float ax=x*sw; + float ay=y*sh; + DrawRectangle(ax+MeasureTextEx(this->theme->font,content.c_str(),fs,1).x,ay,2,fs,{0,0,0,127}); + } + } + void exit()override{ + text::exit(); + } + }; + struct textinputfield :public textfield{ + bool active; + int cpos; + textinputfield():active(false),cpos(0){} + textinputfield(Texture2D* texture,enginend::theme *theme,double x,double y,double w,double h,float fsize):active(false),cpos(0), + textfield(texture,theme,x,y,w,h,fsize,""){} + void boot()override{} + void tick()override{ + textfield::tick(); + Vector2 mouse=GetMousePosition(); + float sw=GetScreenWidth(); + float sh=GetScreenHeight(); + Rectangle r={float(x*sw),float(y*sh),float(w*sw),float(h*sh)}; + if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){ + active=CheckCollisionPointRec(mouse,r); + } + 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{ + textfield::draw(); + if(active){ + float sw=GetScreenWidth(); + float sh=GetScreenHeight(); + float ax=x*sw; + float ay=y*sh; + float lh=fs+2; + Vector2 p={ax,ay}; + std::string line=""; + for(char ch:content){ + if(ch=='\n'){ + p.y+=lh; + line=""; + }else{ + line+=ch; + } + } + DrawRectangle(p.x+MeasureTextEx(this->theme->font,line.c_str(),fs,1).x,p.y,2,fs,rl::BLACK); + } + } + void exit()override{ + textfield::exit(); + } + }; +} + diff --git a/engine/src/scenes/node3d.h b/engine/src/scenes/node3d.h new file mode 100644 index 0000000..cfab994 --- /dev/null +++ b/engine/src/scenes/node3d.h @@ -0,0 +1,128 @@ +#pragma once +#include "nodes.h" + +namespace enginend::nodes::trid { + struct node3d:public node { + Vector3 pos,rot,size,scale; + Camera3D* watcher; + Shader* shader; + Color tint; + node3d(){} + node3d(Vector3 pos,Vector3 rot,Vector3 size,Vector3 scale): + pos(pos),rot(rot),scale(scale),size(size) { + tint={255,255,255,255}; + } + }; + + struct physicsagent:virtual public node3d { + bool hardbody,isphysics; + std::vector* bboxes; + physicsagent():hardbody(false),isphysics(false) { + bboxes = new std::vector(); + } + physicsagent(bool hardbody,bool isphysics):hardbody(hardbody),isphysics(isphysics) { + bboxes = new std::vector(); + } + physicsagent(bool hardbody,bool isphysics,std::vector* bboxes): + hardbody(hardbody),isphysics(isphysics),bboxes(bboxes) { + + } + }; + + struct billboard:virtual public physicsagent { + Texture2D* texture; + billboard(){texture=nullptr;} + billboard(Vector3 pos,Vector3 rot,Vector3 size,Vector3 scale,Texture2D* texture): + node3d(pos,rot,size,scale),texture(texture){} + void boot() override { + + } + void draw() override { + DrawBillboard(*watcher,*texture,pos,1.,tint); + } + void exit() override { + } + }; + struct object3d:public physicsagent { + Model* model; + void draw() override { + DrawModel(*model,pos,1.,tint); + } + void exit() override { + } + }; + + struct animatedbillboard:virtual public physicsagent { + Image animimage; + int frames; + int currentframe; + int framedelay; + int framecounter; + unsigned int nextframeoffset; + int prevframe; + Texture2D* texture; + + animatedbillboard() : frames(0), currentframe(0), framedelay(6), framecounter(0), nextframeoffset(0) { + animimage.data = nullptr; + } + + animatedbillboard(const char* gifpath, int delay = 6,Vector3 pos={},Vector3 rot={},Vector3 size={},Vector3 scale={}):node3d(pos,rot,size,scale), + framedelay(delay), currentframe(0), framecounter(0), frames(0), nextframeoffset(0) + { + animimage = LoadImageAnim(gifpath, &frames); + if (frames > 0) { + texture = new Texture2D(LoadTextureFromImage(animimage)); + } + } + void tick() override { + if (frames <= 1) return; + + framecounter++; + if (framecounter >= framedelay) { + framecounter = 0; + currentframe++; + if (currentframe >= frames) currentframe = 0; + nextframeoffset = animimage.width * animimage.height * 4 * currentframe; + } + } + + void draw() override { + + if (prevframe!=currentframe){ + prevframe=currentframe; + UpdateTexture(*this->texture,((unsigned char*)animimage.data)+nextframeoffset); + } + DrawBillboard(*watcher,*texture,pos,1.,tint); + } + void exit() override { + if (animimage.data) UnloadImage(animimage); + if (texture) { + UnloadTexture(*texture); + delete texture; + texture = nullptr; + } + } + }; + struct animatedmodel:virtual public physicsagent { + std::vector *animation; + Model *model; + int animcount; + int curranimation=0; + int currentframe=0; + animatedmodel() { + model = nullptr; + animation = nullptr; + } + animatedmodel(Model *model,std::vector* animation,int animcount,Vector3 pos,Vector3 rot,Vector3 size,Vector3 scale): + model(model), animation(animation),node3d(pos,rot,size,scale),animcount(animcount) + {} + void draw() override { + UpdateModelAnimationBones(*model,(*animation)[curranimation],currentframe++); + if (currentframe >= (*animation)[curranimation].frameCount) currentframe = 0; + DrawModel(*model,pos,1.,tint); + } + void exit() override { + } + }; + +} \ No newline at end of file diff --git a/games/endlauncher/src/main.cpp b/games/endlauncher/src/main.cpp index ec352c6..d3d974a 100644 --- a/games/endlauncher/src/main.cpp +++ b/games/endlauncher/src/main.cpp @@ -4,12 +4,9 @@ #include #include #include - -#include "../../../engine/src/scenes/nodes.h" -#include "../../../engine/src/scenes/nodes.h" #include"themes.h" using namespace enginend; -using namespace enginend::nodes; +using namespace enginend::nodes::twod; netio nete{}; /* @@ -175,7 +172,7 @@ public: playbtn[0]=LoadTexture("res/playoff.png"); playbtn[1]=LoadTexture("res/playon.png"); playbutton= new button(&playbtn[0], enginend::DEFAULT,406,(18*11)+17+9,153,59,std::function(playbuttonfunc)); - currentscene->nodes=std::list{ + currentscene->nodes=std::list{ new background(&bg,0,0,600,300), new textured(&buttonfore,3,36,62,62), new textured(&buttonlock,3,36+((62+4)*1),62,62), diff --git a/games/forespend/src/client/scenes/configmenu.cpp b/games/forespend/src/client/scenes/configmenu.cpp index 189afe3..c5e5c9e 100644 --- a/games/forespend/src/client/scenes/configmenu.cpp +++ b/games/forespend/src/client/scenes/configmenu.cpp @@ -1,19 +1,20 @@ #include "configmenu.h" #include "../../common/themes.h" #include +using namespace enginend::nodes::twod::relative; int configmenupage=0; // 0 is before the mainpage is showing. aka pause menu/main menu when start game enginend::group maincfgpage= enginend::group( { - new enginend::nodes::relative::labeledbutton("video",nullptr,clienttheme,0,0.04,1,0.2,std::function([]() { + new labeledbutton("video",nullptr,clienttheme,0,0.04,1,0.2,std::function([]() { configmenupage=2; }),32), - new enginend::nodes::relative::labeledbutton("sound",nullptr,clienttheme,0,0.27,1,0.2,std::function([]() { + new labeledbutton("sound",nullptr,clienttheme,0,0.27,1,0.2,std::function([]() { }),32), - new enginend::nodes::relative::labeledbutton("input",nullptr,clienttheme,0,0.51,1,0.2,std::function([]() { + new labeledbutton("input",nullptr,clienttheme,0,0.51,1,0.2,std::function([]() { }),32), - new enginend::nodes::relative::labeledbutton("back",nullptr,clienttheme,0,0.75,1,0.2,std::function([]() { + new labeledbutton("back",nullptr,clienttheme,0,0.75,1,0.2,std::function([]() { configmenupage=0; }),32), @@ -22,10 +23,10 @@ enginend::group maincfgpage= enginend::group( enginend::group graphics= enginend::group( { - new enginend::nodes::relative::labeledbutton("fullscreen",nullptr,clienttheme,0,0.04,1,0.2,std::function([]() { - (dynamic_cast(graphics.children[0]))->boolean^=true; + new labeledbutton("fullscreen",nullptr,clienttheme,0,0.04,1,0.2,std::function([]() { + (dynamic_cast(graphics.children[0]))->boolean^=true; }),32,true), - new enginend::nodes::relative::labeledbutton("back",nullptr,clienttheme,0,0.75,1,0.2,std::function([]() { + new labeledbutton("back",nullptr,clienttheme,0,0.75,1,0.2,std::function([]() { configmenupage=1; }),32), } diff --git a/games/forespend/src/client/scenes/mainmenu.h b/games/forespend/src/client/scenes/mainmenu.h index 84cc406..e61343a 100644 --- a/games/forespend/src/client/scenes/mainmenu.h +++ b/games/forespend/src/client/scenes/mainmenu.h @@ -2,23 +2,24 @@ #include #include "configmenu.h" #include "../../common/themes.h" +using namespace enginend::nodes::twod::relative; class mainmenu :public virtual enginend::scene{ private: Texture2D bg= LoadTexture(AT("res/images/tilesheet.png")); public: void boot() override { this->nodes=std::vector{ - new enginend::nodes::relative::animated(AT("res/images/sky.gif"),0,0,1,1,2), - new enginend::nodes::relative::text(nullptr,clienttheme,0.17,0.05,0.8,0.3,32,"FORESPEND"), - new enginend::nodes::relative::labeledbutton("PLAY",nullptr,clienttheme,0.30,0.25,0.4,0.2, + new animated(AT("res/images/sky.gif"),0,0,1,1,2), + new text(nullptr,clienttheme,0.17,0.05,0.8,0.3,32,"FORESPEND"), + new labeledbutton("PLAY",nullptr,clienttheme,0.30,0.25,0.4,0.2, std::function([]{ }),32), - new enginend::nodes::relative::labeledbutton("OPTIONS",nullptr,clienttheme,0.02,0.75,0.56,0.2, + new labeledbutton("OPTIONS",nullptr,clienttheme,0.02,0.75,0.56,0.2, std::function([]{ configmenupage=1; }),32), - new enginend::nodes::relative::labeledbutton("EXIT",nullptr,clienttheme,0.63,0.75,0.35,0.2, + new labeledbutton("EXIT",nullptr,clienttheme,0.63,0.75,0.35,0.2, std::function([](){ std::exit(1); }),32), @@ -55,7 +56,7 @@ public: } break; } - case 1: {this->nodes[0]->draw(); + case 1: {(this->nodes[0])->draw(); for (enginend::nodes::node* n : maincfgpage.children) { n->draw(); }