Geek@Paris
  • palm编程的浮点运算太复杂了,贴一些资料在这里

    2007-11-03
    the following code is written by Fred Bayer, the author of LispMe and
    modified by Warren Young, the author of f/Calc.(tbird. comment)
    u can modify it as u need, hope it helps.

    #include <PalmOS.h>
    #include <PalmTypes.h>
    #include <PalmCompatibility.h>
    #include <FloatMgr.h>
    #include <FeatureMgr.h>

    #define _DONT_USE_FP_TRAPS_ 1
    #include <CoreTraps.h>
    #include <StringMgr.h>

    void SysTrapFlpLToF(FlpDouble *, Long) SYS_TRAP(sysTrapFlpEmDispatch);

    /* convert a long to double */
    double longToDouble(long l) {
    FlpCompDouble fcd;
    asm("moveq.l %0,%%d2": : "i"(sysFloatEm_d_itod):"d2");
    SysTrapFlpLToF(&fcd.fd, l);
    return fcd.d;
    }

    Long SysTrapFlpFToL(FlpDouble) SYS_TRAP(sysTrapFlpEmDispatch);

    /* convert a double to long */
    long doubleToLong(double d) {
    FlpCompDouble fcd;
    fcd.d = d;
    asm("moveq.l %0,%%d2": : "i"(sysFloatEm_d_dtoi):"d2");
    return SysTrapFlpFToL(fcd.fd);
    }

    void SysTrapBinOp(FlpDouble *, FlpDouble, FlpDouble) SYS_TRAP(sysTrapFlpEmDispatch);

    /* the same interface is used for all basic arithmetic operations */
    double genericDoubleOp(double a, double b, long opcode) {
    FlpCompDouble fcda, fcdb, fcds;
    fcda.d = a;
    fcdb.d = b;
    asm("move.l %0,%%d2": : "g"(opcode):"d2");
    SysTrapBinOp(&fcds.fd, fcda.fd, fcdb.fd);
    return fcds.d;
    }

    /* basic arithmetic operations */
    #define addDouble(a,b) genericDoubleOp(a,b,sysFloatEm_d_add)
    #define subDouble(a,b) genericDoubleOp(a,b,sysFloatEm_d_sub)
    #define mulDouble(a,b) genericDoubleOp(a,b,sysFloatEm_d_mul)
    #define divDouble(a,b) genericDoubleOp(a,b,sysFloatEm_d_div)

    SDWord SysTrapCompare(FlpDouble, FlpDouble) SYS_TRAP(sysTrapFlpEmDispatch);

    /* compare 2 doubles for equality */
    Boolean eqDouble(double a, double b) {
    FlpCompDouble fcda, fcdb;
    fcda.d = a;
    fcdb.d = b;
    asm("moveq.l %0,%%d2": : "i"(sysFloatEm_d_feq):"d2");
    return SysTrapCompare(fcda.fd, fcdb.fd);
    }

    /* compare 2 doubles for less or equal */
    Boolean leqDouble(double a, double b) {
    FlpCompDouble fcda, fcdb;
    fcda.d = a;
    fcdb.d = b;
    asm("moveq.l %0,%%d2": : "i"(sysFloatEm_d_fle):"d2");
    return SysTrapCompare(fcda.fd, fcdb.fd);
    }

    /**********************************************************************/
    /* Formatting parameters */
    /**********************************************************************/
    #define NUM_DIGITS 15
    #define MIN_FLOAT 4
    #define ROUND_FACTOR 1.0000000000000005 /* NUM_DIGITS zeros */

    /**********************************************************************/
    /* FP conversion constants */
    /**********************************************************************/
    static double pow1[] = {
    1e256, 1e128, 1e064,
    1e032, 1e016, 1e008,
    1e004, 1e002, 1e001
    };

    static double pow2[] = {
    1e-256, 1e-128, 1e-064,
    1e-032, 1e-016, 1e-008,
    1e-004, 1e-002, 1e-001
    };

    void printDouble(double x, char *s) {
    FlpCompDouble fcd;
    short e, e1, i;
    double *pd, *pd1;
    char sign = ”;
    short dec = 0;

    /*——————————————————————*/
    /* Round to desired precision */
    /* (this doesn’t always provide a correct last digit!) */
    /*——————————————————————*/
    x = mulDouble(x, ROUND_FACTOR);

    /*——————————————————————*/
    /* check for NAN, +INF, -INF, 0 */
    /*——————————————————————*/
    fcd.d = x;
    if ((fcd.ul[0] & 0x7ff00000) == 0x7ff00000)
    if (fcd.fdb.manH == 0 && fcd.fdb.manL == 0)
    if (fcd.fdb.sign)
    StrCopy(s, "[-inf]");
    else
    StrCopy(s, "[inf]");
    else
    StrCopy(s, "[nan]");
    else if (FlpIsZero(fcd))
    StrCopy(s, "0");
    else {
    /*—————————————————————-*/
    /* Make positive and store sign */
    /*—————————————————————-*/
    if (FlpGetSign(fcd)) {
    *s++ = ‘-‘;
    FlpSetPositive(fcd);
    }

    if ((unsigned) fcd.fdb.exp < 0x3ff) { /* meaning x < 1.0 */
    /*————————————————————–*/
    /* Build negative exponent */
    /*————————————————————–*/
    for (e = 1, e1 = 256, pd = pow1, pd1 = pow2; e1;
    e1 >>= 1, ++pd, ++pd1)
    if (!leqDouble(*pd1, fcd.d)) {
    e += e1;
    fcd.d = mulDouble(fcd.d, *pd);
    }
    fcd.d = mulDouble(fcd.d, 10.0);

    /*————————————————————–*/
    /* Only print big exponents */
    /*————————————————————–*/
    if (e <= MIN_FLOAT) {
    *s++ = ‘0’;
    *s++ = ‘.’;
    dec = -1;
    while (–e)
    *s++ = ‘0’;
    }
    else
    sign = ‘-‘;
    }
    else {
    /*————————————————————–*/
    /* Build positive exponent */
    /*————————————————————–*/
    for (e = 0, e1 = 256, pd = pow1, pd1 = pow2; e1;
    e1 >>= 1, ++pd, ++pd1)
    if (leqDouble(*pd, fcd.d)) {
    e += e1;
    fcd.d = mulDouble(fcd.d, *pd1);
    }
    if (e < NUM_DIGITS)
    dec = e;
    else
    sign = ‘+’;
    }

    /*—————————————————————-*/
    /* Extract decimal digits of mantissa */
    /*—————————————————————-*/
    for (i = 0; i < NUM_DIGITS; ++i, –dec) {
    Long d = doubleToLong(fcd.d);
    *s++ = d + ‘0’;
    if (!dec)
    *s++ = ‘.’;
    fcd.d = subDouble(fcd.d, longToDouble(d));
    fcd.d = mulDouble(fcd.d, 10.0);
    }

    /*—————————————————————-*/
    /* Remove trailing zeros and decimal point */
    /*—————————————————————-*/
    while (s[-1] == ‘0’)
    *–s = ”;
    if (s[-1] == ‘.’)
    *–s = ”;

    /*—————————————————————-*/
    /* Append exponent */
    /*—————————————————————-*/
    if (sign) {
    *s++ = ‘e’;
    *s++ = sign;
    StrIToA(s, e);
    }
    else
    *s = ”;
    }
    }

    /****************************************************************************
    The end of the PrintDouble section.
    ****************************************************************************/

    /*
    * This will cut the decimals. No roundings.
    */

    double CutDecimals(double d) {
    long l;

    l = (long) (d * 1000.0);
    return (double) l / 1000.0;
    }

    /*
    * Returns pointer to the object by pointer ID from the given form.
    */
    static void* GetObjectPtr(FormPtr formP, UInt16 objectID)
    {
    FormPtr frmP;

    if (formP != NULL) {
    frmP = formP;
    }
    else {
    frmP = FrmGetActiveForm();
    }

    return FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID)
    );
    }

    // Code is in the public domain, per this snippet from an email from David Bray <dbray@twcny.rr.com>:
    // Str to double begin.
    // This code is here because the internal function has limitations.
    // Check it yourself at Bray’s page

    #if defined(USELIBGLUE)
    #include <Libraries/PalmOSGlue/TxtGlue.h>
    #define PalmIsDigit TxtGlueCharIsDigit
    #else
    #define PalmIsDigit TxtCharIsDigit
    #endif

    double strToDouble(char* str)
    {
    Int start, length, punctPos;
    double result, sign, fractPart;
    char temp[30];
    UInt32 i;
    result = fractPart = 0.0;
    length = punctPos = StrLen(str);
    start = 0;
    sign = 1.0;
    if (str[0] == ‘-‘) {
    sign = -1.0;
    start = 1;
    }

    for (i = start; i < length; i++) // parse the string from left to right converting the integer part
    {
    if (str[i] != ‘.’) {
    if (PalmIsDigit(str[i]))
    {result = result * 10.0 + (double) (str[i] – 48);
    printDouble(result, temp);}
    else {
    return 0.0;
    }
    }
    else {
    punctPos = i;
    break;
    }
    }

    if (str[punctPos] == ‘.’) // parse the string from the end to the ‘.’ converting the fractional part
    {
    for (i = length – 1; i > punctPos; i–) {
    if (PalmIsDigit(str[i]))
    fractPart = fractPart / 10.0 + (double) (str[i] – 48);
    else {
    return 0.0;
    }
    }
    result += fractPart / 10.0;
    }

    return result * sign; // correcting the sign
    }

    // Set text to Field start
    static FieldPtr SetTextFromHandle(Word fieldID, Handle txtH)
    {
    Handle oldTxtH;
    FormPtr frm=FrmGetActiveForm();
    FieldPtr fldP;

    fldP=GetObjectPtr(frm, fieldID);
    ErrNonFatalDisplayIf(!fldP, "missing field");
    oldTxtH = FldGetTextHandle(fldP);

    FldSetTextHandle(fldP, txtH);
    FldDrawField(fldP);

    if (oldTxtH)//Free the old text pointer
    MemHandleFree( (VoidHand) oldTxtH);
    return fldP;
    }

    static FieldPtr SetTxtFld(Word fieldID, CharPtr strP)
    {
    Handle txtH;
    txtH = (Handle) MemHandleNew(StrLen(strP)+1);
    if (!txtH)
    return NULL;
    StrCopy(MemHandleLock((VoidHand) txtH), strP);
    MemHandleUnlock( (VoidHand) txtH);
    return SetTextFromHandle(fieldID, txtH);
    }
    //Set text to field End

    //Get text from field start
    static CharPtr GetTxtFld(Word fieldID)
    {
    CharPtr temp;
    FormPtr frmP = FrmGetActiveForm();
    FieldPtr fldP=GetObjectPtr(frmP, fieldID);
    temp=FldGetTextPtr(fldP);
    if (temp==NULL) temp="";
    return temp;
    }
    //Get text from field end

    // Initial setting
    static void mainFormInit(FormPtr frmP)
    {
    //

    //
    }

    // Menu begin
    static Boolean doMenu(FormPtr frmP, Word command)
    {
    Boolean handled = false;
    switch (command) {
    case Item001 :
    FrmAlert(Alertbox001);
    handled = true;
    break;}
    return handled;
    }
    // Menu end

    // button Manager begin
    static Boolean doButton(FormPtr frmP, Word command)
    {
    char* temp;
    char t[30];
    double inputnumber, result;
    Boolean handled = false;
    //
    temp = GetTxtFld(Field001); //get input number
    StrCopy(t, temp);
    inputnumber = strToDouble(t);
    result = inputnumber * 0.333;
    printDouble(CutDecimals(result), t); // double to string
    SetTxtFld(Field002, t); //Set the solution to the field
    //
    handled = true;
    return handled;
    }

    //button end

    static
    Boolean mainFormEventHandler(EventPtr eventP)
    {
    Boolean handled = false;
    FormPtr frmP = FrmGetActiveForm();
    switch (eventP->eType) {
    case frmOpenEvent:
    FrmDrawForm(frmP);
    mainFormInit(frmP);
    handled = true;
    break;
    case menuEvent:
    handled = doMenu(frmP, eventP->data.menu.itemID);
    break;
    case ctlSelectEvent:
    handled = doButton(frmP, eventP->data.ctlEnter.controlID);
    break;
    }
    return handled;
    }

    void stopApp()
    {

    }

    Boolean appHandleEvent(EventPtr event)
    {
    FormPtr frm;
    Int formId;
    Boolean handled = false;
    if (event->eType == frmLoadEvent) {
    formId = event->data.frmLoad.formID;
    frm = FrmInitForm(formId);
    FrmSetActiveForm(frm);
    if (formId == Form001)
    FrmSetEventHandler (frm, mainFormEventHandler);
    handled = true;
    }
    return handled;
    }

    // Main() start
    DWord PilotMain(Word cmd, Ptr cmdPBP, Word launchFlags)
    {
    EventType event;
    UInt16 error;
    if (cmd == sysAppLaunchCmdNormalLaunch) {
    FrmGotoForm(Form001);
    do {
    EvtGetEvent(&event, evtWaitForever);
    if (!SysHandleEvent(&event))
    if (!MenuHandleEvent(0, &event, &error))
    if (!appHandleEvent(&event))
    FrmDispatchEvent(&event);
    } while (event.eType != appStopEvent);
    stopApp();
    FrmCloseAllForms();
    }
    return 0;
    }
    // Main() end

    Author:admin | Categories:PDA | Tags:
  • Centro, from Palm

    2007-08-26

    At a Tech Summit in Reston, Virginia today, Sprint gave a sneak preview of some new phones coming to its network this fall. Among the new devices included a new smartphone from Palm presented as the Palm Centro.

    PalmInfocenter has confirmed at this time that the Centro is a new Palm OS smartphone that will include EVDO high speed data in a new form-factor. Read on for the rest of the details we know so far…

    The Palm Centro will debut on Sprint sometime this fall. Palm says it is the smallest Palm OS smartphone to date and that it will run on Sprints EVDO network. It features a new design targeting a younger demographic and people new to the smartphone space. It will also include a full keyboard and a touch-screen.

    The news comes to PalmInfocenter via Palm’s Public Relations manager, Paul Loeffler. Paul provided the main points above that we disclosed at the conference, however he stated that Palm is not providing photos, availability information or any other details on the Centro at this time. Paul also states that there is a "bigger story" behind the Centro which will be revealed closer to the product release date. The information above was disclosed to a select group of Sprint executives, as well as a small number of press and market analysts.

    Numerous new Palm smartphone designs have been recently leaked in the past couple months. Among them has been a new design that has been spotted running a number of different operating systems and configurations. ——————————————

    不知道实际使用感受如何,等欧洲和大陆都能用的GSM全频版本~
    哇,太喜欢了,难道说PPC手机计划暂缓?

    Author:admin | Categories:PDA | Tags:
  • 好漂亮啊,但是还是不满足

    2007-08-07
    卒子和CHPENG年初汉化的AppShelf 1.3.1,不知道现在有没有更新的版本,但苦于作者的英语我看不懂,还是用汉化版吧

    下面是我机子上的截图,大家可能要问图标哪里来的,看下面这个帖,以及第五页我发的精简rom
    http://www.maxpda.com/thread-76810-1-1.html

    AppShelf使用教程看这里
    http://bbs.tompda.com/viewthread.php?tid=1612075

    附件:
    AppShelf 1.3.1_CN.rar (2007-8-7 13:27, 365.33 K)
    ——————————————————————————————————————————————
    还是不满足
    卡上程序刷新图标慢
    内存占用1MB多,比ZL还厉害
    卡上程序不能跟内存里的程序混合分类

    Author:admin | Categories:PDA | Tags:
  • 改了一个LauncherX的皮肤,尽量模仿了系统launcher

    2007-08-06
    花了点时间研究了launcherX的皮肤代码,都是16进制符号,呵呵
    终于摸索出了里面的规律,改了一个皮肤

    同时解决了我这个帖子里的问题
    http://www.hi-pda.com/forum/viewthread.php?tid=349413(Treo650上,LauncherX的basic模式下,信号和电池显示总是不完美,何解?)
    解决方法就是这个皮肤配合PalmRevolt的苹果界面同时使用

    但是,因为我直接改的程序里的皮肤……所以没单独的皮肤拿出来
    这个1.1.5版是我最喜欢的版本。一直没丢,非常稳定,反应也很迅速
    五向键已经根据Treo650修改过,左右键是切换分类

    (这个LauncherX里面还有三个精简的LuminX皮肤,分别是tab在左上右三个)

    QUOTE:

    附件: LauncherX_Bob.prc (2007-8-6 17:38, 251.43 K)

    再改了一下内存图标

    QUOTE:

    附件: LauncherX_Bob2.prc (2007-8-6 19:07, 251.71 K)

    具体皮肤代码在这里
    也不详细解释了
    我认为可以写个程序专门为LauncherX修改皮肤用

    Author:admin | Categories:PDA | Tags:
  • Kdic词库数据结构分析,Zdic语音库拆解(附音轨),维基必须分卷的原因

    2007-08-05
    所有讨论在这个帖子里
    http://www.hi-pda.com/forum/viewthread.php?tid=371043
    下面是一个个回帖合并的内容
    ————————————————————————————
    看图说话
    我拿了小帅猫做的TEF词典来分析,该词库一共7400个词条,体积是163633字节。

    用RescoExplorer或者Bird等软件看这个词库,共有75个records,每个record大约在2200字节左右。(不知道这里是不是跟palm限制的每个记录的大小有关?)

    其索引是第一张图,可以看到,00000020h行有个4A,转换成10进制就是74。
    下面从00 00 03 4F开始,每32位(也就是4个两位数,每位都是16进制,转换成2进制后是32位)表示一个record的地址(可见光records的索引就允许达到32位长度),有74个

    其词库开头是第二章图,可以看到00000040h行有个4B,十进制是75。表示record总数
    后面紧跟着的00 00 02 A8表示词条的地址(可见这里又是32位长度)
    下面有跟语音库一样的406f以及确实可能表示词条序号的8000,8001……
    这部分索引的最后一条是00 02 7E 4E 40 6F 80 4A,是第75条(80 00 到 80 4A嘛)

    第三章图是词库中间那部分图,可以看到上面的00 02 7E 4E 40 6F 80 4A这个最后一条索引。
    这个看成是地址的32位,00 02 7E 4E,算成10进制后是163406。而用RescoExplorer查看最后一个record的长度是227。加上其地址后,正好是这个词库的总体积。所以这个32位确实是地址。

    接着后面有一段看不懂的,然后就开始了连续的词条,直到某处后,发现再接着就是连续的解释
    ——————————————————————————————————————————————
    另外我看了
    韦伯斯特词典,词条数108584条,record数6087个。
    英文字根词典,词条数7836条,record数195个。

    ——————————————————————————————————————————
    具体看我的第三张图的解释
    由此已经可以看出语音库的数据结构了
    语音库第一条数据的首地址是00 02 92 40,所以是第168512字节处。第二个数据的首地址是00 02 95 8A,是第169354字节处。
    用工具复制从168512字节到169353字节的数据,保存的16进制文本,重新命名为a.ogg的话,不知是否可以用播放器播放?

    索引有32位,所以最大文件大小是4GB。
    如果是LS所说的24位的话,就只有16MB了,显然不对。而事实上,看语音库的地址数据,后面的都用到28位地址了。都是01开头的。

    语音库里面有(523E)hex也就是21054个数据。
    不知道是不是就是咱所说的两万条的语音库?
    ——————————————————————————————————

    我抠出了abaci和abacus的音轨,其实就是按地址找出其首地址后一直到下一个首一直前那部分,全部拷贝出来,另存为一个文件。
    用Foobar可以播放,看附件

    但是,同样的做法,第一个音轨我就是弄不出来。那个a老是不能播放

    附件:
    abaci.ogg (2007-8-5 13:52, 1.3 K)
    该附件被下载次数 2

    附件:
    abacus.ogg (2007-8-5 13:52, 1.21 K)
    该附件被下载次数 1
    ——————————————————————————————————
    什么32767?
    里面文件写着OggS,什么PSpeex   speex-1.1.6,Encoded with Speex speex-1.1.6等
    看来是某种Ogg的格式吧
    因为发音组件speech是这个格式的,所以也不能改成wav

    如果要wav,可以将抠出来的音轨转成wav,不过没必要吧……
    网上下的14.2万语音库是mp3的……

    ——————————————————————————————————
    哦,你说那个8001、8001,一直到FFFF后,没法再下去了是不是?
    我拿117万词库看看去
    ——————————————————
    看到了,供2BC4个records,也就是11204个
    因为一个records里面可以有100个左右的词,所以可以支持117万词库
    如果这么算,最多32766个records的话,可以支持最大到320万左右个词条
    这个还只是这种简明词库,如果像维基那样的每个词条都几乎撑满4K的词库,就不知道了……

    这次的维基,我分成两半的词库里,records总数是43664+42716个,也就是86380个
    超过了是吧
    然后我看看最后的地址索引是……
    看图吧,确实占用了前面的空间

    第000554C0行
    地址索引是40 70 2A 8F

    如果这样的话
    算他可以用到24位,那最大records数量是FF FF FF – 6F 7F FF =9469952个
    如果可以用到32位,那最大records数量是FF FF FF FF – 40 6F 7F FF =3213918208个

    另外不知道speech.prc里面是否会处理进位的情况

    我认为,这个跟speech没有关系
    Zdic主程序判断到位置后,取出那个音轨,提供给speech播放
    speech仅管播放功能,具体的地址查询是Zdic的一个算法支持的
    ——————————————————————————————————
    跟FF聊天了解到
    palm里限制一个pdb的records最多为65535(看来record的索引是16位索引)个
    而这个维基,这样很明显要分86380左右个才行
    大大超过了65535,所以……

    要解决维基的问题,只有不用palm的pdb格式,用自创格式。
    以前做的pdb,是为了放在palmIII这样的旧设备的内存里用的
    现在有SD卡了,有外存了,大可不必遵循palm的pdb限制

    Author:admin | Categories:PDA | Tags:
  • 7月新出的维基百科、维基文库、维基教科书、维基语录以及我做的配套工具

    2007-08-02
    终于解决了悬而未决的维基百科Palm版制作问题。关于这个问题,我的想法是,总归要有人来做。没人做的话,这个事情将会一拖再拖,一直拖下去,没完没了
    我很高兴地看到,在我的倡议下,在广大网友的支持下,新词典工具的开发项目也已经展开。
    不但有掌印站长亮亮联系了开发员讨论新词典工具,还有原Zdic的作者neisoo也公开了Zdic源码,目前由FirstFan接手了这个改进项目。

    ——————————————————————
    下面转入正题,我的维基百科和wDic以及维基的其他词库
    维基百科2007年7月17日版,for Zdic、Kdic
    http://www.hi-pda.com/forum/viewthread.php?tid=370037
    维基文库、维基教科书、维基语录2007年7月26日版,for Zdic、Kdic
    http://www.hi-pda.com/forum/viewthread.php?tid=370077
    专门为维基百科对半分的版本定制的Zdic——wDic
    http://www.hi-pda.com/forum/viewthread.php?tid=370576
    ———————————————————————
    维基百科的直接下载地址:
    本次维基分段版本下载地址如下
    ftp://61.140.60.84:48021/WIKI/znwiki070717_part1_for_Kdic_Zdic.rar (93.9MB)
    ftp://61.140.60.84:48021/WIKI/znwiki070717_part2_for_Kdic_Zdic.rar (91.1MB)

    分流站点1:
    http://firefox.cybersome.com/pda/znwiki070717_part1_for_Kdic_Zdic.rar
    http://firefox.cybersome.com/pda/znwiki070717_part2_for_Kdic_Zdic.rar

    分流站点2:黑龙江网通ADSL线路(上午8.00到晚22.30提供下载),地址如下:
    http://www.thezone.cn/wiki2007/znwiki070717_for_Zdic_简体中文.rar(GB版)

    GB版本下载地址是(打在一个包里了):
    http://firefox.cybersome.com/pda/znwiki070717_for_Zdic_%bc%f2%cc%e5%d6%d0%ce%c4.rar(GB版)

    按拼音排序的GB版下载地址是(感谢小帅猫制作):
    http://firefox.cybersome.com/pda/znwiki070717_gb_1.zip(GB拼音排序版)
    http://firefox.cybersome.com/pda/znwiki070717_gb_2.zip(GB拼音排序版)

    Author:admin | Categories:PDA | Tags: