/* --------------------------------------- 释放接口 --------------------------------------- */ static void_t iPAK_RAR_release ( __CR_IN__ iPACKAGE* that ) { leng_t idx; iPAK_RAR* real; sPAK_RAR_FILE* list; pack_free_list(that); real = (iPAK_RAR*)that; list = (sPAK_RAR_FILE*)real->pack.__filelst__; if (list != NULL) { for (idx = 0; idx < real->m_cnt; idx++) { mem_free(list[idx].base.find); mem_free(list[idx].base.name); } mem_free(list); } if (real->m_rar != NULL) RARCloseArchive(real->m_rar); TRY_FREE(real->m_ansi); TRY_FREE(real->m_wide); TRY_FREE(real->m_pass); mem_free(that); }
/* tries opening a file in a temporary win structure, and displays errors if unable */ int board_load_popup (window_board_t *win, int append, char *filename) { int i; int ret = 0; window_board_t *win1 = calloc (1, sizeof (window_board_t)); if (board_load (win1, filename)) { if (append) { int n = win->n_boards; for (i = 0; i < win1->n_boards; i++) board_window_append_board (win, win1->boards[i]); if (win->n_boards > n) /* set to first new board */ win->cur = n; } else { MOVE_PTR (win->filename, win1->filename); MOVE_PTR (win->title, win1->title); MOVE_PTR (win->subtitle, win1->subtitle); MOVE_PTR (win->team1, win1->team1); MOVE_PTR (win->team2, win1->team2); for (i = 0; i < win->n_boards; i++) if (win->boards[i]) board_free (win->boards[i]); win->boards = win1->boards; win->n_boards = win1->n_boards; win->n_boards_alloc = win1->n_boards_alloc; win->cur = 0; } card_window_update(win->boards[win->cur]->dealt_cards); show_board(win->boards[win->cur], REDRAW_FULL); recently_used_add (filename); ret = 1; } else { GtkWidget *error = gtk_message_dialog_new (GTK_WINDOW (win->window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Error loading file '%s': %s"), filename, g_strerror (errno)); gtk_dialog_run (GTK_DIALOG (error)); gtk_widget_destroy (error); } TRY_FREE (win1->filename); TRY_FREE (win1->title); TRY_FREE (win1->subtitle); TRY_FREE (win1->team1); TRY_FREE (win1->team2); free (win1); return ret; }
/* ======================================= 读入配置文件 ======================================= */ CR_API void_t qst_load_cfg ( __CR_OT__ sQCOM_conf* cfgs ) { sINIu* ini; ansi_t* str; /* 加载配置文件 */ TRY_FREE(cfgs->font_face); str = file_load_as_strA(QST_PATH_CONFIG WIN_ICONF); if (str == NULL) goto _load_defs; ini = ini_parseU(str); mem_free(str); if (ini == NULL) goto _load_defs; /* 读入配置参数 */ cfgs->color = ini_key_intx32U("qcom::color", 0xFFC0C0C0UL, ini); cfgs->bkcolor = ini_key_intx32U("qcom::bkcolor", 0xFF000000UL, ini); cfgs->font_size = ini_key_intxU("qcom::font_size", 12, ini); cfgs->font_face = ini_key_stringU("qcom::font_face", ini); ini_closeU(ini); return; _load_defs: cfgs->color = 0xFFC0C0C0UL; cfgs->bkcolor = 0xFF000000UL; cfgs->font_size = 12; cfgs->font_face = NULL; }
/* --------------------------------------- 文件单元释放回调 --------------------------------------- */ static void_t rar_free ( __CR_IN__ void_t* obj ) { sPAK_RAR_FILE* unit; unit = (sPAK_RAR_FILE*)obj; TRY_FREE(unit->base.find); mem_free(unit->base.name); }
/* --------------------------------------- 文件单元释放回调 --------------------------------------- */ static void_t xp3_free ( __CR_IN__ void_t* obj ) { sPAK_XP3_FILE* unit; unit = (sPAK_XP3_FILE*)obj; mem_free(unit->segm_lst); TRY_FREE(unit->base.find); mem_free(unit->base.name); }
/* --------------------------------------- 释放接口 --------------------------------------- */ static void_t iXMM_FMOD_release ( __CR_IN__ iXMMEDIA* that ) { iXMM_FMOD* real; real = (iXMM_FMOD*)that; FMOD_Channel_Stop(real->m_chn); FMOD_Sound_Release(real->m_snd); TRY_FREE(real->m_dat); mem_free(that); }
/* ======================================= 主程序 ======================================= */ int main (int argc, char *argv[]) { fbuf_t file; const ansi_t *root; /* 建立 CrHack 系统 */ if (!set_app_type(CR_APP_CUI)) return (QST_ERROR); /* 参数解析 [搜索根目录] */ if (argc < 1) { printf("filehash [directory]\n"); return (QST_ERROR); } /* 生成性能测试对象 */ s_profile = timer_new(); /* 生成输出文件 */ file_deleteA("__hash__.old"); file_renameA("__hash__.old", "__hash__.txt"); file = file_buf_openA("__hash__.txt", CR_FO_WO); if (file == NULL) { printf("can't create output file\n"); return (QST_ERROR); } /* 枚举所有文件 */ if (argc == 1) root = ""; else root = argv[1]; s_rdata = NULL; mem_info(&s_total, &s_avail); s_total = (s_total * 618) / 1000; file_searchA(root, TRUE, FALSE, FALSE, "*.*", hasher, file); /* 释放内存 */ file_buf_close(file); timer_del(s_profile); TRY_FREE(s_rdata); return (QST_OKAY); }
/* --------------------------------------- 打开 UDPv4 通讯接口 --------------------------------------- */ static bool_t qst_com_udpv4 ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { uint_t port; socket_t netw; /* 参数解析 <目标地址> <端口号> */ if (argc < 3) return (FALSE); port = str2intxA(argv[2]); if (port > 65535) return (FALSE); sQstComm* ctx = (sQstComm*)parm; /* 关闭当前接口并打开 UDPv4 连接 */ netw = client_udp_open(argv[1], (int16u)port); if (netw == NULL) return (FALSE); socket_set_timeout(netw, QCOM_SNDTOUT, QCOM_CUTDOWN); /* 设置工作参数 */ qst_com_close(parm, argc, argv); ctx->comm.obj.netw = netw; ctx->comm.send = qst_udpv4_send; /* 启动接收线程 */ ctx->comm.thrd = thread_new(0, qst_udpv4_main, parm, FALSE); if (ctx->comm.thrd == NULL) { socket_close(netw); return (FALSE); } TRY_FREE(ctx->comm.title); ctx->comm.title = str_fmtA(" - UDPv4 \"%s\", %u", argv[1], port); qst_update_title(ctx); return (TRUE); }
/* --------------------------------------- 设置通讯接收模式 --------------------------------------- */ static bool_t qst_com_rtype ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { static ansi_t* name = NULL; /* 参数解析 <接收模式/插件名称> [函数名称] */ if (argc < 2) return (FALSE); sQstComm* ctx = (sQstComm*)parm; CTextOper* opr = (CTextOper*)ctx->oper; _ENTER_COM_SINGLE_ if (str_cmpA(argv[1], "text") == 0) { ctx->comm.text = TRUE; ctx->comm.render = qst_txt_show; ctx->comm.rtype = "text"; } else if (str_cmpA(argv[1], "html") == 0) { ctx->comm.text = TRUE; ctx->comm.render = qst_htm_show; ctx->comm.rtype = "html"; } else if (str_cmpA(argv[1], "hex") == 0) { ctx->comm.text = FALSE; ctx->comm.render = qst_hex_show; ctx->comm.rtype = "hex"; } else if (str_cmpA(argv[1], "ansi") == 0) { qst_csi_clear(); ctx->comm.text = TRUE; ctx->comm.render = qst_csi_show; ctx->comm.rtype = "ansi"; } else { sbin_t sbin; plugin_render_t func; /* 使用外部插件 */ if (argc < 3) goto _failure; sbin = sbin_loadA(argv[1]); if (sbin == NULL) goto _failure; func = sbin_exportT(sbin, argv[2], plugin_render_t); if (func == NULL) { sbin_unload(sbin); goto _failure; } ctx->comm.text = FALSE; ctx->comm.render = func; TRY_FREE(name); name = str_fmtA("%s|%s", argv[1], argv[2]); ctx->comm.rtype = (name == NULL) ? "null" : name; } opr->clear(); _LEAVE_COM_SINGLE_ qst_update_title(ctx); return (TRUE); _failure: _LEAVE_COM_SINGLE_ return (FALSE); }
/* --------------------------------------- 设置通讯发送模式 --------------------------------------- */ static bool_t qst_com_stype ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { static ansi_t* name = NULL; /* 参数解析 <发送模式/插件名称> [函数名称] */ if (argc < 2) return (FALSE); sQstComm* ctx = (sQstComm*)parm; if (str_cmpA(argv[1], "text") == 0) { ctx->comm.tran = NULL; ctx->comm.stype = "text"; } else if (str_cmpA(argv[1], "hex") == 0) { ctx->comm.tran = qst_hex_tran; ctx->comm.stype = "hex"; } else if (str_cmpA(argv[1], "esc") == 0) { ctx->comm.tran = qst_esc_tran; ctx->comm.stype = "esc"; } else if (str_cmpA(argv[1], "dos") == 0) { ctx->comm.tran = qst_dos_tran; ctx->comm.stype = "dos"; } else if (str_cmpA(argv[1], "unix") == 0) { ctx->comm.tran = qst_unx_tran; ctx->comm.stype = "unix"; } else if (str_cmpA(argv[1], "mac") == 0) { ctx->comm.tran = qst_mac_tran; ctx->comm.stype = "mac"; } else { sbin_t sbin; plugin_tran_t func; /* 使用外部插件 */ if (argc < 3) return (FALSE); sbin = sbin_loadA(argv[1]); if (sbin == NULL) return (FALSE); func = sbin_exportT(sbin, argv[2], plugin_tran_t); if (func == NULL) { sbin_unload(sbin); return (FALSE); } ctx->comm.tran = func; TRY_FREE(name); name = str_fmtA("%s|%s", argv[1], argv[2]); ctx->comm.stype = (name == NULL) ? "null" : name; } qst_update_title(ctx); return (TRUE); }
/* --------------------------------------- 打开 RS232 通讯接口 --------------------------------------- */ static bool_t qst_com_rs232 ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { int32u baud; uint_t port, bits; uint_t stop, parity; /* --------------- */ const ansi_t* sstop; const ansi_t* sparity; /* 参数解析 <串口号> [波特率] [数据位] [校验位] [停止位] */ if (argc < 2) return (FALSE); bits = 8; baud = 115200UL; stop = CR_SIO_STOP10; parity = CR_SIO_NOP; sstop = "1"; sparity = "no"; port = str2intxA(argv[1]); if (argc > 2) { baud = str2intx32A(argv[2]); if (argc > 3) { bits = str2intxA(argv[3]); if (argc > 4) { sparity = argv[4]; if (str_cmpA(argv[4], "no") == 0) parity = CR_SIO_NOP; else if (str_cmpA(argv[4], "odd") == 0) parity = CR_SIO_ODD; else if (str_cmpA(argv[4], "even") == 0) parity = CR_SIO_EVEN; else if (str_cmpA(argv[4], "mark") == 0) parity = CR_SIO_MARK; else if (str_cmpA(argv[4], "space") == 0) parity = CR_SIO_SPCE; else sparity = "no"; if (argc > 5) { sstop = argv[5]; if (str_cmpA(argv[5], "1") == 0) stop = CR_SIO_STOP10; else if (str_cmpA(argv[5], "1.5") == 0) stop = CR_SIO_STOP15; else if (str_cmpA(argv[5], "2") == 0) stop = CR_SIO_STOP20; else sstop = "1"; } } } } sQstComm* ctx = (sQstComm*)parm; /* 关闭当前接口并打开串口 */ if (!sio_open(port)) return (FALSE); sio_setup(port, baud, bits, parity, stop); sio_set_buffer(port, 1024, 1024); sio_set_rd_timeout(port, 0, 0, QCOM_CUTDOWN); sio_set_wr_timeout(port, 0, QCOM_SNDTOUT); sio_clear_error(port); sio_flush(port, CR_SIO_FLU_RT); /* 设置工作参数 */ qst_com_close(parm, argc, argv); ctx->comm.obj.port = port; ctx->comm.send = qst_rs232_send; /* 启动接收线程 */ ctx->comm.thrd = thread_new(0, qst_rs232_main, parm, FALSE); if (ctx->comm.thrd == NULL) { sio_close(port); return (FALSE); } TRY_FREE(ctx->comm.title); ctx->comm.title = str_fmtA(" - COM%u, %u, %u, %s, %s", port, baud, bits, sparity, sstop); qst_update_title(ctx); return (TRUE); }
/* ======================================= 主程序 ======================================= */ int main (int argc, char *argv[]) { CR_NOUSE(argc); CR_NOUSE(argv); /* 建立 CrHack 系统 */ if (!set_app_type(CR_APP_CUI)) return (QST_ERROR); SetConsoleTitleA(WIN_TITLE); sint_t x1, y1; uint_t ww, hh; /* 初始化窗口 */ s_hcui = GetStdHandle(STD_OUTPUT_HANDLE); if (s_hcui == INVALID_HANDLE_VALUE) return (QST_ERROR); s_hwnd = GetConsoleWindow(); if (s_hwnd == NULL) return (QST_ERROR); misc_desk_init(WIN_ICONF, &x1, &y1, &ww, &hh, QSRV_DEF_WIDTH, QSRV_DEF_HEIGHT); misc_cui_setwin(s_hwnd, s_hcui, x1, y1, ww, hh); sINIu* ini; uint_t temp; ansi_t* text; int16u port = QST_DEF_PORT; ansi_t* addr = QST_DEF_ADDR; uint_t count = QST_DEF_CLIENT; /* 读取参数 */ text = file_load_as_strA(QST_CFG_STARTUP); if (text != NULL) { ini = ini_parseU(text); mem_free(text); text = NULL; if (ini != NULL) { text = ini_key_stringU("serv::bind", ini); if (text != NULL) addr = text; temp = ini_key_intxU("serv::port", QST_DEF_PORT, ini); if (temp > 1024 && temp < 32768) port = (int16u)temp; temp = ini_key_intxU("serv::count", QST_DEF_CLIENT, ini); if (temp > 0 && temp <= QST_MAX_CLIENT) count = temp; ini_closeU(ini); } } socket_t serv; sQstWork* work; /* 建立工作单元组 */ work = qst_wrk_create(count); if (work == NULL) return (QST_ERROR); /* 初始化网络 */ if (!socket_init()) return (QST_ERROR); serv = server_tcp_open(addr, port); TRY_FREE(text); if (serv == NULL) return (QST_ERROR); /* 初始化锁 */ mtlock_init(&s_qst_lck_shw); mtlock_init(&s_qst_lck_wrk); int16u logo_color; /* 建立颜色值 */ logo_color = cui_make_attr(0, CR_CUI_TEXT_LIGHT | CR_CUI_TEXT_GREEN | CR_CUI_TEXT_RED | CR_CUI_TEXT_BLUE); s_qst_clr_cin = cui_make_attr(0, CR_CUI_TEXT_LIGHT | CR_CUI_TEXT_GREEN | CR_CUI_TEXT_RED); s_qst_clr_say = cui_make_attr(0, CR_CUI_TEXT_LIGHT | CR_CUI_TEXT_GREEN); s_qst_clr_out = cui_make_attr(0, CR_CUI_TEXT_LIGHT | CR_CUI_TEXT_RED); /* 工作循环 */ cui_set_color(logo_color); printf("######################################\n"); printf("## QUESTLAB BROADCAST SERVER ##\n"); printf("######################################\n"); while (!s_quit) { ansi_t* ptr; bool_t okay; ansi_t* name; socket_t netw; /* 接受一个客户端 */ netw = server_tcp_accept(serv); if (netw == NULL) continue; /* 接收客户端名称 */ socket_set_timeout(netw, -1, QST_TCP_TOUT); name = netw_cmd_recv(netw); if (name == NULL) { socket_close(netw); continue; } /* 客户端名称过滤 */ if (str_lenA(name) > QST_MAX_NAME) { netw_ack_send(netw, FALSE); netw_cli_close(netw); mem_free(name); continue; } ptr = name; okay = TRUE; while (*ptr != NIL) { if (is_cntrlA(*ptr++)) { okay = FALSE; break; } } if (!okay) { netw_ack_send(netw, FALSE); netw_cli_close(netw); mem_free(name); continue; } /* 启动一个工作单元 */ if (!qst_wrk_wakeup(work, name, netw, qst_srv_main)) { netw_cli_close(netw); mem_free(name); continue; } } return (QST_OKAY); }
/* ======================================= TGL IPAC 文件读取 ======================================= */ CR_API sFMT_PRT* load_tgl_ipac ( __CR_IO__ iDATIN* datin, __CR_IN__ const sLOADER* param ) { int16u idx; int16u cnt; int32u offs; int32u size; sFMT_PRT* rett; sIPAC_HDR head; iPAK_IPAC* port; sPAK_FILE* list; ansi_t str[17]; /* 必须使用自己私有的读取接口 */ datin = create_file_inX(param); if (datin == NULL) return (NULL); /* 读取 & 检查头部 */ if (!(CR_VCALL(datin)->geType(datin, &head, sIPAC_HDR))) goto _failure1; if (head.magic != mk_tag4("IPAC")) goto _failure1; /* 分配子文件属性表 */ cnt = WORD_LE(head.count); if (cnt != 0) { list = mem_talloc(cnt, sPAK_FILE); if (list == NULL) goto _failure1; str[16] = CR_AC(NIL); mem_tzero(list, cnt, sPAK_FILE); } else { list = NULL; /* 支持空的包文件 */ } /* 加载文件信息表 */ for (idx = 0; idx < cnt; idx++) { /* 读取文件名不保证\0结尾 */ if (CR_VCALL(datin)->read(datin, str, 16) != 16) goto _failure2; /* 文件的包内偏移和大小 */ if (!CR_VCALL(datin)->getd_le(datin, &offs)) goto _failure2; if (!CR_VCALL(datin)->getd_le(datin, &size)) goto _failure2; /* 文件名统一使用 UTF-8 编码 */ list[idx].name = local_to_utf8(param->page, str); if (list[idx].name == NULL) goto _failure2; /* 设置公用文件属性 */ list[idx].skip = sizeof(sPAK_FILE); list[idx].attr = 0; list[idx].offs = offs; list[idx].pack = size; list[idx].size = size; list[idx].memo = "Store"; } /* 生成读包接口对象 */ port = struct_new(iPAK_IPAC); if (port == NULL) goto _failure2; port->m_cnt = cnt; port->m_file = datin; port->pack.__filelst__ = list; port->pack.__vptr__ = &s_pack_vtbl; if (!pack_init_list((iPACKAGE*)port, TRUE)) { mem_free(port); goto _failure2; } /* 返回读取的文件数据 */ rett = struct_new(sFMT_PRT); if (rett == NULL) { iPAK_IPAC_release((iPACKAGE*)port); return (NULL); } rett->type = CR_FMTZ_PRT; rett->port = (iPORT*)port; rett->more = "iPACKAGE"; rett->infor = "TGL IPAC Archive (IPAC)"; return (rett); _failure2: if (list != NULL) { for (cnt = 0; cnt < idx; cnt++) { TRY_FREE(list[cnt].find); mem_free(list[cnt].name); } mem_free(list); } _failure1: CR_VCALL(datin)->release(datin); return (NULL); }
/* ======================================= RAR 文件读取 ======================================= */ CR_API sFMT_PRT* load_rar ( __CR_IO__ iDATIN* datin, __CR_IN__ const sLOADER* param ) { HANDLE rar; sARRAY list; int32u attr; sint_t retc; leng_t fpos; iPAK_RAR* port; sFMT_PRT* rett; sPAK_RAR_FILE temp; RARHeaderDataEx info; RAROpenArchiveDataEx open; /* 只支持磁盘文件 */ if (param->type != CR_LDR_ANSI && param->type != CR_LDR_WIDE) return (NULL); /* 列表模式打开 RAR 文件 */ struct_zero(&open, RAROpenArchiveDataEx); if (param->type == CR_LDR_ANSI) open.ArcName = (ansi_t*)param->name.ansi; else open.ArcNameW = (wide_t*)param->name.wide; open.OpenMode = RAR_OM_LIST; rar = RAROpenArchiveEx(&open); if (rar == NULL) return (NULL); if (param->aprm != NULL && *(byte_t*)param->aprm != 0x00) { RARSetPassword(rar, (ansi_t*)param->aprm); attr = PAK_FILE_ENC; } else { attr = 0; } /* 开始逐个文件读取信息并定位 */ array_initT(&list, sPAK_RAR_FILE); list.free = rar_free; struct_zero(&info, RARHeaderDataEx); for (fpos = 0; ; fpos++) { /* 读取一个文件记录头 */ retc = RARReadHeaderEx(rar, &info); if (retc == ERAR_END_ARCHIVE) break; if (retc != ERAR_SUCCESS) goto _failure1; /* 目录文件不加入列表 */ if (info.Flags & RHDF_DIRECTORY) { retc = RARProcessFile(rar, RAR_SKIP, NULL, NULL); if (retc != ERAR_SUCCESS) goto _failure1; continue; } /* 文件名统一使用 UTF-8 编码 */ struct_zero(&temp, sPAK_RAR_FILE); temp.base.name = local_to_utf8(param->page, info.FileName); if (temp.base.name == NULL) goto _failure1; /* 设置公用文件属性 (偏移没有实际用处) */ temp.base.skip = sizeof(sPAK_RAR_FILE); temp.base.attr = attr; temp.base.offs = 0; temp.base.pack = mk_size(info.PackSizeHigh, info.PackSize); temp.base.size = mk_size(info.UnpSizeHigh, info.UnpSize); if (info.Method != 0x30) temp.base.attr |= PAK_FILE_CMP; if (info.Flags & RHDF_ENCRYPTED) temp.base.attr |= PAK_FILE_ENC; else temp.base.attr &= ~PAK_FILE_ENC; switch (info.Method) { case 0x30: temp.base.memo = "Storing"; break; case 0x31: temp.base.memo = "Fastest compression"; break; case 0x32: temp.base.memo = "Fast compression"; break; case 0x33: temp.base.memo = "Normal compression"; break; case 0x34: temp.base.memo = "Good compression"; break; case 0x35: temp.base.memo = "Best compression"; break; default: temp.base.memo = "Unknown compression"; break; } /* 设置私有文件属性 */ temp.id = fpos; temp.crc32 = (int32u)(info.FileCRC); temp.fattr = (int32u)(info.FileAttr); temp.ftime = (int16u)(info.FileTime & 0xFFFF); temp.fdate = (int16u)(info.FileTime >> 16); temp.htype = (int32u)(info.HashType); mem_cpy(temp.hash, info.Hash, sizeof(temp.hash)); /* 文件信息压入列表 */ if (array_push_growT(&list, sPAK_RAR_FILE, &temp) == NULL) { mem_free(temp.base.name); goto _failure1; } /* 跳过当前已读文件 */ retc = RARProcessFile(rar, RAR_SKIP, NULL, NULL); if (retc != ERAR_SUCCESS && retc != ERAR_BAD_DATA) goto _failure1; } /* 固定一下列表大小 */ if (!array_no_growT(&list, sPAK_RAR_FILE)) goto _failure1; /* 生成读包接口对象 */ port = struct_new(iPAK_RAR); if (port == NULL) goto _failure1; /* 保存需要用到的参数 */ port->m_temp = NULL; if (attr == 0) { port->m_pass = NULL; } else { port->m_pass = str_dupA((ansi_t*)param->aprm); if (port->m_pass == NULL) goto _failure2; } if (param->type == CR_LDR_ANSI) { port->m_wide = NULL; port->m_ansi = str_dupA(param->name.ansi); if (port->m_ansi == NULL) goto _failure3; } else { port->m_ansi = NULL; port->m_wide = str_dupW(param->name.wide); if (port->m_wide == NULL) goto _failure3; } port->m_rar = NULL; port->m_cur = (leng_t)-1; port->m_cnt = array_get_sizeT(&list, sPAK_RAR_FILE); port->pack.__filelst__ = array_get_dataT(&list, sPAK_FILE); port->pack.__vptr__ = &s_pack_vtbl; if (!pack_init_list((iPACKAGE*)port, TRUE)) goto _failure4; RARCloseArchive(rar); /* 返回读取的文件数据 */ rett = struct_new(sFMT_PRT); if (rett == NULL) { iPAK_RAR_release((iPACKAGE*)port); return (NULL); } CR_NOUSE(datin); rett->type = CR_FMTZ_PRT; rett->port = (iPORT*)port; rett->more = "iPACKAGE"; rett->infor = "Roshal ARchive (RAR)"; return (rett); _failure4: TRY_FREE(port->m_ansi); TRY_FREE(port->m_wide); _failure3: TRY_FREE(port->m_pass); _failure2: mem_free(port); _failure1: array_freeT(&list, sPAK_RAR_FILE); RARCloseArchive(rar); return (NULL); }
/* ======================================= FMODEx 文件读取 ======================================= */ CR_API sFMT_PRT* load_fmodex ( __CR_IO__ iDATIN* datin, __CR_IN__ const sLOADER* param ) { uint_t size; void_t* data; ansi_t* path; sFMT_PRT* rett; FMOD_MODE mode; iXMM_FMOD* port; FMOD_SOUND* sound; FMOD_RESULT result; FMOD_CHANNEL* channel; FMOD_CREATESOUNDEXINFO ex_info; /* 必须先初始化 */ if (s_fmodex == NULL) return (NULL); mode = FMOD_LOOP_OFF | FMOD_2D | FMOD_HARDWARE | FMOD_ACCURATETIME; /* 不支持文件区段功能 */ switch (param->type) { case CR_LDR_ANSI: data = NULL; result = FMOD_System_CreateStream(s_fmodex, param->name.ansi, mode, NULL, &sound); break; case CR_LDR_WIDE: data = NULL; path = utf16_to_local(CR_LOCAL, param->name.wide); if (path == NULL) return (NULL); result = FMOD_System_CreateStream(s_fmodex, path, mode, NULL, &sound); mem_free(path); break; case CR_LDR_BUFF: if (cut_size(&size, param->buff.size)) return (NULL); data = mem_dup(param->buff.data, param->buff.size); if (data == NULL) return (NULL); path = (ansi_t*)data; mode |= FMOD_OPENMEMORY; mem_zero(&ex_info, sizeof(ex_info)); ex_info.cbsize = sizeof(ex_info); ex_info.length = size; result = FMOD_System_CreateStream(s_fmodex, path, mode, &ex_info, &sound); break; default: return (NULL); } /* 无法支持的格式 */ if (result != FMOD_OK) goto _failure1; /* 生成播放通道对象 */ result = FMOD_System_PlaySound(s_fmodex, FMOD_CHANNEL_FREE, sound, TRUE, &channel); if (result != FMOD_OK) goto _failure2; /* 生成媒体播放接口对象 */ port = struct_new(iXMM_FMOD); if (port == NULL) goto _failure3; struct_zero(port, iXMM_FMOD); port->m_dat = data; port->m_snd = sound; port->m_chn = channel; if (!fmodex_info(port)) { iXMM_FMOD_release((iXMMEDIA*)port); return (NULL); } port->xmms.__volume__ = 100; port->xmms.__vptr__ = &s_xmms_vtbl; /* 返回读取的文件数据 */ rett = struct_new(sFMT_PRT); if (rett == NULL) { iXMM_FMOD_release((iXMMEDIA*)port); return (NULL); } CR_NOUSE(datin); rett->type = CR_FMTZ_PRT; rett->port = (iPORT*)port; rett->more = "iXMMEDIA"; rett->infor = port->m_inf; return (rett); _failure3: FMOD_Channel_Stop(channel); _failure2: FMOD_Sound_Release(sound); _failure1: TRY_FREE(data); return (NULL); }