void ge_Splashscreen(){ #ifndef LIBGE_MINI if(!_ge_splashscreen_enabled)return; u32 ticks = geGetTick(); u32 time = 0; ge_Image* splash = geLoadImage(geFileFromBuffer(ge_splash_screen, sizeof(ge_splash_screen))); int h = (splash->height > libge_context->height) ? libge_context->height : splash->height; int w = h * splash->width / splash->height; geDrawingMode(GE_DRAWING_MODE_2D); while(time < 3000){ time = geGetTick() - ticks; if(time < 800){ splash->color = RGBA(255, 255, 255, (u8)(time * 255 / 800)); }else if(time < 2200){ splash->color = RGBA(255, 255, 255, 255); }else if(time < 3000){ splash->color = RGBA(255, 255, 255, (u8)((1000-(time-3000)) * 255 / 1000)); } geClearScreen(); geBlitImageStretched(libge_context->width/2, libge_context->height/2, splash, 0, 0, splash->width, splash->height, w, h, GE_BLIT_CENTERED); geSwapBuffers(); } geFreeImage(splash); #endif }
static void show_back(show_back_data* data){ geClearScreen(); lua_pushvalue(data->L, 4); lua_pushvalue(data->L, 5); lua_pushnumber(data->L, data->t); lua_pushnumber(data->L, data->dt); lua_call(data->L, 3, 0); geSwapBuffers(); data->dt = geGetTick() / 1000.0f - data->t; data->t = geGetTick() / 1000.0f; }
void geParticlesDraw(ge_Particles* particles){ float t = ((float)geGetTick())/1000.0; //float dt = t - particles->dt; particles->dt = t; geRendererUse(particles->render); if(particles->texture){ geShaderUniform1f(particles->loc_textured, 1.0); geTextureImage(0, particles->texture); }else{ geShaderUniform1f(particles->loc_textured, 0.0); } particles->visible_parts = 0; int i; for(i=0; i<particles->nParticles; i++){ if(particles->particles[i].life >= 0.0){ geShaderUniform1f(particles->loc_life, particles->particles[i].life / particles->life_time); geShaderUniform2f(particles->loc_size, particles->size.x, particles->size.y); geShaderUniform3f(particles->loc_pos, particles->particles[i].pos.x, particles->particles[i].pos.y, particles->particles[i].pos.z); geShaderUniform3f(particles->loc_rpos, particles->particles[i].pos.x-particles->origin.x, particles->particles[i].pos.y-particles->origin.y, particles->particles[i].pos.z-particles->origin.z); geDrawArray(GE_TRIANGLES, 0, 6); particles->visible_parts++; } } }
int ge_clouds_thread(int args, void* argp){ ge_Scene* scene = (ge_Scene*)argp; nClouds = scene->cloudsGenerator->n_clouds[0] + scene->cloudsGenerator->n_clouds[1] + scene->cloudsGenerator->n_clouds[2]; float map_size_x = scene->cloudsGenerator->map_size_x; while(1){ if(!ge_current_camera){ geSleep(1000); continue; } int c=0; for(c=0; c<nClouds; c++){ if(!ge_current_camera)break; int type = scene->cloudsGenerator->types[c]; ge_Cloud* cloud = &scene->cloudsGenerator->clouds[c]; float scale = 1.5; if(type == GE_CLOUD_TYPE_HIGH_LEVEL){ scale = 5.0; }else if(type == GE_CLOUD_TYPE_MID_LEVEL){ scale = 10.0; }else{ scale = 20.0; } // if(cloud->x > map_size_x/2.0){ if(cloud->z <= 0.0 && cloud->x > 0.0){ srand(0); int first_rand = rand()*geGetTick(); srand(first_rand); GenerateCloud(scene, cloud, c); // cloud->x = -map_size_x/2.0; float D = -4 * (-1.0/scene->cloudsGenerator->map_size_x) * (scene->cloudsGenerator->map_size_x / 2.0); cloud->x = sqrt(D) / (-2.0 / scene->cloudsGenerator->map_size_x); } cloud->alpha = 1.0; if(abs(cloud->x) > map_size_x/2.0*0.6){ // cloud->alpha = 1.0 - (abs(cloud->x) - map_size_x/2.0*0.6) / (map_size_x/2.0*0.4); } float dx = (ge_current_camera->x - cloud->x); float dy = (ge_current_camera->y - cloud->y); float dz = (ge_current_camera->z - cloud->z); float rotX = atanf(dx/dz); float rotY = atanf(dy/dz); // float rotZ = atanf(dx/-dy); ge_LoadIdentity(cloud->matrix); ge_Scale(cloud->matrix, scale, scale, scale); ge_Rotate(cloud->matrix, -rotY, rotX, 0.0); } geSleep(100); } return 0; }
ge_Particles* geCreateParticles(float x, float y, float z, float radius, float velocity, float life_time, int nParticles, ge_Image* texture){ ge_Particles* particles = (ge_Particles*)geMalloc(sizeof(ge_Particles)); particles->loop_mode = true; particles->origin.x = x; particles->origin.y = y; particles->origin.z = z; particles->radius = radius; particles->direction.x = 0.0; particles->direction.y = 1.0; particles->direction.z = 0.0; particles->velocity = velocity; particles->life_time = life_time / (velocity==0.0?1.0:velocity); particles->nParticles = nParticles; particles->size.x = 1.0; particles->size.y = 1.0; particles->texture = texture; particles->nParticles = nParticles; particles->particles = (ge_Particle*)geMalloc(sizeof(ge_Particle)*particles->nParticles); geParticlesLifeSeed(particles, 10.0); particles->shader = geCreateShader(); geShaderLoadVertexSource(particles->shader, "default_shaders/particles.vert"); geShaderLoadFragmentSource(particles->shader, "default_shaders/particles.frag"); particles->render = geCreateRenderer(particles->shader); particles->render->blend_enabled = true; particles->render->depth_mask = false; ge_Object* obj = (ge_Object*)geMalloc(sizeof(ge_Object)); particles->render->objs = (ge_Object**)geMalloc(sizeof(ge_Object*)); particles->render->objs[0] = obj; particles->render->nObjs = 1; particles->render->nVerts = 6; obj->nVerts = 6; obj->verts = _ge_particles_vertices; particles->loc_size = geShaderUniformID(particles->render->shader, "size"); particles->loc_pos = geShaderUniformID(particles->render->shader, "pos"); particles->loc_rpos = geShaderUniformID(particles->render->shader, "rpos"); particles->loc_life = geShaderUniformID(particles->render->shader, "life"); particles->loc_textured = geShaderUniformID(particles->render->shader, "textured"); particles->render->verts = _ge_particles_vertices; geRendererCreateContext(NULL, particles->render); particles->ut = ((float)geGetTick())/1000.0; particles->dt = ((float)geGetTick())/1000.0; return particles; }
float geGetTickFloat(){ return (double)geGetTick() / 1000.0; /* struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); // clock_gettime(CLOCK_REALTIME_HR, &now); float ret = (float)now.tv_sec; u32 ms = now.tv_nsec/1000000 - tick_pause; ret += ((float)ms) / 1000.0; return ret; */ }
void _geGui_RenderInputBox(ge_GuiAreaObject* object, ge_GuiStyle* style){ int i = -1; ge_GuiInputBox* box = (ge_GuiInputBox*)object->object; if(!box->img){ _geGui_MakeResizableObject((ge_GuiWidget*)box, style); } if(box->gotfocus){ geKeyboardInit(); geKeyboardOutput(box->text, box->maxlen, box->maxlines); } if(box->focused){ geKeyboardUpdate(); i = geKeyboardIndex(); } if(box->lostfocus){ geKeyboardFinished(); } u32 foreground = RGBA(255-R(box->back_color), 255-G(box->back_color), 255-B(box->back_color), 255); geBlitImage(object->absx, object->absy, box->img, 0, 0, box->width, box->height, 0); geFontPrintScreen(object->absx+box->textpos[0], object->absy+(box->height/2-style->font->size/2), style->font, box->text, foreground); if(i >= 0){ int w, h; char str[2048] = ""; strncpy(str, box->text, i); geFontMeasureText(style->font, str, &w, &h); int x = object->absx+box->textpos[0]+w; int y = object->absy+(box->height/2-style->font->size/2); if(geGetTick() - tick < 500){ geDrawLineScreen(x, y, x, y+style->font->size, foreground); }else if(geGetTick() - tick >= 1000){ tick = geGetTick(); } } }
void GenerateClouds(ge_Scene* scene){ int first_rand = rand()*geGetTick(); srand(first_rand); int nClouds = scene->cloudsGenerator->n_clouds[0] + scene->cloudsGenerator->n_clouds[1] + scene->cloudsGenerator->n_clouds[2]; scene->cloudsGenerator->clouds = (ge_Cloud*)geMalloc(sizeof(ge_Cloud)*nClouds); scene->cloudsGenerator->types = (u8*)geMalloc(sizeof(u8)*nClouds); int j = 0; for(j=0; j<nClouds; j++){ GenerateCloud(scene, &scene->cloudsGenerator->clouds[j], j); scene->cloudsGenerator->clouds[j].ready = true; } ge_Thread* cloudsThread = geCreateThread("GE_clouds_thread", ge_clouds_thread, GE_THREAD_PRIORITY_LOWEST/*GE_THREAD_PRIORITY_NORMAL*/); geThreadStart(cloudsThread, sizeof(ge_Scene*), scene); }
void geRendererUse(ge_Renderer* render){ geShaderUse(render->shader); if(ge_current_camera){ glUniform3f(render->shader->loc_camera, ge_current_camera->x, ge_current_camera->y, ge_current_camera->z); } geShaderUniform1f(render->shader->loc_time, ((float)geGetTick()) / 1000.0); glBindVertexArray(render->vao); #ifndef PLATFORM_mac // if(render->tesselated && glPatchParameteri){ // glPatchParameteri(GL_PATCH_VERTICES, 3); // } #endif if(render->depth_enabled){ glEnable(GL_DEPTH_TEST); }else{ glDisable(GL_DEPTH_TEST); } glDepthMask(render->depth_mask); if(render->blend_enabled){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }else{ glDisable(GL_BLEND); } int i; for(i=0; i<32; i++){ if(_ge_force_caps[i].used){ if(_ge_force_caps[i].state == 1){ glEnable(_ge_force_caps[i].cap); }else if(_ge_force_caps[i].state == 0){ glDisable(_ge_force_caps[i].cap); } } } if(render->ext_func){ render->ext_func(render, -1); } }
void geParticlesUpdate(ge_Particles* particles){ float t = ((float)geGetTick())/1000.0; float dt = t - particles->ut; particles->ut = t; int i; for(i=0; i<particles->nParticles; i++){ particles->particles[i].pos.x += particles->particles[i].dpos.x * dt * particles->velocity; particles->particles[i].pos.y += particles->particles[i].dpos.y * dt * particles->velocity; particles->particles[i].pos.z += particles->particles[i].dpos.z * dt * particles->velocity; float last_life = particles->particles[i].life; particles->particles[i].life += dt; if(last_life < 0.0 && particles->particles[i].life >= 0.0){ float r = ((float)(rand() % 1000)) / 1000.0; float r2 = ((float)(rand() % 1000)) / 1000.0; float r3 = ((float)(rand() % 1000)) / 1000.0; r = r * M_PI * 2.0; r2 = r2 * M_PI * 2.0; float rtemp = geCos(r); particles->particles[i].pos.x = particles->origin.x + r3 * particles->radius * rtemp * geCos(r2); particles->particles[i].pos.y = particles->origin.y + r3 * particles->radius * rtemp * geSin(r2); particles->particles[i].pos.z = particles->origin.z + r3 * particles->radius * geSin(r); /* particles->particles[i].pos.x = particles->origin.x; particles->particles[i].pos.y = particles->origin.y; particles->particles[i].pos.z = particles->origin.z; */ /* particles->particles[i].pos.x = particles->origin.x + r2 * geCos(r) * particles->radius; particles->particles[i].pos.y = particles->origin.y; particles->particles[i].pos.z = particles->origin.z + r2 * geSin(r) * particles->radius; */ } if(particles->loop_mode && particles->particles[i].life >= particles->life_time){ particles->particles[i].life = particles->particles[i].life_base; } } }
void GenerateCloud(ge_Scene* scene, ge_Cloud* cloud, int j){ bool was_ready = cloud->ready; cloud->ready = false; srand(j*42+geGetTick()*rand()); srand(j*42*rand()*rand() - j*42+geGetTick()*rand()); int type = -1; if(j < scene->cloudsGenerator->n_clouds[0]){ type = GE_CLOUD_TYPE_HIGH_LEVEL; }else if(j < scene->cloudsGenerator->n_clouds[0]+scene->cloudsGenerator->n_clouds[1]){ type = GE_CLOUD_TYPE_MID_LEVEL; }else if(j < scene->cloudsGenerator->n_clouds[0]+scene->cloudsGenerator->n_clouds[1]+scene->cloudsGenerator->n_clouds[2]){ type = GE_CLOUD_TYPE_LOW_LEVEL; }else{ type = GE_CLOUD_TYPE_LOW_LEVEL; // Assume default is low-level } scene->cloudsGenerator->types[j] = (u8)type; int size_range = scene->cloudsGenerator->size_max[type] - scene->cloudsGenerator->size_min[type]; int parts_range = scene->cloudsGenerator->parts_max[type] - scene->cloudsGenerator->parts_min[type]; int size = rand() % size_range + scene->cloudsGenerator->size_min[type]; int parts = rand() % parts_range + scene->cloudsGenerator->parts_min[type]; parts = size * scene->cloudsGenerator->parts_max[type] / scene->cloudsGenerator->size_max[type]; // parts = (size-scene->cloudsGenerator->size_min)*parts_range/size_range; float a = 0.0; a = rand() % 360; scene->cloudsGenerator->clouds[j].x = rand() % scene->cloudsGenerator->map_size_x - (scene->cloudsGenerator->map_size_x/2); scene->cloudsGenerator->clouds[j].y = rand() % scene->cloudsGenerator->map_size_y - (scene->cloudsGenerator->map_size_y/2); float r = geCos(rand()) * (scene->cloudsGenerator->map_size_x/1.0);// + (scene->cloudsGenerator->map_size_x/8); float r2 = geSin(rand()) * (scene->cloudsGenerator->map_size_y/1.0);// + (scene->cloudsGenerator->map_size_x/8); printf("r,r2 = %f, %f\n", r, r2); scene->cloudsGenerator->clouds[j].x = r * geCos(a/**scene->cloudsGenerator->clouds[j].x*/); scene->cloudsGenerator->clouds[j].y = r2 * geSin(a/**scene->cloudsGenerator->clouds[j].y*/); if(type == GE_CLOUD_TYPE_HIGH_LEVEL){ scene->cloudsGenerator->clouds[j].z = rand() % 3000 + 11000; }else if(type == GE_CLOUD_TYPE_MID_LEVEL){ scene->cloudsGenerator->clouds[j].z = rand() % 3000 + 7000; }else if(type == GE_CLOUD_TYPE_LOW_LEVEL){ scene->cloudsGenerator->clouds[j].z = rand() % 2000 + 4000; } scene->cloudsGenerator->clouds[j].size = size; scene->cloudsGenerator->clouds[j].parts = parts; if(was_ready){ free(scene->cloudsGenerator->clouds[j].parts_x); free(scene->cloudsGenerator->clouds[j].parts_y); free(scene->cloudsGenerator->clouds[j].parts_z); free(scene->cloudsGenerator->clouds[j].parts_a); free(scene->cloudsGenerator->clouds[j].parts_matrix); } scene->cloudsGenerator->clouds[j].parts_x = (float*)geMalloc(sizeof(float)*parts); scene->cloudsGenerator->clouds[j].parts_y = (float*)geMalloc(sizeof(float)*parts); scene->cloudsGenerator->clouds[j].parts_z = (float*)geMalloc(sizeof(float)*parts); scene->cloudsGenerator->clouds[j].parts_a = (float*)geMalloc(sizeof(float)*parts); scene->cloudsGenerator->clouds[j].parts_matrix = (float*)geMalloc(sizeof(float)*16*parts); memset(scene->cloudsGenerator->clouds[j].parts_x, 0x0, sizeof(float)*parts); memset(scene->cloudsGenerator->clouds[j].parts_y, 0x0, sizeof(float)*parts); memset(scene->cloudsGenerator->clouds[j].parts_z, 0x0, sizeof(float)*parts); memset(scene->cloudsGenerator->clouds[j].parts_a, 0x0, sizeof(float)*parts); memset(scene->cloudsGenerator->clouds[j].parts_matrix, 0x0, sizeof(float)*16*parts); /* int k = 0; for(k=0; k<parts; k++){ srand(k*2+geGetTick()*rand()); srand((k*4+geGetTick())*rand()); float a=0.0, x=0.0, y=0.0, z=0.0; a = rand() % 360; x = ((rand() % (int)(size*2.0)) - size) * geCos(a); if(type == GE_CLOUD_TYPE_HIGH_LEVEL){ y = ((rand() % (size/2)) - (size/4)) * geSin(a); z = 0.0; }else{ y = ((rand() % (int)(size*1.5)) - (size*0.75)) * geSin(a); z = ((rand() % size/10) - size/20) * geSin(rand() % 360); } scene->cloudsGenerator->clouds[j].parts_x[k] = x; scene->cloudsGenerator->clouds[j].parts_y[k] = y; scene->cloudsGenerator->clouds[j].parts_z[k] = z; scene->cloudsGenerator->clouds[j].parts_a[k] = 1.0; if(z < 0.0){ #define absf(a) (a>0.0?a:-a) scene->cloudsGenerator->clouds[j].parts_a[k] = 1.0 - ((absf(z) / (size/20)) * (1.0-(absf(x) / size)) * (1.0-(absf(y) / (size*0.75)))); printf("%f => %f\n", z, scene->cloudsGenerator->clouds[j].parts_a[k]); } } */ int k = 0; for(k=0; k<parts; k++){ srand(k*2+geGetTick()*rand()); // srand((k*4+geGetTick())*rand()); float a=0.0, x=0.0, y=0.0, z=0.0, zr=0.0; a = rand() % 360; x = ((rand() % size) - (size/2.0)) * geCos(a); y = ((rand() % size) - (size/2.0)) * geSin(a); if(type == GE_CLOUD_TYPE_HIGH_LEVEL){ z = 0.0; zr = 0.0; }else if(type == GE_CLOUD_TYPE_MID_LEVEL){ z = ((rand() % (int)(size/512)) - (size/1024)) * geSin(rand() % 360); zr = 1024; }else if(type == GE_CLOUD_TYPE_LOW_LEVEL){ z = ((rand() % (int)(size/16)) - (size/32)) * geSin(rand() % 360); zr = 97; } scene->cloudsGenerator->clouds[j].parts_x[k] = x; scene->cloudsGenerator->clouds[j].parts_y[k] = y; scene->cloudsGenerator->clouds[j].parts_z[k] = z; scene->cloudsGenerator->clouds[j].parts_a[k] = 1.0; if(z < 0.0){ #define absf(x) (x<0.0?-x:x) scene->cloudsGenerator->clouds[j].parts_a[k] = 1.0 - ((absf(z) / (size/zr)) * (1.0-(absf(x) / (size/2.0))) * (1.0-(absf(y) / (size/2.0)))); } } cloud->ready = true; }
int _ev_thread(int args, void* argp){ LibGE_LinuxContext* context = (LibGE_LinuxContext*)argp; u32 ticks = geGetTick(); bool finished = false; int key = 0; if(wheel_j == -1){ while(wheel_i == -1); wheel_j = 0; } while(1){ // mouse_warp_x = mouse_warp_y = 0; while(XPending(context->dpy)){ XNextEvent(context->dpy, &event); // if(event.type)printf("event: %d\n", event.type); if((event.type == ButtonPress || event.type == ButtonRelease) && (event.xbutton.button == GEK_MWHEELUP || event.xbutton.button == GEK_MWHEELDOWN)){ memcpy(&wheel_ev[wheel_j], &event.xbutton, sizeof(XButtonEvent)); wheel_j = (wheel_j + 1) % 32; } switch (event.type){ case ClientMessage: if (*XGetAtomName(context->dpy, event.xclient.message_type) == *"WM_PROTOCOLS"){ finished = true; } if (event.xclient.data.l[0] == XInternAtom(context->dpy, "WM_DELETE_WINDOW", False)){ finished = true; } break; case ConfigureNotify: new_w = event.xconfigure.width; new_h = event.xconfigure.height; break; /* case ConfigureNotify: if(event.xexpose.width!=libge_context->width || event.xexpose.height!=libge_context->height){ libge_context->width = event.xconfigure.width; libge_context->height = event.xconfigure.height; libge_context->projection_matrix[0] = (float)0xFFFFFFFF; geGraphicsInit(); geDrawingMode(libge_context->drawing_mode | 0xF0000000); } break; */ case KeymapNotify: XRefreshKeyboardMapping(&event.xmapping); break; case KeyPress: key = (int)XLookupKeysym(&event.xkey, 0); if(key == XK_ISO_Level3_Shift){ key = XK_Alt_L; } if(key >= 0xFF00){ key -= 0xFF00; } if(key >= 'a' && key <= 'z'){ key += ('A' - 'a'); } { char str[25]; int len; KeySym keysym; len = XLookupString(&event.xkey, str, 25, &keysym, NULL); last_pressed = (u8)str[0]; printf("key : %X %X\n", key, last_pressed); } keys_pressed[key] = true; keys_released[key] = false; if(keys_pressed[GEK_LALT] && keys_pressed[GEK_F4]){ finished = true; } break; case KeyRelease: key = (int)XLookupKeysym(&event.xkey, 0); if(key >= 0xFF00){ key -= 0xFF00; } if(key <= 0xFF){ if(key >= 'a' && key <= 'z'){ key += ('A' - 'a'); } keys_pressed[key] = false; keys_released[key] = true; } break; case ButtonPress: if(event.xbutton.button == GEK_MWHEELUP){ wup = 1; }else if(event.xbutton.button == GEK_MWHEELDOWN){ wdown = 1; }else{ keys_pressed[event.xbutton.button] = true; keys_released[event.xbutton.button] = false; } break; case ButtonRelease: if(event.xbutton.button == GEK_MWHEELUP){ pending_wup_release = true; }else if(event.xbutton.button == GEK_MWHEELDOWN){ pending_wdown_release = true; }else{ keys_pressed[event.xbutton.button] = false; keys_released[event.xbutton.button] = true; } break; case MotionNotify: /* if(changed){ changed = false; continue; } if(libge_context->mouse_round){ if(reset){ warp_x = warp_y = 0; reset = false; } warp_x += event.xmotion.x - libge_context->width / 2; warp_y += event.xmotion.y - libge_context->height / 2; libge_context->mouse_x = libge_context->width / 2; libge_context->mouse_y = libge_context->height / 2; changed = true; XWarpPointer(context->dpy, context->win, context->win, 0, 0, 0, 0, libge_context->mouse_x, libge_context->mouse_y); }else{ mouse_last_x = libge_context->mouse_x; mouse_last_y = libge_context->mouse_y; libge_context->mouse_x = event.xmotion.x; libge_context->mouse_y = event.xmotion.y; mouse_warp_x = libge_context->mouse_x-mouse_last_x; mouse_warp_y = libge_context->mouse_y-mouse_last_y; } */ break; default: break; } } if(finished){ _to_close = true; finished = false; geSleep(1000); exit(0); } ticks = geWaitTick(1000 / 120, ticks); } return 0; }
static int textInput(lua_State *L){ int argc = lua_gettop(L); if(argc != 3 && argc != 5) return luaL_error(L, "Argument error: geTextInput(title, initial_text, font[, draw_callback, callback_data]) takes two or four argument."); lua_getfield(L, 3, "fnt"); ge_Font* font = *toFont(L, -1); #if (defined(PLATFORM_android) || defined(PLATFORM_ios)) float dt=0.0f, t = geGetTick() / 1000.0f; show_back_data data = { L, dt, t }; char text[2048] = ""; if(geIMEInput((void(*)(void*))show_back, &data, text, sizeof(text))){ lua_pushstring(L, text); }else{ lua_pushstring(L, luaL_checkstring(L, 2)); } #else ge_GuiWindow* win = geGuiCreateWindow(luaL_checkstring(L, 1), geGetContext()->width * 0.9, geGetContext()->width * 0.3, 0); geGuiStyleFont(win->style, font, font->size); ge_GuiInputBox* input = geGuiCreateInputBox(win->width * 0.9, font->size * 2.0, luaL_checkstring(L, 2), 32); ge_GuiButton* ok = geGuiCreateButton("Ok", win->width * 0.4, win->height * 0.3); ge_GuiButton* cancel = geGuiCreateButton("Cancel", win->width * 0.4, win->height * 0.3); geGuiWindowLinkObject(win, -input->width / 2, -input->height * 1.0, input, GE_GUI_ALIGNX_CENTER | GE_GUI_ALIGNY_CENTER); geGuiWindowLinkObject(win, -input->width / 2, input->height * 0.4, ok, GE_GUI_ALIGNX_CENTER | GE_GUI_ALIGNY_CENTER); geGuiWindowLinkObject(win, -input->width / 2, input->height * 0.4, cancel, GE_GUI_ALIGNX_RIGHT | GE_GUI_ALIGNY_CENTER); bool first_focus = false; bool done = false; float dt=0.0f, t = geGetTick() / 1000.0f; while(win->visible){ geClearScreen(); lua_pushvalue(L, 4); lua_pushvalue(L, 5); lua_pushnumber(L, t); lua_pushnumber(L, dt); lua_call(L, 3, 0); geSwapBuffers(); if(!first_focus){ geGuiGiveFocus(input); first_focus = true; } if(ok->pressed){ done = true; win->visible = false; } if(cancel->pressed){ win->visible = false; } dt = geGetTick() / 1000.0f - t; t = geGetTick() / 1000.0f; } if(done){ lua_pushstring(L, input->text); }else{ lua_pushstring(L, luaL_checkstring(L, 2)); } #endif return 1; }
void geBlitImageDepthStretched(int x, int y, int z, ge_Image* img, int _sx, int _sy, int ex, int ey, int width, int height, int flags){ if(!img)return; if((t_ptr)img==0xBAADF00D)return; if(!img->id)return; if(abs(z) > 2048){ return; } x += libge_context->draw_off_x; y += libge_context->draw_off_y; if(flags & GE_BLIT_CENTERED){ x -= width / 2; y -= height / 2; } if(x > libge_context->width || x+width < 0 || y > libge_context->height || y+height < 0){ return; } if(flags & GE_BLIT_NOALPHA){ glDisable(GL_ALPHA_TEST); glDisable(GL_BLEND); }else{ glEnable(GL_ALPHA_TEST); glEnable(GL_BLEND); int b_src = libge_context->blend_src; int b_dst = libge_context->blend_dst; b_src = (b_src == GE_DEFAULT) ? GL_SRC_ALPHA : b_src; b_dst = (b_dst == GE_DEFAULT) ? GL_ONE_MINUS_SRC_ALPHA : b_dst; glBlendFunc(b_src, b_dst); } float texMaxX = img->u; float texMaxY = img->v; float sx = _sx*texMaxX/img->width; float sy = _sy*texMaxY/img->height; texMaxX = ex*texMaxX/img->width; texMaxY = ey*texMaxY/img->height; if(img->flags & GE_IMAGE_ANIMATED){ sy += ((_ge_ImageAnimated*)img)->_ge_n * img->v; if(geGetTickFloat() - ((_ge_ImageAnimated*)img)->_ge_t >= ((_ge_ImageAnimated*)img)->frameTime){ ((_ge_ImageAnimated*)img)->_ge_t = geGetTickFloat(); ((_ge_ImageAnimated*)img)->_ge_n = (((_ge_ImageAnimated*)img)->_ge_n + 1) % ((_ge_ImageAnimated*)img)->nImages; } } int tex_mode = GL_TEXTURE_2D; if(!ge_current_shader){ geShaderUse(_ge_GetVideoContext()->shader2d); } if(ge_current_shader == _ge_GetVideoContext()->shader2d){ geShaderUniform1f(_ge_GetVideoContext()->loc_textured, 1.0); glUniform1f(ge_current_shader->loc_time, ((float)geGetTick()) / 1000.0); glUniform1f(ge_current_shader->loc_ratio, ((float)libge_context->width) / ((float)libge_context->height)); } glEnable(tex_mode); glBindTexture(tex_mode, img->id); if(flags & GE_BLIT_VFLIP){ glBegin(GL_QUADS); glColor4ub(R(img->color), G(img->color), B(img->color), A(img->color)); glTexCoord2f(sx, sy+texMaxY); glVertex3f(x, y, z+libge_context->img_stack[z+2048]); glTexCoord2f(sx+texMaxX, sy+texMaxY); glVertex3f(x+width, y, z+libge_context->img_stack[z+2048]); glTexCoord2f(sx+texMaxX, sy); glVertex3f(x+width, y+height, z+libge_context->img_stack[z+2048]); glTexCoord2f(sx, sy); glVertex3f(x, y+height, z+libge_context->img_stack[z+2048]); glEnd(); }else{ glBegin(GL_QUADS); glColor4ub(R(img->color), G(img->color), B(img->color), A(img->color)); glTexCoord2f(sx, sy); glVertex3f(x, y, z+libge_context->img_stack[z+2048]); glTexCoord2f(sx+texMaxX, sy); glVertex3f(x+width, y, z+libge_context->img_stack[z+2048]); glTexCoord2f(sx+texMaxX, sy+texMaxY); glVertex3f(x+width, y+height, z+libge_context->img_stack[z+2048]); glTexCoord2f(sx, sy+texMaxY); glVertex3f(x, y+height, z+libge_context->img_stack[z+2048]); glEnd(); } libge_context->img_stack[z+2048] += 0.001; }
void geRendererUse(ge_Renderer* render){ geShaderUse(render->shader); if(ge_current_camera){ glUniform3f(render->shader->loc_camera, ge_current_camera->x, ge_current_camera->y, ge_current_camera->z); } geShaderUniform1f(render->shader->loc_time, ((float)geGetTick()) / 1000.0); glBindBuffer(GL_ARRAY_BUFFER, render->vbo); if(render->customVert){ if(render->customVert->vertex_offset >= 0){ glEnableVertexAttribArray(3); //pos glVertexAttribPointer(3, render->customVert->vertex_count, render->customVert->vertex_type, false, render->customVert->size, BUFFER_OFFSET(render->customVert->vertex_offset)); }else{ glDisableVertexAttribArray(3); //pos } if(render->customVert->color_offset >= 0){ glEnableVertexAttribArray(1); //color glVertexAttribPointer(1, render->customVert->color_count, render->customVert->color_type, true, render->customVert->size, BUFFER_OFFSET(render->customVert->color_offset)); }else{ glDisableVertexAttribArray(1); //color } if(render->customVert->texture_offset >= 0){ glEnableVertexAttribArray(0); //tex glVertexAttribPointer(0, render->customVert->texture_count, render->customVert->texture_type, false, render->customVert->size, BUFFER_OFFSET(render->customVert->texture_offset)); }else{ glDisableVertexAttribArray(0); //tex } if(render->customVert->normal_offset >= 0){ glEnableVertexAttribArray(2); //normal glVertexAttribPointer(2, 3, render->customVert->normal_type, true, render->customVert->size, BUFFER_OFFSET(render->customVert->normal_offset)); }else{ glDisableVertexAttribArray(2); //normal } }else{ glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(ge_Vertex), BUFFER_OFFSET(40)); //3*4 + 4*4 + 3*4 => size(u,v,w,color[4],nx,ny,nz) glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(ge_Vertex), BUFFER_OFFSET(12)); //3*4 => size(u,v,w) glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ge_Vertex), BUFFER_OFFSET(28)); //3*4 + 4*4 => size(u,v,w,color[4]) glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ge_Vertex), BUFFER_OFFSET(0)); } if(render->depth_enabled){ glEnable(GL_DEPTH_TEST); }else{ glDisable(GL_DEPTH_TEST); } // glDepthMask(render->depth_mask); if(render->blend_enabled){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }else{ glDisable(GL_BLEND); } if(render->ext_func){ render->ext_func(render, -1); } }
void geSceneDraw(ge_Scene* scene){ current_scene = scene; int i = 0; int j = 0; CalculateModelMatrices(); /* if(scene->sky.animator){ geRendererUse(&scene->sky); geShaderUniform1f(scene->sky.depth_enabled, ((float)geGetTick())/1000.0); geMatrixMode(GE_MATRIX_MODEL); geLoadIdentity(); geUpdateMatrix(); for(i=0; i< scene->sky.nObjs; i++){ glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, scene->sky.objs[i]->material.textures[0]->id); if(scene->sky.objs[i]->material.textures[1]){ glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, scene->sky.objs[i]->material.textures[1]->id); // geShaderUniform1i(geShaderUniformID(scene->sky.shader, "ge_Texture1"), 1); } glDrawArrays(GL_TRIANGLES, scene->sky.objs[i]->vert_start, scene->sky.objs[i]->nVerts); } } */ if(scene->cloudsGenerator){ } float time = ((float)geGetTick()) / 1000.0; for(i=0; i<scene->nRenderers; i++){ if(scene->renderers[i].enabled == false)continue; if(scene->renderers[i].matrix_used){ geMatrixMode(GE_MATRIX_PROJECTION); geLoadMatrix(scene->renderers[i].projection_matrix); }else{ geMatrixMode(GE_MATRIX_PROJECTION); geLoadMatrix(libge_context->projection_matrix); } geShaderUse(scene->renderers[i].shader); glUniform1f(scene->renderers[i].shader->loc_time, time); glUniform1f(scene->renderers[i].shader->loc_ratio, ((float)libge_context->width) / ((float)libge_context->height)); if(scene->fogEnabled){ glUniform1f(scene->renderers[i].shader->loc_fog_density, scene->fog->density); glUniform4f(scene->renderers[i].shader->loc_fog_color, scene->fog->color[0], scene->fog->color[1], scene->fog->color[2], scene->fog->color[3]); glUniform1f(scene->renderers[i].shader->loc_fog_start, scene->fog->start); glUniform1f(scene->renderers[i].shader->loc_fog_end, scene->fog->end); } /* if(scene->renderers[i].depth_enabled){ glEnable(GL_DEPTH_TEST); }else{ glDisable(GL_DEPTH_TEST); } if(scene->renderers[i].blend_enabled){ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }else{ glDisable(GL_BLEND); } */ if(scene->renderers[i].ext_func){ scene->renderers[i].ext_func(&scene->renderers[i], -1); } StaticLightingFunc2(scene, &scene->renderers[i], -1); for(j=0; j<scene->nDynamicLights; j++){ glUniform4f(scene->renderers[i].shader->loc_lights[j].loc_position, scene->dynamicLights[j].position.x, scene->dynamicLights[j].position.y, scene->dynamicLights[j].position.z, scene->dynamicLights[j].position.w); glUniform4f(scene->renderers[i].shader->loc_lights[j].loc_target, scene->dynamicLights[j].target.x, scene->dynamicLights[j].target.y, scene->dynamicLights[j].target.z, scene->dynamicLights[j].target.w); glUniform4f(scene->renderers[i].shader->loc_lights[j].loc_ambient, scene->dynamicLights[j].ambient[0], scene->dynamicLights[j].ambient[1], scene->dynamicLights[j].ambient[2], scene->dynamicLights[j].ambient[3]); glUniform4f(scene->renderers[i].shader->loc_lights[j].loc_diffuse, scene->dynamicLights[j].diffuse[0], scene->dynamicLights[j].diffuse[1], scene->dynamicLights[j].diffuse[2], scene->dynamicLights[j].diffuse[3]); glUniform4f(scene->renderers[i].shader->loc_lights[j].loc_specular, scene->dynamicLights[j].specular[0], scene->dynamicLights[j].specular[1], scene->dynamicLights[j].specular[2], scene->dynamicLights[j].specular[3]); glUniform1f(scene->renderers[i].shader->loc_lights[j].loc_attenuation, scene->dynamicLights[j].attenuation); glUniform1f(scene->renderers[i].shader->loc_lights[j].loc_spotCutoff, scene->dynamicLights[j].spot_cutoff); glUniform1f(scene->renderers[i].shader->loc_lights[j].loc_spotCosCutoff, scene->dynamicLights[j].spot_coscutoff); glUniform1f(scene->renderers[i].shader->loc_lights[j].loc_spotExponent, scene->dynamicLights[j].spot_exponent); } for(j=0; j<scene->nLights; j++){ glUniform4f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_position, scene->lights[j].position.x, scene->lights[j].position.y, scene->lights[j].position.z, scene->lights[j].position.w); glUniform4f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_target, scene->lights[j].target.x, scene->lights[j].target.y, scene->lights[j].target.z, scene->lights[j].target.w); glUniform4f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_ambient, scene->lights[j].ambient[0], scene->lights[j].ambient[1], scene->lights[j].ambient[2], scene->lights[j].ambient[3]); glUniform4f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_diffuse, scene->lights[j].diffuse[0], scene->lights[j].diffuse[1], scene->lights[j].diffuse[2], scene->lights[j].diffuse[3]); glUniform4f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_specular, scene->lights[j].specular[0], scene->lights[j].specular[1], scene->lights[j].specular[2], scene->lights[j].specular[3]); if(!scene->lights[j].used){ glUniform1f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_attenuation, -1.0); }else if(scene->lights[j].type != GE_LIGHT_TYPE_SPOT){ glUniform1f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_attenuation, -2.0); }else{ glUniform1f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_attenuation, scene->lights[j].attenuation); } glUniform1f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_spotCutoff, scene->lights[j].spot_cutoff); glUniform1f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_spotCosCutoff, scene->lights[j].spot_coscutoff); glUniform1f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_spotExponent, scene->lights[j].spot_exponent); glUniform3f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_vector, scene->lights[j].vector.x, scene->lights[j].vector.y, scene->lights[j].vector.z); glUniform3f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_targetVector, scene->lights[j].target_vector.x, scene->lights[j].target_vector.y, scene->lights[j].target_vector.z); glUniform1f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_CosInnerMinusOuterAngle, scene->lights[j].CosInnerMinusOuterAngle); glUniform1f(scene->renderers[i].shader->loc_lights[j+8/*j+scene->nDynamicLights*/].loc_CosOuterConeAngle, scene->lights[j].CosOuterConeAngle); } if(ge_current_camera){ glUniform3f(scene->renderers[i].shader->loc_camera, ge_current_camera->x, ge_current_camera->y, ge_current_camera->z); } geRenderObjects(&scene->renderers[i]); if(scene->renderers[i].callback){ scene->renderers[i].callback(&scene->renderers[i], -1); } } }
void geBlitImageDepthStretchedRotated(int x, int y, int z, ge_Image* img, int _sx, int _sy, int ex, int ey, int width, int height, float angle, int flags){ if(!img)return; if((t_ptr)img==0xBAADF00D)return; if(!img->id)return; if(abs(z) > 2048){ return; } if(!(flags & GE_BLIT_NOOFFSET)){ x += libge_context->draw_off_x; y += libge_context->draw_off_y; } if(flags & GE_BLIT_NOALPHA){ glDisable(GL_ALPHA_TEST); glDisable(GL_BLEND); }else{ glEnable(GL_ALPHA_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } float texMaxX = img->u; float texMaxY = img->v; float sx = _sx*texMaxX/img->width; float sy = _sy*texMaxY/img->height; texMaxX = ex*texMaxX/img->width; texMaxY = ey*texMaxY/img->height; if(img->flags & GE_IMAGE_ANIMATED){ sy += ((_ge_ImageAnimated*)img)->_ge_n * img->v; if(geGetTickFloat() - ((_ge_ImageAnimated*)img)->_ge_t >= ((_ge_ImageAnimated*)img)->frameTime){ ((_ge_ImageAnimated*)img)->_ge_t = geGetTickFloat(); ((_ge_ImageAnimated*)img)->_ge_n = (((_ge_ImageAnimated*)img)->_ge_n + 1) % ((_ge_ImageAnimated*)img)->nImages; } } float Cos = geCos(angle); float Sin = geSin(-angle); float sw = Sin*width*0.5; float sh = Sin*height*0.5; float cw = Cos*width*0.5; float ch = Cos*height*0.5; int mw = 0; int mh = 0; if(!(flags & GE_BLIT_CENTERED)){ mw = (width-x) / 2; mh = (height-y) / 2; mw += (int)((x - cw - sh) - (x - cw + sh)); mh += (int)((y - sw + ch) - (y - sw - ch)); } x += mw; y += mh; if(!ge_current_shader){ geShaderUse(_ge_GetVideoContext()->shader2d); } if(ge_current_shader == _ge_GetVideoContext()->shader2d){ geShaderUniform1f(_ge_GetVideoContext()->loc_textured, 1.0); glUniform1f(_ge_GetVideoContext()->shader2d->loc_time, ((float)geGetTick()) / 1000.0); glUniform1f(_ge_GetVideoContext()->shader2d->loc_ratio, ((float)libge_context->width) / ((float)libge_context->height)); } glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, img->id); glBegin(GL_TRIANGLE_FAN); glColor4ub(R(img->color), G(img->color), B(img->color), A(img->color)); glTexCoord2f(sx, sy+texMaxY); glVertex3f(x - cw - sh, y - sw + ch, (float)z+libge_context->img_stack[z+2048]); glTexCoord2f(sx, sy); glVertex3f(x - cw + sh, y - sw - ch, (float)z+libge_context->img_stack[z+2048]); glTexCoord2f(sx+texMaxX, sy); glVertex3f(x + cw + sh, y + sw - ch, (float)z+libge_context->img_stack[z+2048]); glTexCoord2f(sx+texMaxX, sy+texMaxY);glVertex3f(x + cw - sh, y + sw + ch, (float)z+libge_context->img_stack[z+2048]); glEnd(); libge_context->img_stack[z+2048] += 0.001; }
void geSceneDraw(ge_Scene* scene){ current_scene = scene; int i = 0; int j = 0; CalculateModelMatrices(); if(scene->sky.animator){ geRendererUse(&scene->sky); geShaderUniform1f(scene->sky.depth_enabled, ((float)geGetTick())/1000.0); geMatrixMode(GE_MATRIX_MODEL); geLoadIdentity(); geUpdateMatrix(); for(i=0; i< scene->sky.nObjs; i++){ glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, scene->sky.objs[i]->material.textures[0]->id); if(scene->sky.objs[i]->material.textures[1]){ glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, scene->sky.objs[i]->material.textures[1]->id); // geShaderUniform1i(geShaderUniformID(scene->sky.shader, "ge_Texture1"), 1); } glDrawArrays(GL_TRIANGLES, scene->sky.objs[i]->vert_start, scene->sky.objs[i]->nVerts); } } if(scene->cloudsGenerator){ // DrawClouds(scene); } float time = ((float)geGetTick()) / 1000.0; for(i=0; i<scene->nRenderers; i++){ if(scene->renderers[i].enabled && scene->renderers[i].extension){ if(((ge_type32_struct*)scene->renderers[i].extension)->type == GE_RENDERER_WATER){ geWaterRender(&scene->renderers[i], ge_current_camera, (void(*)(void*))geSceneDraw, scene); } } } for(i=0; i<scene->nRenderers; i++){ if(scene->renderers[i].enabled == false)continue; ge_Shader* fforce = NULL; if(scene->render_mode == GE_SCENE_RENDER_SHADOW && scene->renderers[i].shadow_shader){ fforce = geForceShader(scene->renderers[i].shadow_shader); } /* if(scene->renderers[i].matrix_used){ geMatrixMode(GE_MATRIX_PROJECTION); geLoadMatrix(scene->renderers[i].projection_matrix); }else{ geMatrixMode(GE_MATRIX_PROJECTION); geLoadMatrix(libge_context->projection_matrix); } */ geShaderUse(scene->renderers[i].shader); glUniform1f(scene->renderers[i].shader->loc_time, time); glUniform1f(scene->renderers[i].shader->loc_ratio, ((float)libge_context->width) / ((float)libge_context->height)); if(scene->fogEnabled){ glUniform1f(scene->renderers[i].shader->loc_fog_density, scene->fog->density); glUniform4f(scene->renderers[i].shader->loc_fog_color, scene->fog->color[0], scene->fog->color[1], scene->fog->color[2], scene->fog->color[3]); glUniform1f(scene->renderers[i].shader->loc_fog_start, scene->fog->start); glUniform1f(scene->renderers[i].shader->loc_fog_end, scene->fog->end); } if(scene->renderers[i].ext_func){ scene->renderers[i].ext_func(&scene->renderers[i], -1); } geRendererUpdate(&scene->renderers[i]); if(ge_current_camera){ glUniform3f(scene->renderers[i].shader->loc_camera, ge_current_camera->x, ge_current_camera->y, ge_current_camera->z); } geRenderObjects(&scene->renderers[i]); if(scene->renderers[i].callback){ scene->renderers[i].callback(&scene->renderers[i], -1); } if(scene->render_mode == GE_SCENE_RENDER_SHADOW && scene->renderers[i].shadow_shader && fforce){ geForceShader(fforce); } } }
float geGetTickFloat(){ return (double)geGetTick() / 1000.0; }
void _geGui_AreaRender(int x, int y, ge_GuiArea* area, ge_GuiStyle* style){ int mx, my; int i = 0; geCursorPosition(&mx, &my); ge_GuiKeyEvent key_e; memcpy(key_e.pressed, libge_context->ge_keys->pressed, sizeof(u8)*(GE_KEYS_COUNT+32)); for(i=0; i<area->nObjects; i++){ area->objs[i].absx = x + area->objs[i].x + area->x; area->objs[i].absy = y + area->objs[i].y + area->y; if(area->objs[i].flags & GE_GUI_ALIGNX_CENTER){ area->objs[i].absx += area->width / 2; } if(area->objs[i].flags & GE_GUI_ALIGNY_CENTER){ area->objs[i].absy += area->height / 2; } if(area->objs[i].flags & GE_GUI_ALIGNX_RIGHT){ area->objs[i].absx += area->width; } if(area->objs[i].flags & GE_GUI_ALIGNY_BOTTOM){ area->objs[i].absy += area->height; } ge_GuiWidget* widget = (ge_GuiWidget*)area->objs[i].object; if(!widget || !widget->visible || !area->objs[i].render){ continue; } if(!widget->enabled && widget->img){ widget->img->color = RGBA(190, 190, 190, 255); }else if(widget->img){ widget->img->color = RGBA(255, 255, 255, 255); } if(widget->enabled && mx >= area->objs[i].absx && my >= area->objs[i].absy && mx <= (area->objs[i].absx+widget->width) && my <= (area->objs[i].absy+widget->height)){ if(geKeysToggled(libge_context->ge_keys, GEK_LBUTTON)){ widget->focused = true; widget->gotfocus = true; _ge_gui_focused_widget = widget; } }else if(widget->focused == true && widget->gotfocus == false){ if(geKeysToggled(libge_context->ge_keys, GEK_LBUTTON)){ widget->lostfocus = true; widget->focused = false; } } if(widget->focused && widget->KeyEventFunc){ widget->KeyEventFunc(widget, &key_e); } if(widget->focused && widget->CursorEventFunc && geKeysToggled(libge_context->ge_keys, GEK_LBUTTON)){ if(!widget->cursor_event){ widget->cursor_event = (ge_GuiCursorEvent*)geMalloc(sizeof(ge_GuiCursorEvent)); widget->last_cursor_event = (ge_GuiCursorEvent*)geMalloc(sizeof(ge_GuiCursorEvent)); } widget->cursor_event->x = mx - widget->x; widget->cursor_event->y = my - widget->y; widget->cursor_event->last_x = _ge_gui_cursor_last_x - widget->x; widget->cursor_event->last_y = _ge_gui_cursor_last_y - widget->y; widget->cursor_event->warp_x = (widget->cursor_event->last_x - widget->cursor_event->x) - widget->x; widget->cursor_event->warp_y = (widget->cursor_event->last_y - widget->cursor_event->y) - widget->y; widget->cursor_event->ticks = geGetTick(); widget->cursor_event->last = widget->last_cursor_event; widget->CursorEventFunc(widget, widget->cursor_event); memcpy(widget->last_cursor_event, widget->cursor_event, sizeof(ge_GuiCursorEvent)); } area->objs[i].render(&area->objs[i], style); widget->gotfocus = false; widget->lostfocus = false; } _ge_gui_cursor_last_x = mx; _ge_gui_cursor_last_y = my; }