而demo這個也是本魔認為最麻煩的一個
這邊有用到蠻複雜的結構
以及demo需要把之前好幾回的東西整合起來思考 ((因為它有init
總之來看看吧~
demo.h
#ifndef __DEMO_H #define __DEMO_H #include "defines.h" #define CMD_MAXNAMELEN (256) typedef struct _FRM_NODE //frame節點 { int frmno; //編號 unsigned long frm[32]; //內容 32個PWM struct _FRM_NODE *next; //下一個節點 }FRM_NODE; typedef struct _ACT_NODE //動作的節點 { int type; //型態 int time; //時間 int actno; //編號 unsigned long *frm; union{ //union型別 選一個用 int frmno; //編號 char *filename; //檔案名稱 }data; struct _ACT_NODE *next; //下一個節點 }ACT_NODE; //-- values for ACT_t.type #define ACT_START (0) #define ACT_PAUSE (1) #define ACT_PLAYFRAMENO (2) #define ACT_PLAYSND (3) typedef struct _CMD_NODE //指令的節點 { int command; //指令編號 int actno; //動作的編號 char name[CMD_MAXNAMELEN+1]; //指令名稱 ACT_NODE *act; //對應到的動作結點 struct _CMD_NODE *next; //下一個節點 }CMD_NODE; typedef struct _CH_t //channel的節點 { int pin; //腳位編號 int mode_idx; //模式 int offset; //偏移值 }CH_t; typedef struct { //主要架構 int rbidx; int initact; ACT_NODE *initactnode; int initfrm; int initfrm_mode; unsigned long usedChannels; unsigned long *inithome; CH_t channel[32]; int actidx; int actsize; ACT_NODE *actpool; ACT_NODE **acttable; int frmidx; int frmsize; FRM_NODE *frmpool; FRM_NODE **frmtable; int cmdidx; int cmdsize; CMD_NODE *cmdpool; CMD_NODE **cmdtable; // int SND_maxNum; //unused at the moment } DEF_t; //-- value for initfrm_mode #define INIT_FRM_FALSE (0) #define INIT_FRM_TRUE (1) #ifdef __cplusplus extern "C" { #endif CMD_NODE *tool_FindCMDNode(CMD_NODE **table, int command, int size); ACT_NODE *tool_FindACTNode(ACT_NODE **table, int actno, int size); bool tool_InitCapture(CH_t *channel, unsigned long usedch, int mode_idx); bool tool_InitDemo(DEF_t *def, char *dirname); bool tool_InitReplay(DEF_t *def, char *filename, int replaytime, int mode_idx, int actno, unsigned long usedchannels); #ifdef __cplusplus } #endif #endif
demo.cpp
#include <math.h> #include <stdlib.h> #include "demo.h" #include "parse.h" #include "errcode.h" #include "fileio.h" static int prime(int n); static int HashFun(int n, int base); static ACT_NODE *SearchACT(ACT_NODE *node, int actno); static CMD_NODE *SearchCMD(CMD_NODE *node, int cmd); static FRM_NODE *SearchFRM(FRM_NODE *node, int frmno); static int GetTotalACT(ACT_NODE *pool, int idx); static int InsertACT(ACT_NODE ***table, ACT_NODE *pool, int total, int size); static int InsertCMD(CMD_NODE ***table, CMD_NODE *pool, int total, int size); static int InsertFRM(FRM_NODE ***table, FRM_NODE *pool, int total, int size); static ACT_NODE *map_FindACTNode(ACT_NODE **table, int actno, int size); static CMD_NODE *map_FindCMDNode(CMD_NODE **table, int command, int size); static FRM_NODE *map_FindFRMNode(FRM_NODE **table, int frmno, int size); static int map_MappingACT(FRM_NODE **table, ACT_NODE *actpool, int actidx, int size); static int map_MappingCMD(ACT_NODE **table, CMD_NODE *cmdpool, int cmdidx, int size); static int map_MappingDEF(DEF_t *def); static void SetFrame(FRM_NODE *pool, CH_t *ch, int idx); static int FRMToACT(DEF_t *def, char *filename, int actno, int time); /* ================== hash function ==================*/ static int prime(int n) //尋找比n大 且最接近n的質數 { int i, j, size, max; int *array; max = (int)sqrt((double)n) + 1; size = max * max; array = (int *)malloc(sizeof(int) * size); for(i = 0; i < size; i++) array[i] = 0; for(i = 2; i < max; i++){ if(array[i] == 0){ for(j = 2*i; j < size; j += i) array[j] = 1; } } for(i = n; i < size; i++){ if(array[i] == 0) break; } free(array); return i; } static int HashFun(int n, int base) //雜湊 取base次方 再mod base { return (n ^ base) % base; } /* ================== general function ==================*/ static ACT_NODE *SearchACT(ACT_NODE *node, int actno) //尋找ACT_NODE內編號actno的節點 { while(node != NULL){ if(node->actno == actno) break; node = node->next; } return node; } static CMD_NODE *SearchCMD(CMD_NODE *node, int cmd) //尋找CMD_NODE內編號cmd的節點 { while(node != NULL){ if(node->command == cmd) break; node = node->next; } return node; } /* ================== insert function ==================*/ static FRM_NODE *SearchFRM(FRM_NODE *node, int frmno) //尋找FRM_NODE內編號frmno的節點 { while(node != NULL){ if(node->frmno == frmno) break;; node = node->next; } return node; } static int GetTotalACT(ACT_NODE *pool, int idx) //得到action的總個數 { int i, total; total = 0; for(i = 0; i < idx - 1; i++){ if(pool[i].type == ACT_START) total += 1; } return total; } static int InsertACT(ACT_NODE ***table, ACT_NODE *pool, int total, int size) //建造ACT的表格 { int i, idx; if(size == 0) return SUCCESS; *table = (ACT_NODE **)malloc(sizeof(ACT_NODE *) * size); if(*table == NULL) return MEMORY_ERROR; for(i = 0; i < size; i++) (*table)[i] = NULL; for(i = 0; i < total - 1; i++){ if(pool[i].type == ACT_START){ idx = HashFun(pool[i].actno, size); if(SearchACT((*table)[idx], pool[i].actno) != NULL){ errcode_SetErrACT(pool[i].actno); return MAP_REPEAT_ACTNO; } pool[i].next = (*table)[idx]; (*table)[idx] = &pool[i]; } } return SUCCESS; } static int InsertCMD(CMD_NODE ***table, CMD_NODE *pool, int total, int size) //建造CMD的表格 { int i, idx; if(size == 0) return SUCCESS; *table = (CMD_NODE **)malloc(sizeof(CMD_NODE *) * size); if(*table == NULL) return MEMORY_ERROR; for(i = 0; i < size; i++) (*table)[i] = NULL; for(i = 0; i < total; i++){ idx = HashFun(pool[i].command, size); if(SearchCMD((*table)[idx], pool[i].command) != NULL){ errcode_SetErrCMD(pool[i].command); return MAP_REPEAT_CMD; } pool[i].next = (*table)[idx]; (*table)[idx] = &pool[i]; } return SUCCESS; } static int InsertFRM(FRM_NODE ***table, FRM_NODE *pool, int total, int size) //建造FRM的表格 { int i, idx; if(size == 0) return SUCCESS; *table = (FRM_NODE **)malloc(sizeof(FRM_NODE *) * size); if(*table == NULL) return MEMORY_ERROR; for(i = 0; i < size; i++) (*table)[i] = NULL; for(i = 0; i < total; i++){ idx = HashFun(pool[i].frmno, size); if(SearchFRM((*table)[idx], pool[i].frmno) != NULL){ errcode_SetErrFRM(pool[i].frmno); return MAP_REPEAT_FRMNO; } pool[i].next = (*table)[idx]; (*table)[idx] = &pool[i]; } return SUCCESS; } static int InsertTable(DEF_t *def) //計算table大小 以及創建table { int status; def->actsize = prime((int)(GetTotalACT(def->actpool, (def->actidx)) * 1.5)); def->cmdsize = prime((int)(def->cmdidx * 1.5)); def->frmsize = prime((int)(def->frmidx * 1.5)); status = InsertACT(&def->acttable, def->actpool, def->actidx, def->actsize); if(status == SUCCESS) status = InsertCMD(&def->cmdtable, def->cmdpool, def->cmdidx, def->cmdsize); if(status == SUCCESS) status = InsertFRM(&def->frmtable, def->frmpool, def->frmidx, def->frmsize); return status; } /* ================== function for mapping ==================*/ static ACT_NODE *map_FindACTNode(ACT_NODE **table, int actno, int size) //回傳ACT table內的actno 若已有使用則回傳下一個 { ACT_NODE *p; int idx; if(table == NULL) return NULL; idx = HashFun(actno, size); p = SearchACT(table[idx], actno); if(p == NULL) return p; return p + 1; } static CMD_NODE *map_FindCMDNode(CMD_NODE **table, int command, int size) //回傳CMD table內的command { int idx; if(table == NULL) return NULL; idx = HashFun(command, size); return SearchCMD(table[idx], command); } static FRM_NODE *map_FindFRMNode(FRM_NODE **table, int frmno, int size) //回傳FRM table內的frmno { int idx; if(table == NULL) return NULL; idx = HashFun(frmno, size); return SearchFRM(table[idx], frmno); } static int map_MappingACT(FRM_NODE **table, ACT_NODE *actpool, int actidx, int size) //mapping FRM編號 { int i; FRM_NODE *p; for(i = 0; i < actidx; i++){ if(actpool[i].type == ACT_PLAYFRAMENO){ p = map_FindFRMNode(table, actpool[i].data.frmno, size); if(p == NULL){ errcode_SetErrFRM(actpool[i].data.frmno); return MAP_NOFINDFRM; } actpool[i].frm = p->frm; } } return SUCCESS; } static int map_MappingCMD(ACT_NODE **table, CMD_NODE *cmdpool, int cmdidx, int size) //mapping act編號 { int i; ACT_NODE *p; for(i = 0; i < cmdidx; i++){ p = map_FindACTNode(table, cmdpool[i].actno, size); if(p == NULL){ errcode_SetErrACT(cmdpool[i].actno); return MAP_NOFINDACT; } cmdpool[i].act = p; } return SUCCESS; } static int map_MappingDEF(DEF_t *def) //mapping def的所有NODE { FRM_NODE *p; int status; if(def->initfrm != -1){ p = map_FindFRMNode(def->frmtable, def->initfrm, def->frmsize); if(p == NULL){ errcode_SetErrFRM(def->initfrm); return MAP_NOFINDINITFRM; } def->inithome = p->frm; } if(def->initact != -1){ def->initactnode = map_FindACTNode(def->acttable, def->initact, def->actsize); if(def->initactnode == NULL){ errcode_SetErrACT(def->initact); return MAP_NOFINEINITACT; } } status = map_MappingACT(def->frmtable, def->actpool, def->actidx, def->frmsize); if(status == SUCCESS) status = map_MappingCMD(def->acttable, def->cmdpool, def->cmdidx, def->actsize); return status; } /* ================== function for offset ==================*/ static void SetFrame(FRM_NODE *pool, CH_t *ch, int idx) //將偏移植算入frame { int i, j; unsigned long temp[32]; for(i = 0; i < idx; i++){ for(j = 0; j < 32; j++) temp[j] = pool[i].frm[j]; for(j = 0; j < 32; j++){ if(ch[j].pin != -1) pool[i].frm[ch[j].pin] = temp[j] + ch[j].offset; } } } /* ================== function for replay frame ==================*/ int FRMToACT(DEF_t *def, char *filename, int actno, int time) //設定一些預設值 replay mode用 { FILEIO *fp; INI_ITEM_t item; ACT_NODE *act; int status = SUCCESS; fp = ini_FileOpen(filename); if(fp == NULL) return FRM_OFFSET + OPEN_FILE_FAIL; act = &def->actpool[def->actidx]; act->type = ACT_START; act->actno = actno; status = tool_InsertACTPool(&def->actpool, &def->actidx); while ((status == SUCCESS) && (ini_ReadNextItem(fp, &item) != INI_FILEEND)) { act = &def->actpool[def->actidx]; switch(item.type) { case INI_GROUPTITLE: act->type = ACT_PLAYFRAMENO; act->time = time; status = tool_GetGroupFRM(item.itemname, &act->data.frmno); if(status == SUCCESS) status = tool_InsertACTPool(&def->actpool, &def->actidx); break; } } ini_FileClose(fp); act = &def->actpool[def->actidx]; act->type = ACT_START; act->actno = -1; status = tool_InsertACTPool(&def->actpool, &def->actidx); return status; } /* ================== tool function ==================*/ CMD_NODE *tool_FindCMDNode(CMD_NODE **table, int command, int size) { return map_FindCMDNode(table, command, size); } ACT_NODE *tool_FindACTNode(ACT_NODE **table, int actno, int size) { return map_FindACTNode(table, actno, size); } bool tool_InitCapture(CH_t *channel, unsigned long usedch, int mode_idx) //init Capture mode { int i; for(i = 0; i < 32; i++) channel[i].pin = -1; for(i = 0; i < 32; i++){ if((usedch & (1L << i)) != 0){ channel[i].pin = i; channel[i].offset = 0; channel[i].mode_idx = mode_idx; } } return true; } bool tool_InitReplay(DEF_t *def, char *filename, int replaytime, int mode_idx, int actno, unsigned long usedchannels) //init replay mode { int i; int status; status = tool_InitDEF(def); for(i = 0; i < 32; i++){ if((usedchannels & (1L << i)) != 0){ def->channel[i].pin = i; def->channel[i].offset = 0; def->channel[i].mode_idx = mode_idx; } } if(status == SUCCESS) status = tool_ParseFile_FRM(def, filename); if(status == SUCCESS) status = FRMToACT(def, filename, actno, replaytime); if(status == SUCCESS) status = InsertTable(def); if(status == SUCCESS) status = map_MappingACT(def->frmtable, def->actpool, def->actidx, def->frmsize); if(status == SUCCESS) return true; errcode_ShowErr(status); return false; } bool tool_InitDemo(DEF_t *def, char *dirname) //init demo mode { int status; status = tool_InitDEF(def); if(status == SUCCESS) status = tool_ReadFile(dirname, def); SetFrame(def->frmpool, def->channel, def->frmidx); if(status == SUCCESS) status = InsertTable(def); if(status == SUCCESS) status = map_MappingDEF(def); if(status == SUCCESS) return true; errcode_ShowErr(status); return false; }
基本上這樣子RoBoRC就告一段落了
相信學到這邊大家應該也都對RoBoRC有相當的了解!
以上!
0 留言:
張貼留言