/* XImage allocation for normal client-side buffer */ void _ggi_x_freefb(struct ggi_visual *vis) { ggi_x_priv *priv = GGIX_PRIV(vis); if (priv->slave) { struct gg_stem *stem = priv->slave->instance.stem; ggiClose(priv->slave->instance.stem); ggDelStem(stem); priv->slave = NULL; } if (priv->ximage) { #ifndef HAVE_XINITIMAGE XFree(priv->ximage); #else free(priv->ximage); #endif priv->ximage = NULL; } if (priv->fb) { free(priv->fb); priv->fb = NULL; } LIB_ASSERT(priv->slave == NULL, "priv->slave: wild pointer\n"); LIB_ASSERT(priv->ximage == NULL, "priv->ximage: wild pointer\n"); LIB_ASSERT(priv->fb == NULL, "priv->fb: wild pointer\n"); _ggi_free_dbs(vis); }
/* _ggi_db_add_buffer Adds a buffer at the end of the list. Returns the position of the buffer (starting with 0). */ int _ggi_db_add_buffer(ggi_db_list *dbl, ggi_directbuffer *buf) { LIB_ASSERT(dbl != NULL, "_ggi_db_add_buffer: list is NULL"); LIB_ASSERT(buf != NULL, "_ggi_db_add_buffer: buffer is NULL"); dbl->num++; dbl->bufs = _ggi_realloc(dbl->bufs, sizeof(ggi_directbuffer *) * dbl->num); dbl->bufs[dbl->num-1] = buf; return dbl->num-1; }
/* _ggi_db_del_buffer Deletes the buffer at position idx from the list. Returns the number of buffers left in the list. */ int _ggi_db_del_buffer(ggi_db_list *dbl, int idx) { LIB_ASSERT(dbl != NULL, "_ggi_db_del_buffer: list is NULL"); LIB_ASSERT(dbl->num > 0, "_ggi_db_del_buffer: called for empty list"); dbl->num--; memmove(dbl->bufs+idx, dbl->bufs+idx+1, (dbl->num-idx)*sizeof(ggi_directbuffer)); if (dbl->num == 0) { free(dbl->bufs); dbl->bufs = NULL; } else { dbl->bufs = _ggi_realloc(dbl->bufs, sizeof(ggi_directbuffer *) * dbl->num); } return dbl->num; }
/* XImage allocation for normal client-side buffer */ static void _ggi_xshm_free_ximage(struct ggi_visual *vis) { ggi_x_priv *priv; XShmSegmentInfo *myshminfo; priv = GGIX_PRIV(vis); myshminfo = priv->priv; if (myshminfo == NULL) return; if (priv->slave) { struct gg_stem *stem = priv->slave->instance.stem; ggiClose(priv->slave->instance.stem); ggDelStem(stem); priv->slave = NULL; } if (priv->ximage) { XShmDetach(priv->disp, myshminfo); /* Seems OK to destroy image before fb for SHM */ XDestroyImage(priv->ximage); shmdt(myshminfo->shmaddr); /* shmid has already been removed, see below. */ priv->ximage = NULL; priv->fb = NULL; } if (priv->fb) { free(priv->fb); priv->fb = NULL; } LIB_ASSERT(priv->slave == NULL, "priv->slave: wild pointer\n"); LIB_ASSERT(priv->ximage == NULL, "priv->ximage: wild pointer\n"); LIB_ASSERT(priv->fb == NULL, "priv->fb: wild pointer\n"); free(myshminfo); priv->priv = NULL; _ggi_free_dbs(vis); }
static int GGIclose(struct ggi_visual *vis, struct ggi_dlhandle *dlh) { suid_hook *priv = SUIDHOOK(vis); ggi_mode mode; int x; LIB_ASSERT(priv != NULL, "display-suidkgi: priv == NULL"); if (priv->is_up) { #if 1 /* Not sure, if this is needed, but ... */ mode.frames=1; mode.graphtype=GT_TEXT16; mode.visible.x=mode.virt.x=80; mode.visible.y=mode.virt.y=25; mode.dpp.x = 9;mode.dpp.y =14; x=GGI_suidkgi_checkmode(vis,&mode); DPRINT("TESTMODE1 says %d.\n",x); x=GGI_suidkgi_setmode(vis,&mode); DPRINT("SETMODE1 says %d.\n",x); #endif /* suidkgi_cleanup_module(); */ if (priv->vt_fd >= 0) { vtswitch_close(vis); priv->vt_fd = -1; } DPRINT("Cleanup went well.\n"); close(priv->dev_mem); priv->is_up=0; } if (vis->input) { giiClose(vis->input); vis->input = NULL; } free(priv); return 0; }
int GGI_directx_DDChangePalette(struct ggi_visual *vis) { directx_priv *priv = LIBGGI_PRIVATE(vis); int start = LIBGGI_PAL(vis)->rw_start; int stop = LIBGGI_PAL(vis)->rw_stop; ggi_color *clut = LIBGGI_PAL(vis)->clut.data; HRESULT hr; int x; static PALETTEENTRY pal[256]; LIB_ASSERT(priv->lpddp, "No palette!\n"); if (start >= stop) return 0; for (x = start; x < stop; x++) { pal[x].peFlags = PC_NOCOLLAPSE; pal[x].peRed = clut[x].r >> 8; pal[x].peGreen = clut[x].g >> 8; pal[x].peBlue = clut[x].b >> 8; } /* for (x = 0; x < 10; x++) { pal[x].peFlags = pal[x+246].peFlags = PC_EXPLICIT; pal[x].peRed = x; pal[x+246].peRed = x+246; pal[x].peGreen = pal[x].peBlue = 0; } */ hr = IDirectDrawPalette_SetEntries( priv->lpddp, 0, start, stop - start, &pal[start]); if (hr != 0) { fprintf(stderr, "DDP_SetEntries Failed RC = %ld. Exiting\n", hr & 0xffff); exit(-1); } return 0; }
int GIIdl_quartz(gii_input *inp, const char *args, void *argptr) { int rc = 0; gii_inputquartz_arg *quartzarg = argptr; quartz_priv *priv; DPRINT_MISC("quartz input starting. (args=%s,argptr=%p)\n", args, argptr); priv = calloc(1, sizeof(quartz_priv)); if (priv == NULL) { rc = GGI_ENOMEM; goto err0; } /* Attention: quartzarg->theWindow is invalid at this point. * It becomes valid once a mode has been set up. */ priv->theWindow = quartzarg->theWindow; #if 0 LIB_ASSERT(priv->theWindow != NULL, "quartzarg->theWindow is NULL\n"); #endif if (0 == (priv->origin[QZ_DEV_KEY] = _giiRegisterDevice(inp, &key_devinfo, NULL))) { rc = GGI_ENODEVICE; goto err1; } /* if */ if (0 == (priv->origin[QZ_DEV_MOUSE] = _giiRegisterDevice(inp, &mouse_devinfo, NULL))) { rc = GGI_ENODEVICE; goto err1; } /* if */ if (GGI_OK != QuartzInit(priv)) { rc = GGI_ENODEVICE; goto err2; } inp->GIIsendevent = GII_quartz_send_event; inp->GIIeventpoll = GII_quartz_eventpoll; #if 0 inp->GIIseteventmask = GII_quartz_seteventmask; inp->GIIgeteventmask = GII_quartz_geteventmaks; #endif inp->GIIclose = GII_quartz_close; inp->targetcan = emKey | emPointer; inp->curreventmask = emKey | emPointer; inp->maxfd = 0; /* We poll from an event queue - ouch! */ inp->flags |= GII_FLAGS_HASPOLLED; inp->priv = priv; inp->GIIseteventmask(inp, inp->targetcan); if (GGI_OK != QuartzFinishLaunch(inp)) { rc = GGI_ENODEVICE; goto err2; } send_devinfo(inp, QZ_DEV_KEY); send_devinfo(inp, QZ_DEV_MOUSE); DPRINT_MISC("quartz input fully up\n"); return GGI_OK; err2: err1: GII_quartz_close(inp); err0: return rc; } /* GIIdlinit */
/* _ggi_db_free Frees a ggi_directbuffer obtained from _ggi_db_get_new. */ void _ggi_db_free(ggi_directbuffer *db) { LIB_ASSERT(db != NULL, "_ggi_db_free: db is NULL"); free(db); }
static int _ggi_clip2d(ggi_visual *vis,int *_x0, int *_y0, int *_x1, int *_y1, int *clip_first, int *clip_last) { int first,last, code; int x0,y0,x1,y1; int x,y; int dx,dy; unsigned int absdx, absdy; int xmajor; int slope; int i; *clip_first = first = 0; *clip_last = last = 0; outcode(first,*_x0,*_y0); outcode(last,*_x1,*_y1); if ((first | last) == 0) { return 1; /* Trivially accepted! */ } if ((first & last) != 0) { return 0; /* Trivially rejected! */ } x0=*_x0; y0=*_y0; x1=*_x1; y1=*_y1; dx = x1 - x0; dy = y1 - y0; absdx = x0 < x1 ? x1 - x0 : x0 - x1; absdy = y0 < y1 ? y1 - y0 : y0 - y1; xmajor = absdx > absdy; slope = ((x1>=x0) && (y1>=y0)) || ((x1<x0) && (y1<y0)); if ((absdx > MAX_DIFF) || (absdy > MAX_DIFF)) { return _ggi_clip2d_3(vis, _x0, _y0, _x1, _y1, clip_first, clip_last); } for (i = 0; i < 4; i++) { code = first; if (first==0) code = last; if (code&OC_LEFT) { x = LIBGGI_GC(vis)->cliptl.x; if (xmajor) { y = *_y0 + FloorDiv(dy*(x - *_x0)*2 + dx, 2*dx); } else { if (slope) { y = *_y0 + CeilDiv(dy*((x - *_x0)*2 - 1), 2*dx); } else { y = *_y0 + FloorDiv(dy*((x - *_x0)*2 - 1), 2*dx); } } } else if (code&OC_RIGHT) { x = LIBGGI_GC(vis)->clipbr.x - 1; if (xmajor) { y = *_y0 + FloorDiv(dy*(x - *_x0)*2 + dx, 2*dx); } else { if (slope) { y = *_y0 + CeilDiv(dy*((x - *_x0)*2 + 1), 2*dx)-1; } else { y = *_y0 + FloorDiv(dy*((x - *_x0)*2 + 1), 2*dx)+1; } } } else if (code&OC_TOP) { y = LIBGGI_GC(vis)->cliptl.y; if (xmajor) { if (slope) { x = *_x0 + CeilDiv(dx*((y - *_y0)*2 - 1), 2*dy); } else { x = *_x0 + FloorDiv(dx*((y - *_y0)*2 - 1), 2*dy); } } else { x = *_x0 + FloorDiv( dx*(y - *_y0)*2 + dy, 2*dy); } } else { /* OC_BOTTOM */ LIB_ASSERT((code & OC_BOTTOM), "unknown outcode\n"); y = LIBGGI_GC(vis)->clipbr.y - 1; if (xmajor) { if (slope) { x = *_x0 + CeilDiv(dx*((y - *_y0)*2 + 1), 2*dy)-1; } else { x = *_x0 + FloorDiv(dx*((y - *_y0)*2 + 1), 2*dy)+1; } } else { x = *_x0 + FloorDiv(dx*(y - *_y0)*2 + dy, 2*dy); } } if (first!=0) { x0 = x; y0 = y; outcode(first,x0,y0); *clip_first = 1; } else { x1 = x; y1 = y; last = code; outcode(last,x1,y1); *clip_last = 1; } if ((first & last) != 0) { return 0; /* Trivially rejected! */ } if ((first | last) == 0) { *_x0=x0; *_y0=y0; *_x1=x1; *_y1=y1; return 1; /* Trivially accepted! */ } } return 0; /* Aieee! Failed to clip, clip whole line... */ }
static int _ggi_clip2d_3(ggi_visual *vis, int *_x0, int *_y0, int *_x1, int *_y1, int *clip_first, int *clip_last) { int first,last, code; int x0,y0,x1,y1; int x,y; unsigned dx[3], dy[3], tmp[3]; unsigned int absdx, absdy; int xmajor; int slope; int i; *clip_first = first = 0; *clip_last = last = 0; outcode(first,*_x0,*_y0); outcode(last,*_x1,*_y1); if ((first | last) == 0) { return 1; /* Trivially accepted! */ } if ((first & last) != 0) { return 0; /* Trivially rejected! */ } x0=*_x0; y0=*_y0; x1=*_x1; y1=*_y1; assign_int_3(dx, x1); assign_int_3(tmp, x0); sub_3(dx, tmp); assign_int_3(dy, y1); assign_int_3(tmp, y0); sub_3(dy, tmp); absdx = x0 < x1 ? x1 - x0 : x0 - x1; absdy = y0 < y1 ? y1 - y0 : y0 - y1; xmajor = absdx > absdy; slope = ((x1>=x0) && (y1>=y0)) || ((x1<x0) && (y1<y0)); for (i = 0; i < 4; i++) { code = first; if (first==0) code = last; if (code&OC_LEFT) { x = LIBGGI_GC(vis)->cliptl.x; if (xmajor) { /* y = *_y0 + FloorDiv(dy*(x - *_x0)*2 + dx, 2*dx); */ unsigned _x[3], res[3]; assign_int_3(_x, x); assign_int_3(tmp, *_x0); sub_3(_x, tmp); lshift_3(_x, 1); mul_3(_x, dy); add_3(_x, dx); assign_3(tmp, dx); lshift_3(tmp, 1); FloorDiv_3(res, _x, tmp); assign_int_3(tmp, *_y0); add_3(res, tmp); y = res[0]; } else if (slope) { /* y = *_y0 + CeilDiv(dy*((x - *_x0)*2 - 1), 2*dx); */ unsigned _x[3], res[3]; assign_int_3(_x, x); assign_int_3(tmp, *_x0); sub_3(_x, tmp); lshift_3(_x, 1); dec_3(_x); mul_3(_x, dy); assign_3(tmp, dx); lshift_3(tmp, 1); CeilDiv_3(res, _x, tmp); assign_int_3(tmp, *_y0); add_3(res, tmp); y = res[0]; } else { /* y = *_y0 + FloorDiv(dy*((x - *_x0)*2 - 1), 2*dx); */ unsigned _x[3], res[3]; assign_int_3(_x, x); assign_int_3(tmp, *_x0); sub_3(_x, tmp); lshift_3(_x, 1); dec_3(_x); mul_3(_x, dy); assign_3(tmp, dx); lshift_3(tmp, 1); FloorDiv_3(res, _x, tmp); assign_int_3(tmp, *_y0); add_3(res, tmp); y = res[0]; } } else if (code&OC_RIGHT) { x = LIBGGI_GC(vis)->clipbr.x - 1; if (xmajor) { /* y = *_y0 + FloorDiv(dy*(x - *_x0)*2 + dx, 2*dx); */ unsigned _x[3], res[3]; assign_int_3(_x, x); assign_int_3(tmp, *_x0); sub_3(_x, tmp); lshift_3(_x, 1); mul_3(_x, dy); add_3(_x, dx); assign_3(tmp, dx); lshift_3(tmp, 1); FloorDiv_3(res, _x, tmp); assign_int_3(tmp, *_y0); add_3(res, tmp); y = res[0]; } else if (slope) { /* y = *_y0 + CeilDiv(dy*((x - *_x0)*2 + 1), 2*dx)-1; */ unsigned _x[3], res[3]; assign_int_3(_x, x); assign_int_3(tmp, *_x0); sub_3(_x, tmp); lshift_3(_x, 1); inc_3(_x); mul_3(_x, dy); assign_3(tmp, dx); lshift_3(tmp, 1); CeilDiv_3(res, _x, tmp); dec_3(res); assign_int_3(tmp, *_y0); add_3(res, tmp); y = res[0]; } else { /* y = *_y0 + FloorDiv(dy*((x - *_x0)*2 + 1), 2*dx)+1; */ unsigned _x[3], res[3]; assign_int_3(_x, x); assign_int_3(tmp, *_x0); sub_3(_x, tmp); lshift_3(_x, 1); inc_3(_x); mul_3(_x, dy); assign_3(tmp, dx); lshift_3(tmp, 1); FloorDiv_3(res, _x, tmp); inc_3(res); assign_int_3(tmp, *_y0); add_3(res, tmp); y = res[0]; } } else if (code&OC_TOP) { y = LIBGGI_GC(vis)->cliptl.y; if (!xmajor) { /* x = *_x0 + FloorDiv(dx*(y - *_y0)*2 + dy, 2*dy); */ unsigned _y[3], res[3]; assign_int_3(_y, y); assign_int_3(tmp, *_y0); sub_3(_y, tmp); lshift_3(_y, 1); mul_3(_y, dx); add_3(_y, dy); assign_3(tmp, dy); lshift_3(tmp, 1); FloorDiv_3(res, _y, tmp); assign_int_3(tmp, *_x0); add_3(res, tmp); x = res[0]; } else if (slope) { /* x = *_x0 + CeilDiv(dx*((y - *_y0)*2 - 1), 2*dy); */ unsigned _y[3], res[3]; assign_int_3(_y, y); assign_int_3(tmp, *_y0); sub_3(_y, tmp); lshift_3(_y, 1); dec_3(_y); mul_3(_y, dx); assign_3(tmp, dy); lshift_3(tmp, 1); CeilDiv_3(res, _y, tmp); assign_int_3(tmp, *_x0); add_3(res, tmp); x = res[0]; } else { /* x = *_x0 + FloorDiv(dx*((y - *_y0)*2 - 1), 2*dy); */ unsigned _y[3], res[3]; assign_int_3(_y, y); assign_int_3(tmp, *_y0); sub_3(_y, tmp); lshift_3(_y, 1); dec_3(_y); mul_3(_y, dx); assign_3(tmp, dy); lshift_3(tmp, 1); FloorDiv_3(res, _y, tmp); assign_int_3(tmp, *_x0); add_3(res, tmp); x = res[0]; } } else { /* OC_BOTTOM */ LIB_ASSERT((code & OC_BOTTOM), "unknown outcode\n"); y = LIBGGI_GC(vis)->clipbr.y - 1; if (!xmajor) { /* x = *_x0 + FloorDiv(dx*(y - *_y0)*2 + dy, 2*dy); */ unsigned _y[3], res[3]; assign_int_3(_y, y); assign_int_3(tmp, *_y0); sub_3(_y, tmp); lshift_3(_y, 1); mul_3(_y, dx); add_3(_y, dy); assign_3(tmp, dy); lshift_3(tmp, 1); FloorDiv_3(res, _y, tmp); assign_int_3(tmp, *_x0); add_3(res, tmp); x = res[0]; } else if (slope) { /* x = *_x0 + CeilDiv(dx*((y - *_y0)*2 + 1), 2*dy)-1; */ unsigned _y[3], res[3]; assign_int_3(_y, y); assign_int_3(tmp, *_y0); sub_3(_y, tmp); lshift_3(_y, 1); inc_3(_y); mul_3(_y, dx); assign_3(tmp, dy); lshift_3(tmp, 1); CeilDiv_3(res, _y, tmp); dec_3(res); assign_int_3(tmp, *_x0); add_3(res, tmp); x = res[0]; } else { /* x = *_x0 + FloorDiv(dx*((y - *_y0)*2 + 1), 2*dy)+1; */ unsigned _y[3], res[3]; assign_int_3(_y, y); assign_int_3(tmp, *_y0); sub_3(_y, tmp); lshift_3(_y, 1); inc_3(_y); mul_3(_y, dx); assign_3(tmp, dy); lshift_3(tmp, 1); FloorDiv_3(res, _y, tmp); inc_3(res); assign_int_3(tmp, *_x0); add_3(res, tmp); x = res[0]; } } if (first!=0) { x0 = x; y0 = y; outcode(first,x0,y0); *clip_first = 1; } else { x1 = x; y1 = y; last = code; outcode(last,x1,y1); *clip_last = 1; } if ((first & last) != 0) { return 0; /* Trivially rejected! */ } if ((first | last) == 0) { *_x0=x0; *_y0=y0; *_x1=x1; *_y1=y1; return 1; /* Trivially accepted! */ } } return 0; /* Aieee! Failed to clip, clip whole line... */ }
void World::think() { auto world = Core_detail::world_index_get_world_data(m_impl->world_instance_id); LIB_ASSERT(world); /* Calculate Delta time. */ { const lib::milliseconds now = lib::timer::get_current_time(); const lib::milliseconds frame_time = lib::timer::get_delta(m_impl->dt_timer, now); m_impl->dt = lib::timer::to_seconds(frame_time); m_impl->dt_timer = now; m_impl->running_time += m_impl->dt; } /* Engine thing. Most of this can go I think, or at least be brought into here. */ Engine::Tick_information tick_info; { auto resources = Data::get_context_data(); LIB_ASSERT(resources); Engine::think( world, resources, m_impl->dt, m_impl->running_time, m_impl->context->get_width(), m_impl->context->get_height(), &tick_info); } /* Distro Collisions */ { Data::Physics::Physics_data *phys = world->physics; LIB_ASSERT(phys); Data::Graph::Graph_data *graph = world->scene_graph; LIB_ASSERT(graph); const size_t coll_count( Data::Physics::world_get_number_of_colliding_items(phys) ); const Data::Physics::Contact *contacts( Data::Physics::world_get_colliding_items(phys) ); for(size_t i = 0; i < coll_count; ++i) { uintptr_t collision_callback = 0; uintptr_t user_data = 0; const uint32_t this_id = lib::bits::lower32(contacts[i].collision_a_b); Data::Graph::node_get_collision_callback( graph, this_id, &user_data, &collision_callback ); if(collision_callback) { ((on_collision_callback_fn)collision_callback)( user_data, Entity_ref(this_id), to_core_collision(&contacts[i], 1) ); } } } /* Debug Menu -- Shows the debugging menu bar at the top of the screen. */ #ifdef CORE_DEBUG_MENU { auto world = Core_detail::world_index_get_world_data(m_impl->world_instance_id); Debug_menu::display_global_data_menu(m_impl->context->get_context_data()->input_pool); Debug_menu::display_world_data_menu( world.get(), m_impl->dt, m_impl->dt_mul, 12345, tick_info.number_of_draw_calls, tick_info.camera_runs ); } #endif }