cxu32 cx_str_explode (char **dst, cxu32 dstSize, const char *src, char delimiter) { CX_ASSERT (dst); CX_ASSERT (src); cxu32 count = 0; const char *start = src; const char *found = strchr (start, delimiter); while (found) { CX_ASSERT (count < dstSize); dst [count++] = cx_strdup (start, found - start); start = found + 1; found = strchr (start, delimiter); } CX_ASSERT (count < dstSize); if (*start != '\0') { dst [count++] = cx_strdup (start, strlen (start)); } return count; }
cxAtlas *cxAtlas::SetCoords(const cxArray *coords,const cxFrames *frames) { CX_ASSERT(!Size().IsZero(), "size not set"); cxInt size = frames->Num(); SetCapacity(size); const cxInt *map = frames->Map(); for(cxInt i = 0;i < size;i++){ cxInt mapIdx = map[i]; CX_ASSERT(mapIdx < coords->Size(), "map idx error"); //get map tex cxTexCoord *coord = coords->At(mapIdx)->To<cxTexCoord>(); if(coord->IsEmpty()){ continue; } //trimmed box cxBoxPoint3F bp = coord->Trimmed(BoxPoint(), Size(), FlipX(), FlipY()); if(bp.Size().IsZero()){ continue; } //add render cxBoxRender &render = renders.Inc(); render.SetVertices(bp); render.SetColor(Color()); //get coord box const cxBoxCoord2F &tbox = coord->BoxCoord(Pixel(), FlipX(), FlipY()); render.SetCoords(tbox); } return this; }
//support key.key key.0.0.1, max 8 level static json_t *jsonGetJson(json_t *json,cxConstChars key) { CX_ASSERT(cxConstCharsOK(key), "key error"); json_t *rv = json_object_get(json, key); if(rv != NULL){ return rv; } cxChars ckey = allocator->strdup(key); cxInt num = 0; cxChars ckeys[16]; cxChars src = ckey; ckeys[num++] = src; while (*src++ != '\0') { if(*src != '.')continue; CX_ASSERT(num < 16, ". opt too more"); ckeys[num++] = src + 1; *src++ = '\0'; } json_t *pv = json; cxInt index = 0; for(cxInt i=0; i < num;i ++){ cxConstChars ckey = ckeys[i]; if(cxKeyIsNumber(ckey, &index)){ rv = json_array_get(pv, index); }else{ rv = json_object_get(pv, ckey); } if(rv == NULL)break; pv = rv; } allocator->free(ckey); return rv; }
const cx_colour *_ui_intrinsic_colour_get (const ui_intrinsic_t *intr, ui_widget_state_t wstate) { CX_ASSERT (intr); CX_ASSERT ((wstate >= UI_WIDGET_STATE_NORMAL) && (wstate < NUM_UI_WIDGET_STATES)); return &intr->colour [wstate]; }
cxu32 cx_str_utf8_to_unicode (cxu32 *dst, cxu32 dstSize, const char *utf8src) { cxu32 dstLen = 0; cxu32 srcSize = strlen (utf8src); // data length CX_ASSERT ((srcSize < dstSize) && "dstSize too small"); const cxu8 *src = (const cxu8 *) utf8src; cxi32 ss = srcSize; #if CX_DEBUG cxi32 srcCount = 0; #endif while ((ss > 0) && (dstLen < (dstSize - 1))) { cxu32 ch = 0; cxu32 offset = cx_str_utf8_decode (&ch, src); CX_ASSERT (dstLen < dstSize); dst [dstLen++] = ch; src += offset; ss -= offset; #if CX_DEBUG srcCount += offset; #endif } dst [dstLen] = 0; return dstLen; }
void _ui_intrinsic_colour_set (ui_intrinsic_t *intr, ui_widget_state_t wstate, const cx_colour *colour) { CX_ASSERT (intr); CX_ASSERT (colour); CX_ASSERT ((wstate >= UI_WIDGET_STATE_NORMAL) && (wstate < NUM_UI_WIDGET_STATES)); intr->colour [wstate] = *colour; }
void _ui_intrinsic_texture_set (ui_intrinsic_t *intr, ui_widget_state_t wstate, cx_texture *texture) { CX_ASSERT (intr); CX_ASSERT (texture); CX_ASSERT ((wstate >= UI_WIDGET_STATE_NORMAL) && (wstate < NUM_UI_WIDGET_STATES)); intr->texture [wstate] = texture; }
cxArray *cxArray::Swap(cxInt src,cxInt dst) { CX_ASSERT(src >= 0 && src < Size(), "src out bound"); CX_ASSERT(dst >= 0 && dst < Size(), "dst out bound"); cxObject **ptr = (cxObject **)mv.data(); CX_SWAP_VAR(ptr[src], ptr[dst]); return this; }
void input_register_gesture_event_callback (input_gesture_type type, input_gesture_event_callback fn) { CX_ASSERT (g_initialised); CX_ASSERT ((type > INPUT_GESTURE_TYPE_INVALID) && (type < NUM_INPUT_GESTURE_TYPES)); CX_ASSERT (!cx_list2_exists (&g_gestureEventCallbacks [type], fn)); cx_list2_insert_back (&g_gestureEventCallbacks [type], fn); }
void input_register_touch_event_callback (input_touch_type type, input_touch_event_callback fn) { CX_ASSERT (g_initialised); CX_ASSERT ((type > INPUT_TOUCH_TYPE_INVALID) && (type < NUM_INPUT_TOUCH_TYPES)); CX_ASSERT (!cx_list2_exists (&g_touchEventCallbacks [type], fn)); cx_list2_insert_back (&g_touchEventCallbacks [type], fn); }
cxAtlas *cxAtlas::SetFramesIdx(cxInt idx) { CX_ASSERT(cframes != nullptr, "frames not set"); cidx = idx; const cxArray *layers = cframes->Layers(idx); CX_ASSERT(layers != nullptr, "frames null"); SetTexture(cframes->Texture()); SetCoords(layers, cframes); return this; }
cxu32 cx_str_utf8_decode (cxu32 *dst, const cxu8 *src) { CX_ASSERT (dst); CX_ASSERT (src); cxu32 ch = 0; cxu32 offset = 0; if ((src [0] & UTF8_BYTE6) == UTF8_BYTE6) { offset = 6; } else if ((src [0] & UTF8_BYTE5) == UTF8_BYTE5) { offset = 5; } else if ((src [0] & UTF8_BYTE4) == UTF8_BYTE4) { ch = ((src [0] & 0x07) << 18) | ((src [1] & 0x3f) << 12) | ((src [2] & 0x3f) << 6) | ((src [3] & 0x3f)); offset = 4; } else if ((src [0] & UTF8_BYTE3) == UTF8_BYTE3) { ch = ((src [0] & 0x0f) << 12) | ((src [1] & 0x3f) << 6) | ((src [2] & 0x3f)); offset = 3; } else if ((src [0] & UTF8_BYTE2) == UTF8_BYTE2) { ch = ((src [0] & 0x1f) << 6) | ((src [1] & 0x3f)); offset = 2; } else if (src [0] < UTF8_BYTE1) { ch = (src [0]); offset = 1; } else { offset = strlen ((const char *) src); CX_ERROR ("Invalid UTF8 character"); } *dst = ch; return offset; }
bool ui_do_button (ui_context_t *context, const ui_button_t *button) { CX_ASSERT (context); CX_ASSERT (button); bool ret = false; bool isHot = (button->elem == context->hover); bool isActive = (button->elem == context->active); if (isHot) { // is touch event end, return true; if (context->event.type == INPUT_TOUCH_TYPE_END) { bool isInside = ui_touch_hit (context, button->elem); if (isInside) { context->active = button->elem; ret = true; } } // render hover skin ui_render_element (button->elem); } else if (isActive) { // render active skin ui_render_element (button->elem); } else { // is touch event begin, return true; if (context->event.type == INPUT_TOUCH_TYPE_BEGIN) { // if touch event inside, set hover bool isInside = ui_touch_hit (context, button->elem); if (isInside) { context->hover = button->elem; } } // render normal skin ui_render_element (button->elem); } return ret; }
static void input_process_cached_events (void) { CX_ASSERT (g_initialised); if (g_gestureEventsCount > 0) { g_touchEventsCount = 0; } // gesture events for (unsigned i = 0, c = g_gestureEventsCount; i < c; ++i) { const input_gesture_event *gestureEvent = &g_gestureEventsCache [i]; cx_list2 *list = &g_gestureEventCallbacks [gestureEvent->type]; cx_list2_node *cb = list->head; while (cb) { CX_ASSERT (cb->data); input_gesture_event_callback fn = (input_gesture_event_callback) cb->data; fn (gestureEvent); cb = cb->next; } } // touch events for (unsigned i = 0, c = g_touchEventsCount; i < c; ++i) { const input_touch_event *touchEvent = &g_touchEventsCache [i]; cx_list2 *list = &g_touchEventCallbacks [touchEvent->type]; cx_list2_node *cb = list->head; while (cb) { CX_ASSERT (cb->data); input_touch_event_callback fn = (input_touch_event_callback) cb->data; fn (touchEvent); cb = cb->next; } } }
cxJson cxJsonCreate(cxString json) { CX_ASSERT(json != NULL, "args error"); cxJson this = CX_CREATE(cxJson); json_error_t error = {0}; if(cxStringLength(json) <= 0){ return this; } this->json = json_loadb(cxStringBody(json), cxStringLength(json), JSON_DECODE_ANY, &error); CX_ASSERT(this->json != NULL, "cxJson load error (%d:%d) %s:%s",error.line,error.column,error.source,error.text); return this; }
static ui_intrinsic_t *ui_ctx_input_hit (ui_context_t *ctx, const cx_vec2 *point, bool ext) { CX_FATAL_ASSERT (ctx); CX_ASSERT (point); ui_intrinsic_t *hit = NULL; cx_list2_node *intrNode = ctx->intrList.tail; float tx = ctx->canvasWidth * point->x; float ty = ctx->canvasHeight * point->y; while (intrNode) { ui_intrinsic_t *intr = (ui_intrinsic_t *) intrNode->data; CX_ASSERT (intr); if (intr->enable) { float w = intr->dimension.x; float h = intr->dimension.y; float x = intr->position.x; float y = intr->position.y; if (ext && (ctx->hover == intr)) { const float ex = 4.0f; const float ey = 6.0f; w += ex; h += ey; x -= (ex * 0.5f); y -= (ey * 0.5f); } if ((tx >= x) && (tx <= (x + w))) { if ((ty >= y) && (ty <= (y + h))) { hit = intr; break; } } } intrNode = intrNode->prev; } return hit; }
static void ui_ctx_render_checkbox (ui_context_t *ctx, ui_checkbox_t *checkbox) { CX_FATAL_ASSERT (ctx); CX_ASSERT (checkbox); ui_checkbox_callbacks_t *callbacks = (ui_checkbox_callbacks_t *) checkbox->_callbacks; if (callbacks && callbacks->renderFn) { callbacks->renderFn (checkbox); } else { // default render ui_widget_state_t wstate = ui_ctx_widget_state (ctx, &checkbox->intr); if (checkbox->checked) { } else { } float x1 = checkbox->intr.position.x; float y1 = checkbox->intr.position.y; float x2 = x1 + checkbox->intr.dimension.x; float y2 = y1 + checkbox->intr.dimension.y; cx_texture *texture = checkbox->intr.texture [wstate]; cx_colour colour = checkbox->intr.colour [wstate]; cx_draw_quad (x1, y1, x2, y2, 0.0f, 0.0f, &colour, texture); } }
static void input_clear_cached_events (void) { CX_ASSERT (g_initialised); g_touchEventsCount = 0; g_gestureEventsCount = 0; }
void input_update (void) { CX_ASSERT (g_initialised); input_process_cached_events (); input_clear_cached_events (); }
cxTexture cxTextureCreate(cxConstChars file) { cxTexture texture = NULL; CX_ASSERT(file != NULL, "file args error"); cxStream stream = cxAssetsStreamCreate(file); if(stream == NULL){ CX_ERROR("create stream from file %s failed",file); return NULL; } char *ext = strrchr(file, '.'); if(ext == NULL){ CX_ERROR("unknow file ext name"); return NULL; } if(cxConstCharsEqu(ext, ".png")){ texture = cxTexturePNGLoadStream(stream); }else if(cxConstCharsEqu(ext, ".pvr")){ texture = cxTexturePVRLoadStream(stream); }else if(cxConstCharsEqu(ext, ".xml")){ texture = cxTextureXMLLoadStream(stream); }else if(cxConstCharsEqu(ext, ".pkm")){ texture = cxTexturePKMLoadStream(stream); }else if(cxConstCharsEqu(ext, ".jpg") || cxConstCharsEqu(ext, ".jpeg")){ texture = cxTextureJPGLoadStream(stream); }else{ CX_ERROR("load texture failed %s",file); } return texture; }
cxAny cxPlayEffect(cxConstChars file,cxBool loop) { cxPlayer this = cxPlayerInstance(); JniMethodInfo methodInfo; cxBool ret = cxGetStaticMethodInfo(&methodInfo, CLASS_NAME, "cxEnginePlayEffect","(Ljava/lang/String;Z)I"); CX_ASSERT(ret, "get static method info failed"); CX_UNUSED_PARAM(ret); jstring path = (*methodInfo.env)->NewStringUTF(methodInfo.env,file); cxInt soundId = (*methodInfo.env)->CallStaticIntMethod(methodInfo.env, methodInfo.classID, methodInfo.methodID, path, loop); (*methodInfo.env)->DeleteLocalRef(methodInfo.env,path); if(soundId <= 0){ CX_ERROR("play file failed %s",file); return NULL; } cxTrack track = cxHashGet(this->tracks, cxHashStrKey(file)); //add or replace if(track == NULL || track->soundId != soundId){ track = CX_ALLOC(cxTrack); track->file = cxStringAllocChars(file); track->soundId = soundId; cxHashSet(this->tracks, cxHashStrKey(file), track); CX_RELEASE(track); } return track; }
static cxInt cxSpriteTexture(lua_State *L) { CX_LUA_DEF_THIS(cxReaderAttrInfo *); cxConstChars v = NULL; cxConstChars k = NULL; if(!lua_istable(L, 2)){ luaL_error(L, "args error"); return 0; } lua_getfield(L, 2, "v"); v = luaL_checkstring(L, -1); lua_pop(L, 1); lua_getfield(L, 2, "k"); k = luaL_checkstring(L, -1); lua_pop(L, 1); if(v == NULL){ luaL_error(L, "v args error"); return 0; } cxTextureAttr attr = CX_CREATE(cxTextureAttr); cxSprite sprite = cxViewRootGet(this->root, v); CX_ASSERT(sprite != NULL, "sprite is null"); CX_RETAIN_SWAP(attr->texture, sprite->texture); if(k != NULL){ attr->box = cxTextureBox(sprite->texture, k); attr->size = cxTextureSize(sprite->texture, k); } CX_LUA_PUSH_OBJECT(attr); return 1; }
void ui_render_element (const ui_intrinsic_t *elem) { CX_ASSERT (elem); float x1 = elem->position.x; float y1 = elem->position.y; float x2 = x1 + elem->dimension.x; float y2 = y1 + elem->dimension.y; cx_texture *texture = elem->texture [0]; cx_colour colour = elem->colour [0]; colour.a = elem->opacity; cx_draw_quad (x1, y1, x2, y2, 0.0f, 0.0f, &colour, texture); #if 0 if (elem->text && *elem->text) { float tx = 4.0f; float ty = 36.0f; cx_font_render (font, elem->text, tx, ty, 0.0f, CX_FONT_ALIGNMENT_DEFAULT, &elem->fgColour); } #endif }
cxArray *cxArray::Append(cxObject *obj) { CX_ASSERT(obj != nullptr && obj != this, "obj error"); mv.push_back(obj); obj->Retain(); return this; }
bool ui_touch_hit (ui_context_t *context, const ui_intrinsic_t *elem) { CX_ASSERT (elem); bool ret = false; float w = intr->dimension.x; float h = intr->dimension.y; float x = intr->position.x; float y = intr->position.y; float tx = ctx->canvasWidth * ctx->inputEv.point.x; float ty = ctx->canvasHeight * ctx->inputEv.point.y; if ((tx >= x) && (tx <= (x + w))) { if ((ty >= y) && (ty <= (y + h))) { ret = true; } } return ret; }
static void ui_ctx_add_intrinsic (ui_context_t *ctx, const ui_intrinsic_t *intr) { CX_FATAL_ASSERT (ctx); CX_ASSERT (intr); cx_list2_insert_front (&ctx->intrList, intr); }
static void ui_ctx_remove_intrinsic (ui_context_t *ctx, const ui_intrinsic_t *intr) { CX_FATAL_ASSERT (ctx); CX_ASSERT (intr); cx_list2_remove (&ctx->intrList, intr); }
static void ui_ctx_render_button (ui_context_t *ctx, ui_button_t *button) { CX_FATAL_ASSERT (ctx); CX_ASSERT (button); ui_button_callbacks_t *callbacks = (ui_button_callbacks_t *) button->_callbacks; if (callbacks && callbacks->renderFn) { callbacks->renderFn (button); } else { // do default render if (button->intr.show) { ui_widget_state_t wstate = ui_ctx_widget_state (ctx, &button->intr); float x1 = button->intr.position.x; float y1 = button->intr.position.y; float x2 = x1 + button->intr.dimension.x; float y2 = y1 + button->intr.dimension.y; cx_texture *texture = button->intr.texture [wstate]; cx_colour colour = button->intr.colour [wstate]; cx_draw_quad (x1, y1, x2, y2, 0.0f, 0.0f, &colour, texture); } } }
ui_widget_state_t _ui_intrinsic_widget_state_get (ui_context_t *ctx, const ui_intrinsic_t *intr) { CX_FATAL_ASSERT (ctx); CX_ASSERT (intr); return ui_ctx_widget_state (ctx, intr); }
/* { "func":"timeConvert", "args":60 } { "func":"timeConvert", "args":[1,3,4,5] } */ static cxConstChars jsonStrConvert(json_t *v) { cxJson json = cxJsonReference(v); cxStr txt = cxJsonDump(json); cxConstChars funcName = cxJsonConstChars(json, "func"); if(!cxConstCharsOK(funcName)){ return cxStrBody(txt); } cxConvert convert = cxGetConvert(funcName); if(convert == NULL){ return cxStrBody(txt); } CX_ASSERT(convert->func != NULL, "convert error"); cxStr ret = NULL; cxJson args = cxJsonAny(json, "args"); if(args == NULL){ ret = ((cxStr (*)(void))convert->func)(); }else if(cxJsonIsStr(args)){ cxConstChars a1 = cxJsonToConstChars(args); ret = ((cxStr (*)(cxConstChars))convert->func)(a1); }else if(cxJsonIsInt(args)){ cxInt a1 = cxJsonToInt(args, 0); ret = ((cxStr (*)(cxInt))convert->func)(a1); }else if(cxJsonIsDouble(args)){ cxDouble a1 = cxJsonToDouble(args, 0); ret = ((cxStr (*)(cxDouble))convert->func)(a1); }else if(cxJsonIsBool(args)){ cxBool a1 = cxJsonToBool(args, false); ret = ((cxStr (*)(cxBool))convert->func)(a1); }else{ ret = ((cxStr (*)(cxJson))convert->func)(args); } return ret == NULL ? NULL : cxStrBody(ret); }