ユーザ用ツール

サイト用ツール


ハイハイスクールアドベンチャー_palmos版

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
ハイハイスクールアドベンチャー_palmos版 [2025/11/06 23:54] – [概要] arakiハイハイスクールアドベンチャー_palmos版 [2025/11/20 04:22] (現在) – [NDKのこと] araki
行 56: 行 56:
  
 モダンなグラフィックライブラリは大体ダブルバッファ使っていたりするし、レンダリングは一気に行われるスタイルだったり、UI用のスレッド以外では表示の更新ができなかったりという制約の中でやっているので、そんなことをいわれてもどうにもならないのだ。 モダンなグラフィックライブラリは大体ダブルバッファ使っていたりするし、レンダリングは一気に行われるスタイルだったり、UI用のスレッド以外では表示の更新ができなかったりという制約の中でやっているので、そんなことをいわれてもどうにもならないのだ。
 +
 +
 +<file c high.h>
 +/*
 + * High High School Adventure
 + *
 +    Copyright(c)1985 ZOBplus
 +    Copyright(c)2002,2025 ZOBplus hiro <hiro@zob.ne.jp>
 + */
 +
 +#ifndef HIGH_H
 +#define HIGH_H
 +
 +#define ZAMA_CREATOR_ID   'ZAMA'
 +#define ZAMA_PREFS_ID     (0)
 +#define ZAMA_PREFS_VER    (100)
 +
 +#define ZAMA_ITEM_NUMBERS (12)
 +#define ZAMA_CMD_INVALID  (0)
 +#define ZAMA_CMD_END      (61)
 +
 +#define ZAMA_SILK_NOTIFY  (1)
 +
 +#define ZAMA_CODE_ISAKO   (135)
 +
 +#define ZAMA_GLOBAL_VAR   (5000)
 +#define ZAMA_GRAPH_VAR    (5001)
 +
 +enum ZamaDirection {
 +  DirInvalid = -1,
 +  DirNorth, DirSouth, DirWest, DirEast, DirUp, DirDown, DirEnter, DirExit,
 +  DirMax
 +};
 +
 +enum ZamaSex {
 +  SexInvalid = 0,
 +  SexBoy,
 +  SexGirl,
 +  SexMax
 +};
 +
 +enum ActType {
 +  ActComp = 0,
 +  ActAction
 +};
 +
 +enum CmpOperator {
 +  CMP_NOP = 0,
 +  CMP_EQ,
 +  CMP_NE,
 +  CMP_GT,
 +  CMP_GE,
 +  CMP_LT,
 +  CMP_LE,
 +};
 +
 +enum ActOperator {
 +  ACT_NOP = 0,
 +  ACT_MOVE,
 +  ACT_ASGN,
 +  ACT_MESG,
 +  ACT_DLOG,
 +  ACT_LOOK,
 +  ACT_SND,
 +  ACT_OVER,
 +};
 +
 +enum RuleValueType {
 +  TYPE_NONE = 0,
 +  TYPE_FACT,
 +  TYPE_PLACE,
 +  TYPE_SYSTEM,
 +  TYPE_VECTOR,
 +};
 +
 +typedef struct CmdHeaderType {
 +  UInt16 _act:1;
 +  UInt16 _op:3;
 +  UInt16 _pad:4;
 +  UInt16 _type:3;
 +  UInt16 _id:5;
 +} CmdHeaderType;
 +typedef CmdHeaderType *CmdHeaderPtr;
 +
 +typedef struct CmdBodyType {
 +  UInt16 _type:3;
 +  UInt16 _id:5;
 +  UInt16 _value:8;
 +} CmdBodyType;
 +typedef CmdBodyType *CmdBodyPtr;
 +
 +typedef struct CmdBlkType {
 +  CmdHeaderType _head;
 +  CmdBodyType   _body;
 +} CmdBlkType;
 +typedef CmdBlkType *CmdBlkPtr;
 +
 +typedef struct RuleType {
 +  UInt8 _mapId;
 +  UInt8 _cmdN;
 +  UInt8 _objN;
 +  UInt8 _pad;
 +  UInt8 _args[44];
 +} RuleType;
 +typedef RuleType *RulePtr;
 +
 +#define EndOfRule (0xff)
 +
 +typedef struct ZamaPrefsType {
 +  UInt8   _lastSaved;
 +  Boolean _suspended;
 +  FontID  _curFont;
 +  Boolean _linedraw;
 +  Boolean _sound;
 +} ZamaPrefsType;
 +typedef ZamaPrefsType *ZamaPrefsPtr;
 +
 +typedef struct ZamaMapType {
 +  UInt8 graphic[0x400];
 +  UInt8 reaction[0x100];
 +  UInt8 mesg[0x300];
 +} ZamaMapType;
 +typedef ZamaMapType *ZamaMapPtr;
 +
 +typedef struct ZamaUserDataType {
 +  UInt8   vector[87][8];
 +  UInt8   place[ZAMA_ITEM_NUMBERS];
 +  UInt8   fact[15];
 +  union {
 +    struct {
 +      UInt8 mapID, mapW, cmdN, objN, dret, rand, dlogOk, dmesg;
 +    } n;
 +    UInt8 ary[8]; /* 0: mapID 1: mapW  2: cmdN 3: objN 4: dret 5: rand */
 +                  /* 6: dlogOk 7: dmesg 8: reserved */
 +  } sys;
 +} ZamaUserDataType;
 +typedef ZamaUserDataType *ZamaUserDataPtr;
 +
 +typedef struct ZamaWordType {
 +  Char  word[4];
 +  UInt8 number;
 +} ZamaWordType;
 +typedef ZamaWordType *ZamaWordPtr;
 +
 +typedef struct ZamaMesgType {
 +  UInt8 len;
 +  Char  mesg[1];
 +} ZamaMesgType;
 +typedef ZamaMesgType *ZamaMesgPtr;
 +
 +typedef struct ZamaReactionType {
 +  UInt16 action;
 +  UInt8  number;
 +} ZamaReactionType;
 +typedef ZamaReactionType *ZamaReactionPtr;
 +
 +#ifndef stdSilkHeight
 +#define stdSilkHeight (65)
 +#endif /* stdSilkHeight */
 +
 +#endif /* HIGH_H */
 +</file>
 +<file c high.c>
 +/*
 + * High-High School Adventure
 +   Copyright(c)2002-2003 ZOBplus hiro <hiro@zob.ne.jp>
 +   Copyright(c)ZOBplus
 + */
 +
 +#include <PalmOS.h>
 +#include <SonyCLIE.h>
 +#include <SmallFontSupport.h>
 +#ifdef USE_GRAPH2
 +#include "graph2.h"
 +#else /* USE_GRAPH2 */
 +#include "graph.h"
 +#endif /* USE_GRAPH2 */
 +#include "high.h"
 +#include "highrsc.h"
 +
 +typedef struct {
 +  ZamaMapType      map;
 +  ZamaUserDataType user;
 +  UInt8            object[0x200];
 +  ZamaPrefsType    prefs;
 +
 +  Char             cmd[5];
 +  Char             obj[5];
 +
 +  RectangleType    pict;
 +  UInt16           _silkr; /* silk control */
 +  UInt32           _silkVer;
 +  Boolean          _resized; /* resized */
 +  Boolean          _ignoreKey;
 +
 +  UInt32           _startup;
 +  Boolean          _over;
 +
 +/* tsPatch support */
 +  Boolean          tsPatch;
 +  UInt32           tinyFontID;
 +  UInt32           tinyBoldFontID;
 +  UInt32           smallFontID;
 +  UInt32           smallSymbolFontID;
 +  UInt32           smallSymbol11FontID;
 +  UInt32           smallSymbol7FontID;
 +  UInt32           smallLedFontID;
 +  UInt32           smallBoldFontID;
 +} ZamaGlobalVarType;
 +
 +static
 +ZamaGlobalVarType *
 +CreateGlobalVariables()
 +{
 +  ZamaGlobalVarType *ptr = NULL;
 +  Err err;
 +  if ((err = FtrPtrNew(ZAMA_CREATOR_ID, ZAMA_GLOBAL_VAR, sizeof(ZamaGlobalVarType), &ptr)) != errNone)
 +  {
 +    return NULL;
 +  }
 +  return ptr;
 +}
 +
 +static
 +void
 +DeleteGlobalVariables()
 +{
 +  FtrPtrFree(ZAMA_CREATOR_ID, ZAMA_GLOBAL_VAR);
 +}
 +
 +static
 +ZamaGlobalVarType *
 +GetGlobalVariables()
 +{
 +  ZamaGlobalVarType *ptr = NULL;
 +  Err err;
 +  if ((err = FtrGet(ZAMA_CREATOR_ID, ZAMA_GLOBAL_VAR, &ptr)) != errNone)
 +  {
 +    return NULL;
 +  }
 +  return ptr;
 +}
 +
 +static
 +MemPtr
 +GetObjectPtr(UInt16 id)
 +{
 +  FormPtr form;
 +  form = FrmGetActiveForm();
 +  return FrmGetObjectPtr(form, FrmGetObjectIndex(form, id));
 +}
 +
 +static
 +DmOpenRef
 +OpenDatabase(Char *name_)
 +{
 +  LocalID     dbID;
 +  DmOpenRef   dbP;
 +  Err         err;
 +  UInt16      cardNo;
 +
 +  if ((err = SysCurAppDatabase(&cardNo, &dbID)) != errNone) {
 +    cardNo = 0;
 +  }
 +  if ((dbID = DmFindDatabase(cardNo, name_)) == 0) {
 +    /* error */
 +    return NULL;
 +  }
 +  if ((dbP = DmOpenDatabase(cardNo, dbID, dmModeReadOnly)) == 0) {
 +    /* error */
 +    return NULL;
 +  }
 +  return dbP;
 +}
 +
 +static
 +Boolean
 +SaveGame(UInt16 fileno_)
 +{
 +  LocalID     dbID;
 +  DmOpenRef   dbP;
 +  MemHandle   rec;
 +  UInt16      err, i, index, attr, version;
 +  MemPtr      p;
 +  Boolean     res = true;
 +  UInt16      cardNo;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  if ((err = SysCurAppDatabase(&cardNo, &dbID)) != errNone) {
 +    cardNo = 0;
 +  }
 +  while ((dbID = DmFindDatabase(cardNo, "ZAMAuser")) == 0) {
 +    /* create database */
 +    err = DmCreateDatabase(cardNo, "ZAMAuser", ZAMA_CREATOR_ID, 'data', false);
 +    if (err) {
 +      FrmAlert(ZAMA_SAVE_ALERT);
 +      return false;
 +    }
 +  }
 +  DmDatabaseInfo(cardNo, dbID, NULL, &attr, &version,
 +                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
 +  attr |= dmHdrAttrBackup;
 +  version = 0x100; /* version 1.00 */
 +  DmSetDatabaseInfo(cardNo, dbID, NULL, &attr, &version,
 +                    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
 +  if ((dbP = DmOpenDatabase(cardNo, dbID, dmModeReadWrite)) == 0) {
 +    /* error */
 +    FrmAlert(ZAMA_SAVE_ALERT);
 +    return false;
 +  }
 +  for (i = 0 ; i < 4 ; i++) {
 +    if (DmQueryRecord(dbP, i) == NULL) {
 +      if ((rec = DmNewHandle(dbP, sizeof(ZamaUserDataType))) == NULL) {
 +        FrmAlert(ZAMA_SAVE_ALERT);
 +        res = false;
 +        goto _done;
 +      }
 +      index  = i;
 +      if (DmAttachRecord(dbP, &index, rec, NULL) != errNone) {
 +        FrmAlert(ZAMA_SAVE_ALERT);
 +        res = false;
 +        goto _done;
 +      }
 +    }
 +  }
 +  if ((rec = DmGetRecord(dbP, fileno_)) == NULL) {
 +    FrmAlert(ZAMA_SAVE_ALERT);
 +    res = false;
 +    goto _done;
 +  }
 +  p = MemHandleLock(rec);
 +
 +  DmWrite(p, 0, &z->user, sizeof(ZamaUserDataType));
 +
 +  MemHandleUnlock(rec);
 +  DmReleaseRecord(dbP, fileno_, true);
 +  if (fileno_ != 0) {
 +    z->prefs._lastSaved = fileno_;
 +  }
 + _done:;
 +  DmCloseDatabase(dbP);
 +  return res;
 +}
 +
 +static
 +Boolean
 +LoadGame(UInt16 fileno_)
 +{
 +  DmOpenRef   dbP;
 +  MemHandle   rec;
 +  Char        sid[16];
 +  MemPtr      p;
 +  Boolean     res = true;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  if ((dbP = OpenDatabase("ZAMAuser")) == NULL) {
 +    FrmCustomAlert(ZAMA_NODATA_ALERT, StrIToA(sid, fileno_), NULL, NULL);
 +    return false;
 +  }
 +  if ((rec = DmQueryRecord(dbP, fileno_)) == NULL) {
 +    FrmCustomAlert(ZAMA_NODATA_ALERT, StrIToA(sid, fileno_), NULL, NULL);
 +    res = false;
 +    goto _done;
 +  }
 +  p = MemHandleLock(rec);
 +
 +  MemMove((MemPtr)&z->user, p, sizeof(ZamaUserDataType));
 +
 +  MemHandleUnlock(rec);
 +  z->prefs._lastSaved = fileno_;
 + _done:;
 +  DmCloseDatabase(dbP);
 +  return res;
 +}
 +
 +#ifdef USE_GRAPH2
 +static
 +FontID
 +ZamaFontSelect(FontID curFont_)
 +{
 +  FormPtr       formP;
 +  UInt16        ret;
 +  Coord         x, y;
 +  WinHandle     hWin;
 +  RectangleType bounds;
 +  FontID        font;
 +  UInt16        small, fnt;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  formP = FrmInitForm(ZAMA_FONT_FORM);
 +  GGetDisplayExtent(&x, &y, false);
 +  if (y > 160) {
 +    /* silk turned off */
 +    hWin = FrmGetWindowHandle(formP);
 +    WinGetBounds(hWin, &bounds);
 +    bounds.topLeft.y += stdSilkHeight;
 +    if (bounds.topLeft.y + bounds.extent.y >= y) {
 +      bounds.topLeft.y = y - bounds.extent.y;
 +    }
 +    WinSetBounds(hWin, &bounds);
 +  }
 +  small = FrmGetObjectIndex(formP, ZAMA_SMALL_FONT);
 +  font = curFont_;
 +  if (font & fntAppFontCustomBase) {
 +    font -= fntAppFontCustomBase;
 +    CtlSetValue(FrmGetObjectPtr(formP, small), true);
 +  }
 +  switch (font) {
 +  case stdFont:       fnt = ZAMA_STD_FONT;        break;
 +  case boldFont:      fnt = ZAMA_BOLD_FONT;       break;
 +  case largeFont:     fnt = ZAMA_LARGE_FONT;      break;
 +  case largeBoldFont: fnt = ZAMA_LARGE_BOLD_FONT; break;
 +  default:
 +    CtlSetValue(FrmGetObjectPtr(formP, small), true);
 +    if (font == z->tinyFontID) {
 +      fnt = ZAMA_STD_FONT;
 +    } else if (font == z->tinyBoldFontID) {
 +      fnt = ZAMA_BOLD_FONT;
 +    } else if (font == z->smallFontID) {
 +      fnt = ZAMA_LARGE_FONT;
 +    } else if (font == z->smallBoldFontID) {
 +      fnt = ZAMA_LARGE_BOLD_FONT;
 +    } else {
 +      fnt = ZAMA_STD_FONT;
 +    }
 +    break;
 +  }
 +  fnt = FrmGetObjectIndex(formP, fnt);
 +  CtlSetValue(FrmGetObjectPtr(formP, fnt), true);
 +  FrmUpdateForm(ZAMA_FONT_FORM, frmRedrawUpdateCode);
 +  ret = FrmDoDialog(formP);
 +  fnt = FrmGetControlGroupSelection(formP, ZAMA_FONT_SELECT);
 +  if (fnt == frmNoSelectedControl) {
 +    ret = ZAMA_BUTTON_CANCEL;
 +  }
 +  if (fnt == FrmGetObjectIndex(formP, ZAMA_STD_FONT)) {
 +    fnt = stdFont;
 +  } else if (fnt == FrmGetObjectIndex(formP, ZAMA_BOLD_FONT)) {
 +    fnt = boldFont;
 +  } else if (fnt == FrmGetObjectIndex(formP, ZAMA_LARGE_FONT)) {
 +    fnt = largeFont;
 +  } else if (fnt == FrmGetObjectIndex(formP, ZAMA_LARGE_BOLD_FONT)) {
 +    fnt = largeBoldFont;
 +  } else {
 +    ret = ZAMA_BUTTON_CANCEL;
 +  }
 +  if (CtlGetValue(FrmGetObjectPtr(formP, small))) {
 +    if (z->tsPatch) {
 +      switch (fnt) {
 +      case stdFont:      fnt = z->tinyFontID; break;
 +      case boldFont:     fnt = z->tinyBoldFontID; break;
 +      case largeFont:    fnt = z->smallFontID; break;
 +      case largeBoldFont: fnt = z->smallBoldFontID; break;
 +      }
 +    } else {
 +      fnt += fntAppFontCustomBase;
 +    }
 +  }
 +  FrmDeleteForm(formP);
 +  return (ret == ZAMA_BUTTON_OK) ? fnt : curFont_;
 +}
 +#endif /* USE_GRAPH2 */
 +
 +static
 +Boolean
 +ZamaSndPlay(UInt16 id)
 +{
 +  UInt16  volRefNum;
 +  Err     err;
 +  Char    *pathFmt =  = "/Palm/PROGRAMS/high/%d.wav";
 +  Char    pathName[1024];
 +  FileRef dbFileRef;
 +  UInt32  size;
 +  SndPtr  bufP;
 +  UInt32  vIterator;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +  if (z->prefs._sound) {
 +    /* play sound */
 +    StrPrintF(pathName, pathFmt, id);
 +    vIterator = vfsIteratorStart;
 +     err = VFSVokumeEnumerate(&volRefNum, &vIterator);
 +    if (err != errNone) {
 +      return false;
 +    }
 +    if (VFSFileOpen(volRefNum, pathName, vfsModeRead, &dbFileRef) != errNone) {
 +      return false;
 +    }
 +    VFSFileSize(dbFileRef, &size);
 +  }
 +  return true;
 +}
 +
 +static
 +void
 +VOSplit(Char *srcP_)
 +{
 +  Char   *p;
 +  UInt16  i;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  StrCopy(z->cmd, "!!!!");
 +  StrCopy(z->obj, "!!!!");
 +  for (p = srcP_ ; *p && *p == ' ' ; p++); /* skip heading space */
 +  for (i = 0 ; *p && *p != ' ' && i < 4 ; i++) {
 +    z->cmd[i] = 1 + *p++;
 +  }
 +  for ( ; *p && *p != ' ' ; p++); /* skip until space */
 +  for ( ; *p && *p == ' ' ; p++); /* skip space */
 +  for (i = 0 ; *p && *p != ' ' && i < 4 ; i++) {
 +    z->obj[i] = 1 + *p++;
 +  }
 +}
 +
 +static
 +UInt16
 +SearchWord(Char *word_, Boolean verb_)
 +{
 +  DmOpenRef   dbP;
 +  MemHandle   rec;
 +  ZamaWordPtr p;
 +  UInt16      index;
 +  UInt16      i, n;
 +
 +  if (word_ == NULL || StrCompare("!!!!", word_) == 0) {
 +    return 0;
 +  }
 +  if ((dbP = OpenDatabase("ZAMAdict")) == NULL) {
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "����", NULL, NULL);
 +    return 0;
 +  }
 +  index = (verb_) ? 0 : 1;
 +  n = 0;
 +  if ((rec = DmQueryRecord(dbP, index)) == NULL) {
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "����", NULL, NULL);
 +    goto _done;
 +  }
 +  p = (ZamaWordPtr)MemHandleLock(rec);
 +  for (i = 0 ; p[i].word[0] ; i++) {
 +    if (StrNCaselessCompare(word_, p[i].word, 4) == 0) {
 +      n = p[i].number;
 +      break;
 +    }
 +  }
 +  MemHandleUnlock(rec);
 + _done:;
 +  DmCloseDatabase(dbP);
 +  return n;
 +}
 +
 +static
 +MemHandle
 +SearchFixedMessage(UInt16 mesgId_)
 +{
 +  ZamaMesgPtr  p = NULL;
 +  UInt16       i;
 +  DmOpenRef    dbP;
 +  MemHandle    rec, mesg;
 +  ZamaMesgPtr  mesgP;
 +
 +  if ((dbP = OpenDatabase("ZAMAdict")) == NULL) {
 +    /* error */
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "����", NULL, NULL);
 +    return 0;
 +  }
 +  mesg = 0;
 +  if ((rec = DmQueryRecord(dbP, 2)) == NULL) {
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "����", NULL, NULL);
 +    goto _done;
 +  }
 +  mesgId_ &= 0x7f;
 +  p = (ZamaMesgPtr)MemHandleLock(rec);
 +  for (i = 0 ; p->len > 0 && i < mesgId_ - 1 ; i++) {
 +    p = (ZamaMesgPtr)(p->mesg + p->len);
 +  }
 +  if (p && p->len) {
 +    mesg = MemHandleNew(sizeof(ZamaMesgType) + p->len - 1);
 +    mesgP = (ZamaMesgPtr)MemHandleLock(mesg);
 +    MemMove(mesgP, p, sizeof(ZamaMesgType) + p->len - 1);
 +    MemHandleUnlock(mesg);
 +  }
 +
 +  MemHandleUnlock(rec);
 + _done:;
 +  DmCloseDatabase(dbP);
 +  return mesg;
 +}
 +
 +static
 +MemHandle
 +SearchMapMessage(UInt16 cmdN_, UInt16 objN_)
 +{
 +  ZamaMesgPtr      p = NULL;
 +  int              i;
 +  int              n = 0;
 +  ZamaReactionType mp;
 +  UInt8           *rp = map.reaction;
 +  MemHandle        mesg;
 +  ZamaMesgPtr      mesgP;
 +
 +  cmdN_ = (cmdN_ << 8) | objN_;
 +  for (i = 0 ; *rp ; i++) {
 +    mp.action = (rp[0] << 8) | rp[1];
 +    mp.number = rp[2];
 +    if (cmdN_ == mp.action) {
 +      p = (ZamaMesgPtr)map.mesg;
 +      for (n = 0 ; p->len > 0 && n < mp.number - 1 ; n++) {
 +        p = (ZamaMesgPtr)(p->mesg + p->len);
 +      }
 +      break;
 +    }
 +    rp += 3;
 +  }
 +  mesg = 0;
 +  if (p && p->len) {
 +    mesg = MemHandleNew(sizeof(ZamaMesgType) + p->len - 1);
 +    mesgP = (ZamaMesgPtr)MemHandleLock(mesg);
 +    MemMove(mesgP, p, sizeof(ZamaMesgType) + p->len - 1);
 +    MemHandleUnlock(mesg);
 +  } else {
 +    cmdN_ >>= 8; /* restore Command ID */
 +    i = 0;
 +    if (cmdN_ <= 0x0e && cmdN_ >= 0x0b) {
 +      i = cmdN_ - 8;
 +    } else if (cmdN_ == 7 || cmdN_ == 8) {
 +      i = cmdN_ - 6;
 +    } else if (cmdN_ >= 0x11 && cmdN_ <= 0x18) {
 +      i = cmdN_ - 9;
 +    } else if (cmdN_ == 0x1c || cmdN_ == 0x1d) {
 +      i = cmdN_ - 12;
 +    } else if (cmdN_ == 0x20 || cmdN_ == 0x21) {
 +      i = cmdN_ - 14;
 +    } else if (cmdN_ == 0x26) {
 +      i = 0x14;
 +    } else if (cmdN_ == 0x28 || cmdN_ == 0x2f) {
 +      i = 0x15;
 +    } else if (cmdN_ == 0x29) {
 +      i = 7;
 +    } else if (objN_ == 0) {
 +      i = 0x30 + (SysRandom(0) % 4);
 +    }
 +    if (i) {
 +      mesg = SearchFixedMessage(i);
 +    }
 +  }
 +  return mesg;
 +}
 +
 +static
 +void
 +ScrollMessageField(void)
 +{
 +  Int16        lines, pos, min, max, page;
 +  UInt16       scrollPos, textHeight, fieldHeight;
 +  FieldPtr     fldP;
 +  ScrollBarPtr scrP;
 +  fldP = GetObjectPtr(ZAMA_MESSAGE_FIELD);
 +  scrP = GetObjectPtr(ZAMA_SCROLL_BAR);
 +  SclGetScrollBar(scrP, &pos, &min, &max, &page);
 +  FldGetScrollValues(fldP, &scrollPos, &textHeight, &fieldHeight);
 +  lines = (pos - scrollPos) /** GScale()*/;
 +  if (lines > 0) {
 +    FldScrollField(fldP, lines, winDown);
 +  } else if (lines < 0) {
 +    FldScrollField(fldP, -lines, winUp);
 +  }
 +  FldSetDirty(fldP, true);
 +#ifdef USE_GRAPH2
 +  if (tsPatch) {
 +    FldDrawField(fldP);
 +  } else {
 +    GFldDrawField(fldP);
 +  }
 +#else /* USE_GRAPH2 */
 +  ZamaFldDrawField(fldP);
 +#endif /* USE_GRAPH2 */
 +}
 +
 +static
 +void
 +UpdateMessageFieldScrollbar(void)
 +{
 +  UInt16       scrollPos, textHeight, fieldHeight;
 +  Int16        maxValue;
 +  FieldPtr     fldP;
 +  ScrollBarPtr scrP;
 +
 +  fldP = GetObjectPtr(ZAMA_MESSAGE_FIELD);
 +  scrP = GetObjectPtr(ZAMA_SCROLL_BAR);
 +  maxValue = 0;
 +  FldGetScrollValues(fldP,&scrollPos, &textHeight, &fieldHeight);
 +  /* fieldHeight *= GScale(); */
 +  if (textHeight > fieldHeight) {
 +    maxValue = (textHeight - fieldHeight) + FldGetNumberOfBlankLines(fldP);
 +  } else if (scrollPos) {
 +    maxValue = scrollPos;
 +  }
 +  SclSetScrollBar(scrP, scrollPos, 0, maxValue, fieldHeight - 1);
 +}
 +
 +static
 +void
 +CleanMessageField(void)
 +{
 +  FieldPtr  fldP;
 +  MemHandle hText;
 +
 +  fldP = GetObjectPtr(ZAMA_MESSAGE_FIELD);
 +#ifdef USE_GRAPH2
 +  if (tsPatch) {
 +    FldEraseField(fldP);
 +  } else {
 +    GFldEraseField(fldP);
 +  }
 +#else /* USE_GRAPH2 */
 +  ZamaFldEraseField(fldP);
 +#endif /* USE_GRAPH2 */
 +  if ((hText = FldGetTextHandle(fldP)) != NULL) {
 +    FldSetTextHandle(fldP, NULL);
 +    MemHandleFree(hText);
 +    FldSetDirty(fldP, true);
 +  }
 +  UpdateMessageFieldScrollbar();
 +#ifdef USE_GRAPH2
 +  if (tsPatch) {
 +    FldDrawField(fldP);
 +  } else {
 +    GFldDrawField(fldP);
 +  }
 +#else /* USE_GRAPH2 */
 +  ZamaFldDrawField(fldP);
 +#endif /* USE_GRAPH2 */
 +}
 +
 +static
 +void
 +PutMessageToField(Char *strP_, UInt16 len_)
 +{
 +  FieldPtr      fldP;
 +  MemHandle     hText;
 +  Char          *textP;
 +  UInt16        max;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  fldP  = GetObjectPtr(ZAMA_MESSAGE_FIELD);
 +  max   = FldGetTextLength(fldP);
 +  hText = FldGetTextHandle(fldP);
 +  FldSetTextHandle(fldP, NULL);
 +  if (hText == NULL) {
 +    hText = MemHandleNew(len_ + 1);
 +    textP = MemHandleLock(hText);
 +  } else {
 +    MemHandleResize(hText, max + len_ + 2);
 +    textP = MemHandleLock(hText);
 +    textP[max++] = '\n'; /* add newline */
 +    textP[max]   = 0;
 +  }
 +  MemMove(&textP[max], strP_, len_);
 +  textP[max + len_] = 0;
 +  MemHandleUnlock(hText);
 +
 +  FldSetTextHandle(fldP, hText);
 +  FldSetDirty(fldP, true);
 +#ifdef USE_GRAPH2
 +  if (z->tsPatch) {
 +    FldDrawField(fldP);
 +  } else {
 +    GFldDrawField(fldP);
 +  }
 +#else /* USE_GRAPH2 */
 +  ZamaFldDrawField(fldP);
 +#endif /* USE_GRAPH2 */
 +  UpdateMessageFieldScrollbar();
 +}
 +
 +static
 +void
 +DrawMessage(UInt16 mesgId_, UInt16 cmdN_, UInt16 objN_)
 +{
 +  Char          *strP;
 +  UInt16        len;
 +  MemHandle     mesg;
 +  ZamaMesgPtr   mesgP;
 +
 +  if (mesgId_ & 0x80) {
 +    mesg = SearchFixedMessage(mesgId_ & 0x7f);
 +  } else {
 +    if (mesgId_ == 1) {
 +      mesgP = (ZamaMesgPtr)map.mesg;
 +      mesg  = MemHandleNew(sizeof(ZamaMesgType) + mesgP->len - 1);
 +      MemMove(MemHandleLock(mesg), mesgP, sizeof(ZamaMesgType) + mesgP->len - 1);
 +      MemHandleUnlock(mesg);
 +    } else {
 +      mesg = SearchMapMessage(cmdN_, objN_);
 +    }
 +  }
 +  strP = "�_��";
 +  len  = StrLen(strP);
 +  if (mesg) {
 +    mesgP = (ZamaMesgPtr)MemHandleLock(mesg);
 +    strP  = mesgP->mesg;
 +    len   = mesgP->len;
 +  }
 +  PutMessageToField(strP, len);
 +  if (mesg) {
 +    MemHandleUnlock(mesg);
 +    MemHandleFree(mesg);
 +  }
 +}
 +
 +static
 +Boolean
 +LoadInitData(void)
 +{
 +  DmOpenRef dbP;
 +  MemHandle rec;
 +  MemPtr    p;
 +  Boolean   res = true;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  if ((dbP = OpenDatabase("ZAMAinit")) == NULL) {
 +    /* error */
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "�����f�[�^", NULL, NULL);
 +    return false;
 +  }
 +  if ((rec = DmQueryRecord(dbP, 0)) == NULL) {
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "�����f�[�^", NULL, NULL);
 +    res = false;
 +    goto _done;
 +  }
 +  p   = (MemPtr)MemHandleLock(rec);
 +  MemMove(&z->user.vector, p, sizeof(z->user.vector));
 +  MemHandleUnlock(rec);
 +
 +  if ((rec = DmQueryRecord(dbP, 1)) == NULL) {
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "�����f�[�^", NULL, NULL);
 +    res = false;
 +    goto _done;
 +  }
 +  p   = (MemPtr)MemHandleLock(rec);
 +  MemMove(&z->user.place, p, sizeof(z->user.place));
 +  MemHandleUnlock(rec);
 +
 +  if ((rec = DmQueryRecord(dbP, 2)) == NULL) {
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "�����f�[�^", NULL, NULL);
 +    res = false;
 +    goto _done;
 +  }
 +  p   = (MemPtr)MemHandleLock(rec);
 +  MemMove(&z->user.fact, p, sizeof(z->user.fact));
 +  MemHandleUnlock(rec);
 + _done:;
 +  DmCloseDatabase(dbP);
 +  return res;
 +}
 +
 +static
 +Boolean
 +LoadMapData(UInt16 id)
 +{
 +  DmOpenRef dbP;
 +  MemHandle rec;
 +  MemPtr    p;
 +  Boolean   res = true;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  if ((dbP = OpenDatabase("ZAMAmap")) == NULL) {
 +    /* error */
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "�n�}", NULL, NULL);
 +    return false;
 +  }
 +  if ((rec = DmQueryRecord(dbP, id)) == NULL) {
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "�n�}", NULL, NULL);
 +    res = false;
 +    goto _done;
 +  }
 +  p   = (MemPtr)MemHandleLock(rec);
 +  MemMove(&z->map, p, sizeof(ZamaMapType));
 +  MemHandleUnlock(rec);
 + _done:;
 +  DmCloseDatabase(dbP);
 +  return true;
 +}
 +
 +static
 +Boolean
 +LoadObjectData(UInt16 id)
 +{
 +  DmOpenRef dbP;
 +  MemHandle rec;
 +  MemPtr    p;
 +  Boolean   res = true;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  if ((dbP = OpenDatabase("ZAMAobj")) == NULL) {
 +    /* error */
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "��̉摜", NULL, NULL);
 +    return false;
 +  }
 +  if ((rec = DmQueryRecord(dbP, id)) == NULL) {
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "��̉摜", NULL, NULL);
 +    res = false;
 +    goto _done;
 +  }
 +  p   = (MemPtr)MemHandleLock(rec);
 +  MemMove(z->object, p, 0x200);
 +  MemHandleUnlock(rec);
 + _done:;
 +  DmCloseDatabase(dbP);
 +  return true;
 +}
 +
 +static
 +UInt16
 +WinDrawOutline(RectanglePtr bP, UInt8 *data,
 +#ifdef USE_GRAPH2
 +               GColorName c
 +#else /* USE_GRAPH2 */
 +               ZamaColorName c
 +#endif /* USE_GRAPH2 */
 +               )
 +{
 +  Coord  x0, y0, x1, y1;
 +  UInt16 i = 0;
 +
 +  x0 = data[i++];
 +  y0 = data[i++];
 +  for (;;) {
 +    x1 = data[i++];
 +    y1 = data[i++];
 +    if (y1 == 0xff) {
 +      if (x1 == 0xff) {
 +        /* end of line data */
 +        break;
 +      }
 +      /* reset line */
 +      x0 = data[i++];
 +      y0 = data[i++];
 +      continue;
 +    }
 +#ifdef USE_GRAPH2
 +    GDrawLine(NULL,
 +              bP->topLeft.x + x0, bP->topLeft.y + y0,
 +              bP->topLeft.x + x1, bP->topLeft.y + y1, c);
 +#else /* USE_GRAPH2 */
 +    ZamaDrawLine(bP->topLeft.x + x0, bP->topLeft.y + y0,
 +                 bP->topLeft.x + x1, bP->topLeft.y + y1, c);
 +#endif /* USE_GRAPH2 */
 +    x0 = x1; y0 = y1;
 +  }
 +  return i;
 +}
 +
 +static
 +void
 +DrawObject(Boolean pre, UInt8 *data)
 +{
 +  UInt16           o = 0;
 +  Coord            xs, ys;
 +  UInt8            b, c;
 +  RectangleType    r;
 +
 +  b  = data[o++];
 +  xs = (data[o++] / 2) + 32;
 +  ys = data[o++] + 32;
 +  RctSetRectangle(&r, xs, ys, 32 + 256 - xs, 32 + 152 - ys);
 +  WinPushDrawState();
 +#ifdef USE_GRAPH2
 +  o += WinDrawOutline(&r, &data[o], (pre)? gColorDarkYellow : b);
 +#else /* USE_GRAPH2 */
 +  o += WinDrawOutline(&r, &data[o], (pre)? DarkYellow : b);
 +#endif /* USE_GRAPH2 */
 +  xs = data[o++];
 +  ys = data[o++];
 +  while (xs != 0xff || ys != 0xff) {
 +    c = data[o++];
 +    /* in order to avoid paint loss */
 +#ifdef USE_GRAPH2
 +    GPaint(&r, xs, ys, (pre)? gColorDarkGray : c, (pre)? gColorDarkYellow : b);
 +#else /* USE_GRAPH2 */
 +    ZamaPaint(&r, xs, ys, (pre) ? DarkGray : c, (pre) ? DarkYellow : b);
 +#endif /* USE_GRAPH2 */
 +    xs = data[o++];
 +    ys = data[o++];
 +  }
 +  WinPopDrawState();
 +}
 +
 +static
 +void
 +ObjectCheck(UInt16 mapID, Boolean msgOut)
 +{
 +  int              i;
 +  int              o = 0;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  for (i = 0 ; i < 12 ; i++) {
 +    if (z->user.place[i] == mapID && LoadObjectData(i + 1)) {
 +      /* draw object bitmap */
 +      o = 0;
 +      if (i == 1 /* Uniform */) {
 +        o = (z->user.fact[0] == 1) ? 0 : 256;
 +      }
 +      DrawObject(true,  &object[o]);
 +      DrawObject(false, &object[o]);
 +      if (msgOut) DrawMessage(0x96 + i, 0, 0);
 +    }
 +  }
 +}
 +
 +static
 +void
 +DrawTeacher(void)
 +{
 +  Coord             x0, y0, x1, y1, oy;
 +  UInt16            i, j, k;
 +  UInt8             c = 0;
 +  UInt16            rep[] = { 18, 24, 2, 2, 2, 22, 9, 0xffff };
 +  UInt16            rep2[] = { 148, 14, 126, 6, 0, 0 };
 +  RectangleType     r, wr;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  oy = 32;
 +  if (LoadObjectData(15)) {
 +    RctSetRectangle(&r, 0, 0, 320, 320);
 +    y0 = 63;
 +    for (i = 0 ; i <= 172 ; i += 2) {
 +      x0 = z->object[i + 0];
 +      x1 = z->object[i + 1];
 +#ifdef USE_GRAPH2
 +    GDrawLine(NULL, x0, oy + y0, x1, oy + y0, gColorBlue);
 +#else /* USE_GRAPH2 */
 +    ZamaDrawLine(x0, oy + y0, x1, oy + y0, Blue);
 +#endif /* USE_GRAPH2 */
 +      ++y0;
 +    }
 +    for (j = 0 ; rep[j] != 0xffff ; j++) {
 +#ifdef USE_GRAPH2
 +      c  = z->object[i++];
 +      if (c == gColorRed) {
 +        c = gColorDarkRed;
 +      }
 +#else /* USE_GRAPH2 */
 +      c  = z->object[i++];
 +      if (c == Red) {
 +        c = DarkRed;
 +      }
 +#endif /* USE_GRAPH2 */
 +      x0 = z->object[i++];
 +      y0 = z->object[i++];
 +      for (k = 0 ; k <= rep[j] + 1 ; k++) {
 +        x1 = z->object[i++];
 +        y1 = z->object[i++];
 +#ifdef USE_GRAPH2
 +        GDrawLine(NULL, x0, oy + y0, x1, oy + y1, c);
 +#else /* USE_GRAPH2 */
 +        ZamaDrawLine(x0, oy + y0, x1, oy + y1, c);
 +#endif /* USE_GRAPH2 */
 +        x0 = x1;
 +        y0 = y1;
 +      }
 +      x0 = z->object[i++];
 +      y0 = z->object[i++];
 +      WinPushDrawState();
 +#ifdef USE_GRAPH2
 +      GPaint(&r, x0, oy + y0, c, c);
 +#else /* USE_GRAPH2 */
 +      ZamaPaint(&r, x0, oy + y0, c, c);
 +#endif /* USE_GRAPH2 */
 +      WinPopDrawState();
 +    }
 +    x0 = z->object[i++];
 +    y0 = z->object[i++];
 +#ifdef USE_GRAPH2
 +    GPaint(&r, x0, oy + y0, c, c);
 +#else /* USE_GRAPH2 */
 +    ZamaPaint(&r, x0, oy + y0, c, c);
 +#endif /* USE_GRAPH2 */
 +    for (j = 120 ; j < 124 ; j++) {
 +#ifdef USE_GRAPH2
 +      GDrawLine(NULL, j, oy + 64, j + 8, oy + 110, gColorYellow);
 +      GDrawLine(NULL, j + 9, oy + 110, j + 11, oy + 126, gColorWhite);
 +#else /* USE_GRAPH2 */
 +      ZamaDrawLine(j, oy + 64, j + 8, oy + 110, Yellow);
 +      ZamaDrawLine(j + 9, oy + 110, j + 11, oy + 126, White);
 +#endif /* USE_GRAPH2 */
 +    }
 +#ifdef USE_GRAPH2
 +    GDrawLine(NULL, 125, oy + 111, 133, oy + 109, gColorRed);
 +    GDrawLine(NULL, 133, oy + 109, 134, oy + 110, gColorRed);
 +    GDrawLine(NULL, 134, oy + 110, 125, oy + 112, gColorRed);
 +    GDrawLine(NULL, 125, oy + 112, 125, oy + 111, gColorRed);
 +    GDrawLine(NULL, 120, oy +  65, 123, oy +  64, gColorWhite);
 +    GDrawLine(NULL, 123, oy +  64, 121, oy +  62, gColorWhite);
 +    GDrawLine(NULL, 121, oy +  62, 120, oy +  65, gColorWhite);
 +    GPaint(&r, 122,oy +  63, gColorWhite, gColorWhite);
 +#else /* USE_GRAPH2 */
 +    ZamaDrawLine(125, oy + 111, 133, oy + 109, Red);
 +    ZamaDrawLine(133, oy + 109, 134, oy + 110, Red);
 +    ZamaDrawLine(134, oy + 110, 125, oy + 112, Red);
 +    ZamaDrawLine(125, oy + 112, 125, oy + 111, Red);
 +    ZamaDrawLine(120, oy +  65, 123, oy +  64, White);
 +    ZamaDrawLine(123, oy +  64, 121, oy +  62, White);
 +    ZamaDrawLine(121, oy +  62, 120, oy +  65, White);
 +    ZamaPaint(&r, 122,oy +  63, White, White);
 +#endif /* USE_GRAPH2 */
 +    for (k = 0 ; rep2[k + 1] != 0 ; k += 2) {
 +      for (j = 0, x0 = rep2[k] ; j < rep2[k + 1] ; j += 2) {
 +        y0 = z->object[i++];
 +        y1 = z->object[i++];
 +#ifdef USE_GRAPH2
 +        GDrawLine(NULL, x0, oy + y0, x0, oy + y1, gColorMagenta); ++x0;
 +        GDrawLine(NULL, x0, oy + y0, x0, oy + y1, gColorYellow);  ++x0;
 +#else /* USE_GRAPH2 */
 +        ZamaDrawLine(x0, oy + y0, x0, oy + y1, Magenta); ++x0;
 +        ZamaDrawLine(x0, oy + y0, x0, oy + y1, Yellow);  ++x0;
 +#endif /* USE_GRAPH2 */
 +        y0 = z->object[i++];
 +        y1 = z->object[i++];
 +#ifdef USE_GRAPH2
 +        GDrawLine(NULL, x0, oy + y0, x0, oy + y1, gColorWhite);   ++x0;
 +#else /* USE_GRAPH2 */
 +        ZamaDrawLine(x0, oy + y0, x0, oy + y1, White);   ++x0;
 +#endif /* USE_GRAPH2 */
 +      }
 +    }
 +
 +#ifdef USE_GRAPH2
 +    RctSetRectangle(&wr, 149, oy + 78, 16, 6);
 +    GDrawRectangle(&wr, gColorBlack);
 +    RctSetRectangle(&wr, 150, oy + 79, 14, 4);
 +    GDrawRectangle(&wr, gColorWhite);
 +    RctSetRectangle(&wr, 156, oy + 78,  2, 6);
 +    GDrawRectangle(&wr, gColorBlack);
 +#else /* USE_GRAPH2 */
 +    RctSetRectangle(&wr, 149, oy + 78, 16, 6);
 +    ZamaDrawRectangle(&wr, Black);
 +    RctSetRectangle(&wr, 150, oy + 79, 14, 4);
 +    ZamaDrawRectangle(&wr, White);
 +    RctSetRectangle(&wr, 156, oy + 78,  2, 6);
 +    ZamaDrawRectangle(&wr, Black);
 +#endif /* USE_GRAPH2 */
 +
 +    for (;;) {
 +      x1 = z->object[i++];
 +      y1 = z->object[i++];
 +      if (y1 == 0xff) {
 +        if (x1 == 0xff) {
 +          break;
 +        }
 +        x0 = z->object[i++];
 +        y0 = z->object[i++];
 +        continue;
 +      }
 +
 +#ifdef USE_GRAPH2
 +      GDrawLine(NULL, x0, oy + y0, x1, oy + y1, gColorBlack);
 +#else /* USE_GRAPH2 */
 +      ZamaDrawLine(x0, oy + y0, x1, oy + y1, Black);
 +#endif /* USE_GRAPH2 */
 +      x0 = x1;
 +      y0 = y1;
 +    }
 +  }
 +}
 +
 +static
 +void
 +CleanMap(
 +#ifdef USE_GRAPH2
 +         GColorName c_
 +#else /* USE_GRAPH2 */
 +         ZamaColorName c_
 +#endif /* USE_GRAPH2 */
 +)
 +{
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +#ifdef USE_GRAPH2
 +  GDrawRectangle(&z->pict, c_);
 +#else /* USE_GRAPH2 */
 +  ZamaDrawRectangle(&z->pict, c_);
 +#endif /* USE_GRAPH2 */
 +}
 +
 +static
 +void
 +DrawMap(Boolean putMesg_)
 +{
 +  UInt16        i = 0;
 +  Coord         x0, y0;
 +  UInt8         c;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  WinPushDrawState();
 +  i += z->map.graphic[i] * 3 + 1; /* skip HALF paint pattern */
 +
 +  if (z->_startup == 0) {
 +    if (z->user.sys.n.mapID == 85 || z->user.sys.n.mapID == 84) {
 +      /* never draw */
 +#ifdef USE_GRAPH2
 +      CleanMap(gColorBlack);
 +#else /* USE_GRAPH2 */
 +      CleanMap(Black);
 +#endif /* USE_GRAPH2 */
 +      DrawMessage(0xcc, 0, 0);
 +      goto _done;
 +    }
 +  }
 +
 +#ifdef USE_GRAPH2
 +  CleanMap(gColorBlue);
 +  /* draw outline */
 +  i += WinDrawOutline(&z->pict, &z->map.graphic[i], gColorWhite);
 +#else /* USE_GRAPH2 */
 +  CleanMap(Blue);
 +  /* draw outline */
 +  i += WinDrawOutline(&z->pict, &z->map.graphic[i], White);
 +#endif /* USE_GRAPH2 */
 +  /* paint */
 +  x0 = z->map.graphic[i++];
 +  y0 = z->map.graphic[i++];
 +  while (x0 != 0xff || y0 != 0xff) {
 +    c = z->map.graphic[i++];
 +#ifdef USE_GRAPH2
 +    GPaint(&z->pict, x0, y0, c, gColorWhite);
 +#else /* USE_GRAPH2 */
 +    ZamaPaint(&z->pict, x0, y0, c, White);
 +#endif /* USE_GRAPH2 */
 +    x0 = z->map.graphic[i++];
 +    y0 = z->map.graphic[i++];
 +  }
 +  if (z->map.graphic[i] == 0xff && z->map.graphic[i + 1] == 0xff) {
 +    i += 2;
 +  } else {
 +#ifdef USE_GRAPH2
 +    i += WinDrawOutline(&z->pict, &z->map.graphic[i], gColorWhite);
 +#else /* USE_GRAPH2 */
 +    i += WinDrawOutline(&z->pict, &z->map.graphic[i], White);
 +#endif /* USE_GRAPH2 */
 +  }
 +  if (z->map.graphic[i] == 0xff && z->map.graphic[i + 1] == 0xff) {
 +    i += 2;
 +  } else {
 +#ifdef USE_GRAPH2
 +    i += WinDrawOutline(&z->pict, &z->map.graphic[i], gColorBlack);
 +#else /* USE_GRAPH2 */
 +    i += WinDrawOutline(&z->pict, &z->map.graphic[i], Black);
 +#endif /* USE_GRAPH2 */
 +  }
 +  if (z->map.graphic[0]) {
 +#ifdef USE_GRAPH2
 +    GChromakeyPaint(&z->pict, &z->map.graphic[0], z->prefs._linedraw);
 +#else /* USE_GRAPH2 */
 +    ZamaChromakeyPaint(&z->pict, &z->map.graphic[0], z->prefs._linedraw);
 +#endif /* USE_GRAPH2 */
 +  }
 +  /* put message #0 */
 +  if (putMesg_) DrawMessage(1, 0, 0);
 + _done:;
 +  WinPopDrawState();
 +}
 +
 +static
 +void
 +GameInit(void)
 +{
 +  FormPtr    formP;
 +  ControlPtr btnP, chkP;
 +  FieldPtr   fldP;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  z->user.sys.n.mapID = 76;
 +  switch (z->_startup) {
 +  case ZAMA_CODE_ISAKO: z->user.sys.n.mapID = 84; break;
 +  default: break;
 +  }
 +
 +  formP = FrmGetActiveForm();
 +  btnP  = GetObjectPtr(ZAMA_BUTTON_START);
 +  fldP  = GetObjectPtr(ZAMA_COMMAND_FIELD);
 +  chkP  = GetObjectPtr(ZAMA_CONTINUE);
 +
 +  FldEraseField(fldP);
 +  FldSetUsable(fldP, false);
 +  CtlSetUsable(btnP, true);
 +  CtlShowControl(btnP);
 +  CtlSetUsable(chkP, z->prefs._suspended);
 +  CtlSetValue(chkP, z->prefs._suspended);
 +  if (z->prefs._suspended) {
 +    CtlShowControl(chkP);
 +  }
 +
 +  FrmDrawForm(formP);
 +  CleanMessageField();
 +  LoadMapData(z->user.sys.n.mapID);
 +  DrawMap(false);
 +  PutMessageToField("�n�C�n�C�X�N�[���E�A�h�x���`���[", 52);
 +  PutMessageToField("   Copyright (c) 1985 ZOBplus   ", 52);
 +  PutMessageToField(" Copyright (c) 2002-2025 ZOBplus hiro", 52);
 +  z->_startup = 0; /* reset */
 +  z->_over = true; /* not yet started */
 +}
 +
 +static
 +void
 +GameOver(void)
 +{
 +  FormPtr    formP;
 +  ControlPtr btnP, chkP;
 +  FieldPtr   fldP;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  formP = FrmGetActiveForm();
 +  btnP  = GetObjectPtr(ZAMA_BUTTON_START);
 +  fldP  = GetObjectPtr(ZAMA_COMMAND_FIELD);
 +  chkP  = GetObjectPtr(ZAMA_CONTINUE);
 +
 +  z->prefs._suspended = false;
 +
 +  FldEraseField(fldP);
 +  FldSetUsable(fldP, false);
 +  CtlSetUsable(btnP, true);
 +  CtlShowControl(btnP);
 +  CtlSetUsable(chkP, false);
 +  CtlSetValue(chkP, false);
 +
 +  z->_over = true;
 +}
 +
 +inline UInt8
 +getCond(UInt16 type_, UInt16 id_, UInt16 offset_)
 +{
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +  UInt8 value;
 +  switch (type_) {
 +  case 0: value = 0; break;
 +  case 1: value = z->user.fact[id_]; break;
 +  case 2: value = z->user.place[id_]; break;
 +  case 3: value = z->user.sys.ary[id_]; break;
 +  case 4: value = z->user.vector[offset_ - 1][id_]; break;
 +  case 5:
 +  case 6:
 +  case 7:
 +  default: value = 0; break;
 +  }
 +  return value;
 +}
 +
 +inline void
 +setStat(UInt16 type_, UInt16 id_, UInt16 offset_, UInt8 value_)
 +{
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +  switch (type_) {
 +  case 0: break;
 +  case 1: z->user.fact[id_]   = value_; break;
 +  case 2: z->user.place[id_]  = value_; break;
 +  case 3: z->user.sys.ary[id_] = value_; break;
 +  case 4: z->user.vector[offset_ - 1][id_] = value_; break;
 +  case 5:
 +  case 6:
 +  case 7:
 +  default: break;
 +  }
 +}
 +
 +static Boolean SexHandleEvent(EventPtr);
 +static Boolean FileHandleEvent(EventPtr);
 +static Boolean InvHandleEvent(EventPtr);
 +static Boolean CutHandleEvent(EventPtr);
 +
 +static
 +Boolean
 +DialogHandler(UInt16 id_)
 +{
 +  FormPtr       formP;
 +  UInt16        ret;
 +  Boolean       redraw = false;
 +  ControlPtr    chkP;
 +  Coord         x, y;
 +  RectangleType bounds;
 +  WinHandle     hWin;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  do {
 +    formP = FrmInitForm(id_);
 +    if (z->_silkr) {
 +      if (z->_silkVer < 0x02) {
 +        SilkLibDisableResize(z->_silkr);
 +      } else {
 +        VskSetState(z->_silkr, vskStateEnable, 0);
 +      }
 +      WinGetDisplayExtent(&x, &y);
 +      if (y > 160) {
 +        hWin = FrmGetWindowHandle(formP);
 +        WinGetBounds(hWin, &bounds);
 +        bounds.topLeft.y += stdSilkHeight;
 +        WinSetBounds(hWin, &bounds);
 +      }
 +    }
 +    switch(id_) {
 +    case ZAMA_SEX_FORM:
 +       FrmSetEventHandler(formP, SexHandleEvent);
 +      break;
 +    case ZAMA_FILE_FORM:
 +      FrmSetEventHandler(formP, FileHandleEvent);
 +      if (z->prefs._lastSaved) {
 +        ret  = FrmGetObjectIndex(formP, ZAMA_FILE_ID1 - 1 + z->prefs._lastSaved);
 +        chkP = FrmGetObjectPtr(formP, ret);
 +        CtlSetValue(chkP, true);
 +      }
 +      FrmDrawForm(formP);
 +      break;
 +    case ZAMA_INV_FORM:
 +      FrmSetEventHandler(formP, InvHandleEvent);
 +      FrmEraseForm(formP);
 +      for (ret = 0 ; ret < ZAMA_ITEM_NUMBERS ; ret++) {
 +        if (z->user.place[ret] == 0xff) {
 +          FrmShowObject(formP, FrmGetObjectIndex(formP, ZAMA_INV_BASE + ret));
 +        } else {
 +          FrmHideObject(formP, FrmGetObjectIndex(formP, ZAMA_INV_BASE + ret));
 +        }
 +      }
 +      FrmDrawForm(formP);
 +      break;
 +    case ZAMA_CUT_FORM:
 +      FrmSetEventHandler(formP, CutHandleEvent);
 +      break;
 +    }
 +    z->user.sys.n.dlogOk = false;
 +    z->user.sys.n.dmesg  = 0;
 +    ret = FrmDoDialog(formP);
 +    if (z->user.sys.n.dmesg) {
 +      CleanMessageField();
 +      DrawMessage(user.sys.n.dmesg, 0, 0);
 +    }
 +    FrmDeleteForm(formP);
 +    if (z->_silkr) {
 +      if (z->_silkVer < 0x02) {
 +        SilkLibEnableResize(z->_silkr);
 +      } else {
 +        VskSetState(z->_silkr, vskStateEnable, 1);
 +      }
 +    }
 +  } while (!z->user.sys.n.dlogOk);
 +  if (z->user.sys.n.dmesg == 0) {
 +    CleanMessageField();
 +  }
 +  switch (id_) {
 +  case ZAMA_SEX_FORM:
 +    z->user.sys.n.mapID = 3; /* enter to the room */
 +    redraw = true;
 +    break;
 +  case ZAMA_FILE_FORM:
 +    if (z->user.sys.n.dret) {
 +      if (z->user.sys.n.cmdN == 0xf) {
 +        SaveGame(z->user.sys.n.dret);
 +      } else {
 +        redraw = LoadGame(z->user.sys.n.dret);
 +        if (redraw) {
 +#ifdef USE_GRAPH2
 +          GPaletteChange(gColorInvalid); /* initialize palette */
 +#else /* USE_GRAPH2 */
 +          ZamaPaletteChange(InvalidColor); /* initialize palette */
 +#endif /* USE_GRAPH2 */
 +        }
 +      }
 +    }
 +    break;
 +  case ZAMA_INV_FORM: /* restore message field */
 +#ifdef USE_GRAPH2
 +    if (z->tsPatch) {
 +      FldDrawField(GetObjectPtr(ZAMA_MESSAGE_FIELD));
 +    } else {
 +      GFldDrawField(GetObjectPtr(ZAMA_MESSAGE_FIELD));
 +    }
 +#else /* USE_GRAPH2 */
 +    ZamaFldDrawField(GetObjectPtr(ZAMA_MESSAGE_FIELD));
 +#endif /* USE_GRAPH2 */
 +    break;
 +  case ZAMA_CUT_FORM: /* cut red or yellow */
 +    if (z->user.sys.n.dret == 0 || z->user.place[11] != 0xff) { /* fail */
 +      if (z->user.place[11] != 0xff) { /* no pinces */
 +        DrawMessage(0xe0, 0, 0);
 +      }
 +      /* color change to red */
 +#ifdef USE_GRAPH2
 +      GPaletteChange(gColorRed);
 +#else /* USE_GRAPH2 */
 +      ZamaPaletteChange(Red);
 +#endif /* USE_GRAPH2 */
 +      DrawMessage(0xc7, 0, 0);
 +      GameOver();
 +    } else {
 +      /* correctly choosen */
 +      z->user.place[11] = 0;
 +      z->user.sys.n.mapID = 74;
 +      ZamaSndPlay(3);
 +      redraw = true;
 +    }
 +    break;
 +  }
 +  return redraw;
 +}
 +
 +static
 +Boolean
 +DarknessCheck(void)
 +{
 +  Boolean redraw = false;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +  if (z->user.sys.n.mapID != 84 && z->user.sys.n.mapID != 85) {
 +    if ((z->user.sys.n.mapID >= 47 && z->user.sys.n.mapID <= 49)||
 +        (z->user.sys.n.mapID >= 67 && z->user.sys.n.mapID <= 71)||
 +         z->user.sys.n.mapID == 61 || z->user.sys.n.mapID == 64 ||
 +         z->user.sys.n.mapID == 75 || z->user.sys.n.mapID == 65 ||
 +         z->user.sys.n.mapID == 74 || z->user.sys.n.mapID == 77) {
 +      if (z->user.fact[7] != 0) {
 +        if (z->user.fact[6] != 0) {
 +          /* semi-blue out */
 +#ifdef USE_GRAPH2
 +          GPaletteChange(gColorBlue);
 +#else /* USE_GRAPH2 */
 +          ZamaPaletteChange(Blue);
 +#endif /* USE_GRAPH2 */
 +        }
 +      } else {
 +        z->user.sys.n.mapW  = z->user.sys.n.mapID;
 +        z->user.sys.n.mapID = 84;
 +        redraw = true;
 +      }
 +    } else {
 +      if (z->user.fact[6] != 0) {
 +        /* normal state */
 +#ifdef USE_GRAPH2
 +        GPaletteChange(gColorInvalid);
 +#else /* USE_GRAPH2 */
 +        ZamaPaletteChange(InvalidColor);
 +#endif /* USE_GRAPH2 */
 +      }
 +    }
 +  }
 +  return redraw;
 +}
 +
 +static
 +Boolean
 +RuleInterpreter(UInt16 cmdN_, UInt16 objN_)
 +{
 +  Boolean    res, ok, redraw;
 +  UInt16     i;
 +  RulePtr    rule;
 +  CmdBlkPtr  blk;
 +  UInt16     v1, v2;
 +  DmOpenRef  dbP;
 +  MemHandle  rec;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  res = false;
 +  if ((dbP = OpenDatabase("ZAMArule")) == NULL) {
 +    /* error */
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "���[��", NULL, NULL);
 +    return false;
 +  }
 +  if ((rec = DmQueryRecord(dbP, 0)) == NULL) {
 +    FrmCustomAlert(ZAMA_FATAL_ALERT, "���[��", NULL, NULL);
 +    goto _done;
 +  }
 +  rule = (RulePtr)MemHandleLock(rec);
 +
 +  for (i = 0 ; rule[i]._mapId != EndOfRule ; i++) {
 +    if (rule[i]._mapId && rule[i]._mapId != z->user.sys.n.mapID) continue;
 +    if (rule[i]._cmdN  && rule[i]._cmdN  != cmdN_)            continue;
 +    if (rule[i]._objN  && rule[i]._objN  != objN_)            continue;
 +    /* check condition block */
 +    ok = true;
 +    for (blk = (CmdBlkPtr)rule[i]._args ; blk->_head._act == ActComp ; blk++) {
 +      v1 = getCond(blk->_head._type, blk->_head._id,
 +                   (blk->_body._type << 5) | blk->_body._id);
 +      if (blk->_head._type == TYPE_SYSTEM && blk->_head._id == 5) {
 +        z->user.sys.n.rand = SysRandom(0) % 256; /* update random number */
 +      }
 +      v2 = blk->_body._value;
 +      if (blk->_body._type && blk->_head._type != TYPE_VECTOR) {
 +        v2 = getCond(blk->_body._type, blk->_body._id, 0);
 +        if (blk->_body._type == TYPE_SYSTEM && blk->_body._id == 5) {
 +          z->user.sys.n.rand = SysRandom(0) % 256; /* update random number */
 +        }
 +      }
 +      switch (blk->_head._op) {
 +      case CMP_EQ: ok = ok && (v1 == v2); break;
 +      case CMP_NE: ok = ok && (v1 != v2); break;
 +      case CMP_GT: ok = ok && (v1 >  v2); break;
 +      case CMP_GE: ok = ok && (v1 >= v2); break;
 +      case CMP_LT: ok = ok && (v1 <  v2); break;
 +      case CMP_LE: ok = ok && (v1 <= v2); break;
 +      default:
 +        ok = false; /* no defalut operation is defined */
 +      }
 +      if (!ok) break; /* short circuit */
 +    }
 +    if (ok) break;
 +  }
 +  if (ok) {
 +    /* do action */
 +    redraw = false;
 +    ok  = false;
 +    for ( ; blk->_head._op ; blk++) {
 +      switch (blk->_head._op) {
 +      case ACT_MOVE:
 +        if (z->user.vector[z->user.sys.n.mapID - 1][blk->_body._value]) {
 +          /* moveable */
 +          z->user.sys.n.mapID =
 +            z->user.vector[z->user.sys.n.mapID - 1][blk->_body._value];
 +          redraw = true;
 +          res = true;
 +        } else {
 +          /* teacher check */
 +          if (z->user.fact[1] == z->user.sys.n.mapID && z->user.sys.n.rand > 85) {
 +            /* teacher catches you */
 +            DrawMessage(0xb5, 0, 0);
 +            /* game over */
 +            z->user.fact[1] = 0; /* teacher gone */
 +            GameOver();
 +            res = true;
 +          } else {
 +            /* you cannot move */
 +            DrawMessage(0xb6, 0, 0);
 +          }
 +          z->user.sys.n.rand = SysRandom(0) % 256;
 +          res = true;
 +        }
 +        break;
 +      case ACT_ASGN:
 +        v1 = (blk->_body._type << 5) | blk->_body._id;
 +        v2 = blk->_body._value;
 +        if (blk->_body._type && blk->_head._type != TYPE_VECTOR) {
 +          v2 = getCond(blk->_body._type, blk->_body._id, 0);
 +        }
 +        setStat(blk->_head._type, blk->_head._id, v1, v2);
 +        if (blk->_head._type == TYPE_PLACE || blk->_head._type == TYPE_FACT) {
 +          if (blk->_head._type == TYPE_PLACE) {
 +            if (v2 == 0xff) {
 +              redraw = true;
 +            } else {
 +              ObjectCheck(z->user.sys.n.mapID, true);
 +            }
 +          }
 +          ok = true;
 +        } else if(blk->_head._type == TYPE_SYSTEM) {
 +          if (blk->_head._id == 0) {
 +            redraw = true;
 +          } else if (blk->_head._id == 5) {
 +            z->user.sys.n.rand = SysRandom(0) % 256; /* update random number */
 +          }
 +        }
 +        res = true;
 +        break;
 +      case ACT_MESG:
 +        DrawMessage(blk->_body._value, 0, 0);
 +        res = true;
 +        break;
 +      case ACT_DLOG:
 +        redraw = DialogHandler(ZAMA_DIALOG_BASE + blk->_body._value);
 +        res = true;
 +        break;
 +      case ACT_LOOK:
 +        if (blk->_body._value == 0) { /* look back */
 +          z->user.sys.n.mapID = z->user.sys.n.mapW;
 +          z->user.sys.n.mapW  = 0;
 +        } else {
 +          z->user.sys.n.mapW  = z->user.sys.n.mapID;
 +          z->user.sys.n.mapID = blk->_body._value;
 +        }
 +        redraw = true;
 +        res = true;
 +        break;
 +      case ACT_SND:
 +        ZamaSndPlay(blk->_body._value);
 +        break;
 +      case ACT_OVER:
 +        ok = false;
 +        switch(blk->_body._value) {
 +        case 0: /* simply put dialog */
 +          z->user.fact[1] = 0; /* teacher gone */
 +          PutMessageToField("�f�������n������", 16);
 +          break;
 +        case 1: /* screen to red */
 +          PutMessageToField("�f�������n������", 16);
 +#ifdef USE_GRAPH2
 +          GPaletteChange(gColorRed);
 +#else /* USE_GRAPH2 */
 +          ZamaPaletteChange(Red);
 +#endif /* USE_GRAPH2 */
 +          break;
 +        case 2: /* game clear */
 +          PutMessageToField("�e����������", 12);
 +#ifdef USE_GRAPH2
 +          GPaletteChange(gColorInvalid);
 +#else /* USE_GRAPH2 */
 +          ZamaPaletteChange(InvalidColor);
 +#endif /* USE_GRAPH2 */
 +          FrmHelp(ZAMA_CREDIT_STR); /* put credit */
 +          break;
 +        }
 +        GameOver();
 +        res = true;
 +        break;
 +      default:
 +        /* error */
 +        res = false;
 +        break;
 +      }
 +    }
 +    if (ok) {
 +      PutMessageToField("�n.�j.", 6);
 +    }
 +    if (z->user.sys.n.mapID == 74) {
 +      switch (++z->user.fact[13]) {
 +      case 4:   DrawMessage(0xe2, 0, 0); break;
 +      case 6:   DrawMessage(0xe3, 0, 0); break;
 +      case 10:  DrawMessage(0xe4, 0, 0); break;
 +      default:  break;
 +      }
 +    }
 +    redraw = DarknessCheck() || redraw;
 +    if (redraw) {
 +      LoadMapData(z->user.sys.n.mapID);
 +      DrawMap(true);
 +      ObjectCheck(z->user.sys.n.mapID, true);
 +    }
 +  }
 +  MemHandleUnlock(rec);
 + _done:;
 +  DmCloseDatabase(dbP);
 +  return res;
 +}
 +
 +static
 +Boolean
 +CommandLoop(void)
 +{
 +  MemHandle     hStr;
 +  Char         *strP;
 +  UInt16        end, rd;
 +  FieldPtr      fldP;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  if ((hStr = FldGetTextHandle(GetObjectPtr(ZAMA_COMMAND_FIELD))) == NULL) {
 +    /* fail to get string */
 +    return false;
 +  }
 +  strP = (Char*)MemHandleLock(hStr);
 +  end  = StrLen(strP);
 +  VOSplit(strP);
 +  CleanMessageField();
 +
 +  z->user.sys.n.cmdN = SearchWord(z->cmd, true);
 +  z->user.sys.n.objN = SearchWord(z->obj, false);
 +  z->user.sys.n.rand = SysRandom(0) % 256;
 +
 +  /* status check */
 +  if (z->user.fact[5] == 2) {
 +    z->user.vector[ 9 - 1][6] = 4;
 +    z->user.vector[10 - 1][6] = 19;
 +    z->user.vector[11 - 1][6] = 6;
 +    z->user.vector[14 - 1][6] = 7;
 +    z->user.vector[16 - 1][6] = 17;
 +    z->user.vector[24 - 1][6] = 8;
 +    z->user.vector[25 - 1][6] = 20;
 +    z->user.vector[26 - 1][6] = 22;
 +    z->user.vector[28 - 1][6] = 21;
 +    z->user.vector[30 - 1][6] = 5;
 +    z->user.vector[37 - 1][6] = 32;
 +    z->user.vector[38 - 1][6] = 33;
 +    z->user.vector[39 - 1][6] = 34;
 +    z->user.vector[40 - 1][6] = 31;
 +    z->user.vector[42 - 1][6] = 35;
 +    z->user.vector[44 - 1][6] = 36;
 +    z->user.fact[5] = 1;
 +  }
 +  if (z->user.fact[3] > 0 && z->user.fact[7] == 1) { /* light on */
 +    --z->user.fact[3]; /* battery */
 +    if (z->user.fact[3] < 8 && z->user.fact[3] > 0) {
 +      z->user.fact[6] = 1;
 +      DrawMessage(0xd9, 0, 0);
 +    }
 +    if (z->user.fact[3] == 0) { /* battery wear out */
 +      z->user.fact[7] = 0;
 +      DrawMessage(0xc0, 0, 0);
 +    }
 +  }
 +  if (z->user.fact[11] > 0) { /* count down */
 +    --z->user.fact[11];
 +    if (z->user.fact[11] == 0) {
 +      ZamaSndPlay(2);
 +      DrawMessage(0xd8, 0, 0);
 +      if (z->user.place[7] == 48) {
 +        z->user.vector[75 - 1][0] = 77;
 +        z->user.vector[68 - 1][2] = 77;
 +        DrawMessage(0xda, 0, 0);
 +      }
 +      if (z->user.place[7] == 255 || z->user.place[7] == z->user.sys.n.mapID) {
 +        /* explosion within the room where you are */
 +        /* change screen to red */
 +#ifdef USE_GRAPH2
 +        GPaletteChange(gColorRed);
 +#else /* USE_GRAPH2 */
 +        ZamaPaletteChange(Red);
 +#endif /* USE_GRAPH2 */
 +        DrawMessage(0xcf, 0, 0);
 +        DrawMessage(0xcb, 0, 0);
 +        /* game over */
 +        GameOver();
 +        goto _done;
 +      } else {
 +        z->user.place[7] = 0; /* explosion ... lose bomber */
 +      }
 +    }
 +  }
 +
 +  if (z->user.sys.n.cmdN == ZAMA_CMD_INVALID || z->user.sys.n.cmdN >= ZAMA_CMD_END) {
 +    DrawMessage(0xaf + z->user.sys.n.rand % 5, 0, 0);
 +    goto _done;
 +  }
 +  if (! RuleInterpreter(z->user.sys.n.cmdN, z->user.sys.n.objN)) {
 +    DrawMessage(0, z->user.sys.n.cmdN, z->user.sys.n.objN);
 +  }
 +
 +  /* teacher check */
 +  if (!z->_over) {
 +    rd = 100 + z->user.sys.n.mapID + ((z->user.fact[1] > 0) ? 1000 : 0);
 +    if (rd < SysRandom(0) % 3000) {
 +      if (z->user.fact[1] == z->user.sys.n.mapID) {
 +        DrawMap(false); /* erase teacher */
 +      }
 +      z->user.fact[1] = 0;
 +    } else {
 +      z->user.fact[1] = z->user.sys.n.mapID; /* appear teacher */
 +    }
 +  }
 +  if ((z->user.sys.n.mapID >= 50 && z->user.sys.n.mapID <= 53) ||
 +      (z->user.sys.n.mapID >= 64 && z->user.sys.n.mapID <= 77) ||
 +       z->user.sys.n.mapID == 83 || z->user.sys.n.mapID == 48 ||
 +       z->user.sys.n.mapID == 61 || z->user.sys.n.mapID == 1 ||
 +       z->user.sys.n.mapID == 86) {
 +    z->user.fact[1] = 0;
 +  }
 +  if (z->user.fact[1] == z->user.sys.n.mapID) {
 +    DrawTeacher();
 +    ZamaSndPlay(6);
 +    DrawMessage(0xb4, 0, 0);
 +  }
 + _done:;
 +  MemHandleUnlock(hStr);
 +  fldP = GetObjectPtr(ZAMA_COMMAND_FIELD);
 +  FldDelete(fldP, 0, end);
 +  FldDrawField(fldP);
 +  return true;
 +}
 +
 +static
 +Boolean
 +MainMenuEvent(EventPtr eventP)
 +{
 +  Boolean       handled = false;
 +  FormPtr       dlogP;
 +  FontID        id;
 +  UInt16        lines, plane, sound;
 +  Coord         x, y;
 +  FieldPtr      fldP;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  fldP = GetObjectPtr(ZAMA_COMMAND_FIELD);
 +  switch (eventP->data.menu.itemID) {
 +  case ZAMA_FONT_MENU:
 +    /* menu select */
 +#ifdef USE_GRAPH2
 +    id = ZamaFontSelect(prefs._curFont);
 +#else /* USE_GRAPH2 */
 +    id = ZamaFontSelect(prefs._curFont);
 +#endif /* USE_GRAPH2 */
 +    if (z->prefs._curFont != id) {
 +      z->prefs._curFont = id;
 +      fldP = GetObjectPtr(ZAMA_MESSAGE_FIELD);
 +      FldSetFont(fldP, id);
 +#ifdef USE_GRAPH2
 +      if (tsPatch) {
 +        FldDrawField(fldP);
 +      } else {
 +        GFldDrawField(fldP);
 +      }
 +#else /* USE_GRAPH2 */
 +      ZamaFldDrawField(fldP);
 +#endif /* USE_GRAPH2 */
 +      UpdateMessageFieldScrollbar();
 +    }
 +    handled = true;
 +    break;
 +  case ZAMA_PREF_MENU:
 +    /* pop-up prefs dialog */
 +    dlogP = FrmInitForm(ZAMA_PREF_FORM);
 +    lines = FrmGetObjectIndex(dlogP, ZAMA_DRAW_LINE);
 +    plane = FrmGetObjectIndex(dlogP, ZAMA_DRAW_PLANE);
 +    /* sound */
 +    sound = FrmGetObjectIndex(dlogP, ZAMA_SND_SWITCH);
 +    if (z->_silkr){
 +      WinGetDisplayExtent(&x, &y);
 +      if (y > 160) {
 +        RectangleType bounds;
 +        WinHandle     hWin;
 +        hWin = FrmGetWindowHandle(dlogP);
 +        WinGetBounds(hWin, &bounds);
 +        bounds.topLeft.y += stdSilkHeight;
 +        WinSetBounds(hWin, &bounds);
 +      }
 +    }
 +#ifndef USE_GRAPH2
 +    if (!ZamaHR()) {
 +      /* not support line draw mode */
 +      CtlSetUsable(FrmGetObjectPtr(dlogP, lines), false);
 +      z->prefs._linedraw = false;
 +    }
 +#endif /* USE_GRAPH2 */
 +    CtlSetValue(FrmGetObjectPtr(dlogP, lines), z->prefs._linedraw);
 +    CtlSetValue(FrmGetObjectPtr(dlogP, plane), !z->prefs._linedraw);
 +    CtlSetValue(FrmGetObjectPtr(dlogP, sound), z->prefs._sound);
 +    if (FrmDoDialog(dlogP) == ZAMA_BUTTON_OK) {
 +      /* change status */
 +#ifndef USE_GRAPH2
 +      if (ZamaHR()) {
 +#endif /* USE_GRAPH2 */
 +        z->prefs._linedraw =
 +            (FrmGetControlGroupSelection(dlogP, ZAMA_DRAW_STYLE) == lines);
 +#ifndef USE_GRAPH2
 +      }
 +#endif /* USE_GRAPH2 */
 +      z->prefs._sound = CtlGetValue(FrmGetObjectPtr(dlogP, sound));
 +    }
 +    FrmDeleteForm(dlogP);
 +    handled = true;
 +    break;
 +  case ZAMA_HELP_CMD:
 +    FrmHelp(ZAMA_HELP_STR);
 +    break;
 +  case ZAMA_ABOUT_CMD:
 +    dlogP = FrmInitForm(ZAMA_FRM_ABOUT);
 +    FrmDoDialog(dlogP);
 +    FrmDeleteForm(dlogP);
 +    break;
 +  }
 +  return handled;
 +}
 +
 +static
 +Boolean
 +MainHeightChanged(EventPtr eventP)
 +{
 +  RectangleType bounds;
 +  FormPtr       formP;
 +  WinHandle     hWin;
 +  Int16         dy;
 +  Coord         nx, ny;
 +  UInt16        i, idx;
 +  FieldPtr      fldP;
 +  Boolean       res = true;
 +  UInt16        objs[] = {
 +    ZAMA_COMMAND_LABEL,
 +    ZAMA_BUTTON_START,
 +    ZAMA_CONTINUE,
 +    0
 +  };
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  formP = FrmGetActiveForm();
 +  hWin  = FrmGetWindowHandle(formP);
 +  WinGetBounds(hWin, &bounds);
 +  WinGetDisplayExtent(&nx, &ny);
 +  if (ny == bounds.topLeft.y + bounds.extent.y) {
 +    /* size has not changed */
 +    return res;
 +  }
 +  bounds.extent.y = ny - bounds.topLeft.y;
 +  bounds.extent.x = nx - bounds.topLeft.x;
 +  FrmEraseForm(formP);
 +  WinSetBounds(hWin, &bounds);
 +  /* relocate object */
 +  dy = (ny == 160) ? -stdSilkHeight : stdSilkHeight;
 +  /* GSI */
 +  for (i = 0 ; i < FrmGetNumberOfObjects(formP) ; i++) {
 +    if (FrmGetObjectType(formP, i) == frmGraffitiStateObj) {
 +      /* found GSI */
 +      FrmGetObjectPosition(formP, i, &nx, &ny);
 +      ny += dy;
 +      FrmSetObjectPosition(formP, i, nx, ny);
 +      break; /* needless to search any more */
 +    }
 +  }
 +  for (i = 0 ; objs[i] ; i++) {
 +    idx = FrmGetObjectIndex(formP, objs[i]);
 +    FrmGetObjectBounds(formP, idx, &bounds);
 +    bounds.topLeft.y += dy;
 +    FrmSetObjectBounds(formP, idx, &bounds);
 +  }
 +  /* move command field */
 +  fldP = FrmGetObjectPtr(formP, FrmGetObjectIndex(formP, ZAMA_COMMAND_FIELD));
 +  FldGetBounds(fldP, &bounds);
 +  bounds.topLeft.y += dy;
 +  FldSetBounds(fldP, &bounds);
 +  FrmSetFocus(formP, FrmGetObjectIndex(formP, ZAMA_COMMAND_FIELD));
 +  FldDrawField(fldP);
 +  /* extent message field */
 +  fldP = FrmGetObjectPtr(formP, FrmGetObjectIndex(formP, ZAMA_MESSAGE_FIELD));
 +  FldGetBounds(fldP, &bounds);
 +  bounds.extent.y += dy * 2;
 +  FldSetBounds(fldP, &bounds);
 +  /* update scrollbar */
 +  idx = FrmGetObjectIndex(formP, ZAMA_SCROLL_BAR);
 +  FrmGetObjectBounds(formP, idx, &bounds);
 +  bounds.extent.y += dy;
 +  FrmSetObjectBounds(formP, idx, &bounds);
 +  /* update */
 +  UpdateMessageFieldScrollbar();
 +  FrmDrawForm(formP);
 +#ifdef USE_GRAPH2
 +  if (tsPatch) {
 +    FldDrawField(fldP);
 +  } else {
 +    GFldDrawField(fldP);
 +  }
 +#else /* USE_GRAPH2 */
 +  ZamaFldDrawField(fldP);
 +#endif /* USE_GRAPH2 */
 +  DrawMap(false);
 +  ObjectCheck(z->user.sys.n.mapID, false);
 +
 +  return res;
 +}
 +
 +static
 +Boolean
 +MainHandleEvent(EventPtr eventP)
 +{
 +  Boolean       handled = false;
 +  FormPtr       formP;
 +  FieldPtr      fldP;
 +  ControlPtr    btnP, chkP;
 +  UInt16        lines;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  formP = FrmGetActiveForm();
 +  /* resize check */
 +  if (z->_silkr && z->_resized && MainHeightChanged(eventP)) {
 +    z->_resized = false;
 +  }
 +  if (eventP->eType == frmOpenEvent) {
 +    GameInit();
 +    handled = true;
 +  } else if (eventP->eType == frmUpdateEvent) {
 +    FrmDrawForm(formP);
 +#ifdef USE_GRAPH2
 +    if (z->tsPatch) {
 +      FldDrawField(GetObjectPtr(ZAMA_MESSAGE_FIELD));
 +    } else {
 +      GFldDrawField(GetObjectPtr(ZAMA_MESSAGE_FIELD));
 +    }
 +#else /* USE_GRAPH2 */
 +    ZamaFldDrawField(GetObjectPtr(ZAMA_MESSAGE_FIELD));
 +#endif /* USE_GRAPH2 */
 +    DrawMap(false); /* maybe re-draw map */
 +    ObjectCheck(z->user.sys.n.mapID, true);
 +    FrmSetFocus(formP, FrmGetObjectIndex(formP, ZAMA_COMMAND_FIELD));
 +    handled = true;
 +  } else if (eventP->eType == ctlSelectEvent) {
 +    switch (eventP->data.ctlSelect.controlID) {
 +    case ZAMA_BUTTON_START:
 +      /* enable command field and disable start button */
 +      btnP = GetObjectPtr(ZAMA_BUTTON_START);
 +      fldP = GetObjectPtr(ZAMA_COMMAND_FIELD);
 +      chkP = GetObjectPtr(ZAMA_CONTINUE);
 +      FrmEraseForm(formP);
 +      CleanMessageField();
 +      CtlSetUsable(btnP, false);
 +      CtlSetUsable(chkP, false);
 +      FldSetUsable(fldP, true);
 +      /* init game */
 +#ifdef USE_GRAPH2
 +      GPaletteChange(gColorInvalid); /* initialize palette */
 +#else /* USE_GRAPH2 */
 +      ZamaPaletteChange(InvalidColor); /* initialize palette */
 +#endif /* USE_GRAPH2 */
 +      if (CtlGetValue(chkP)) { /* load */
 +        LoadGame(0);
 +        DarknessCheck();    /* need to check of darkness */
 +      } else {
 +        LoadInitData();
 +        z->user.sys.n.mapID = 1; /* set map to start point */
 +        SaveGame(0);        /* clear suspended data */
 +      }
 +      z->_over = false; /* start game */
 +      FldDrawField(fldP);
 +      FrmDrawForm(formP);
 +      FrmSetFocus(formP, FrmGetObjectIndex(formP, ZAMA_COMMAND_FIELD));
 +      CleanMessageField();
 +      LoadMapData(z->user.sys.n.mapID);
 +      DrawMap(true);
 +      ObjectCheck(z->user.sys.n.mapID, true);
 +      if (z->user.fact[1] == z->user.sys.n.mapID) { /* teacher check */
 +        DrawTeacher();
 +        DrawMessage(0xb4, 0, 0);
 +      }
 +      z->prefs._suspended = true; /* continuable */
 +      handled = true;
 +      break;
 +    }
 +  } else if (eventP->eType == keyDownEvent) {
 +    fldP  = GetObjectPtr(ZAMA_MESSAGE_FIELD);
 +    lines = FldGetVisibleLines(fldP) - 1;
 +    switch (eventP->data.keyDown.chr) {
 +    case pageUpChr:
 +      if (FldScrollable(fldP, winUp)) {
 +        FldScrollField(fldP, lines, winUp);
 +        UpdateMessageFieldScrollbar();
 +      }
 +      handled = true;
 +      break;
 +    case pageDownChr:
 +      if (FldScrollable(fldP, winDown)) {
 +        FldScrollField(fldP, lines, winDown);
 +        UpdateMessageFieldScrollbar();
 +      }
 +      handled = true;
 +      break;
 +    }
 +  } else if (eventP->eType == fldChangedEvent) {
 +    /* update scrollbar */
 +    if (eventP->data.fldChanged.fieldID == ZAMA_MESSAGE_FIELD) {
 +      UpdateMessageFieldScrollbar();
 +      handled = true;
 +    }
 +  } else if (eventP->eType == sclRepeatEvent || eventP->eType == sclExitEvent){
 +    ScrollMessageField();
 +    handled = true;
 +  } else if (eventP->eType == menuOpenEvent) {
 +    handled = true;
 +  } else if (eventP->eType == menuEvent) {
 +    handled = MainMenuEvent(eventP);
 +  } else if (eventP->eType == appStopEvent) {
 +    FrmEraseForm(formP);
 +    FrmDeleteForm(formP);
 +    handled = true;
 +  }
 +  return handled;
 +}
 +
 +static
 +Boolean
 +SexHandleEvent(EventPtr eventP)
 +{
 +  UInt16  sid;
 +  Boolean handled = false;
 +  FormPtr formP   = FrmGetActiveForm();
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  if (eventP->eType == ctlSelectEvent) {
 +    switch (eventP->data.ctlSelect.controlID) {
 +    case ZAMA_BUTTON_OK:
 +      sid = FrmGetControlGroupSelection(formP, ZAMA_SEX_GROUP);
 +      if (sid == FrmGetObjectIndex(formP, ZAMA_SEX_BOY)) {
 +        z->user.sys.n.dret   = z->user.fact[0] = 1;
 +        z->user.sys.n.dlogOk = true;
 +        z->user.sys.n.dmesg  = 0;
 +      } else if (sid == FrmGetObjectIndex(formP, ZAMA_SEX_GIRL)) {
 +        z->user.sys.n.dret   = z->user.fact[0] = 2;
 +        z->user.sys.n.dlogOk = true;
 +        z->user.sys.n.dmesg = 0;
 +      } else {
 +        z->user.sys.n.dret   = 0;
 +        z->user.sys.n.dlogOk = false;
 +        z->user.sys.n.dmesg  = 0xbc;
 +      }
 +      break;
 +    }
 +  }
 +  return handled;
 +}
 +
 +static
 +Boolean
 +FileHandleEvent(EventPtr eventP)
 +{
 +  Boolean handled = false;
 +  UInt16  fid;
 +  FormPtr formP = FrmGetActiveForm();
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  if (eventP->eType == ctlSelectEvent) {
 +    switch (eventP->data.ctlSelect.controlID) {
 +    case ZAMA_BUTTON_OK:
 +      fid = FrmGetControlGroupSelection(formP, ZAMA_FILE_GROUP);
 +      if (fid == FrmGetObjectIndex(formP, ZAMA_FILE_ID1)) {
 +        z->user.sys.n.dret = 1;
 +      } else if (fid == FrmGetObjectIndex(formP, ZAMA_FILE_ID2)) {
 +        z->user.sys.n.dret = 2;
 +      } else if (fid == FrmGetObjectIndex(formP, ZAMA_FILE_ID3)) {
 +        z->user.sys.n.dret = 3;
 +      } else {
 +        z->user.sys.n.dret = 0;
 +      }
 +      z->user.sys.n.dlogOk = true;
 +      break;
 +    }
 +  }
 +  return handled;
 +}
 +
 +static
 +Boolean
 +InvHandleEvent(EventPtr eventP)
 +{
 +  Boolean handled = false;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  if (eventP->eType == ctlSelectEvent) {
 +    switch (eventP->data.ctlSelect.controlID) {
 +    case ZAMA_BUTTON_OK:
 +      z->user.sys.n.dlogOk = true;
 +      break;
 +    }
 +  }
 +  return handled;
 +}
 +
 +static
 +Boolean
 +CutHandleEvent(EventPtr eventP)
 +{
 +  UInt16  color;
 +  Boolean handled = false;
 +  FormPtr formP = FrmGetActiveForm();
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  if (eventP->eType == ctlSelectEvent) {
 +    switch (eventP->data.ctlSelect.controlID) {
 +    case ZAMA_BUTTON_OK:
 +      z->user.sys.n.dlogOk = true; /* no time kidding */
 +      color = FrmGetControlGroupSelection(formP, ZAMA_CUT_GROUP);
 +      if (color == FrmGetObjectIndex(formP, ZAMA_CUT_RED)) {
 +        z->user.sys.n.dret = 1;
 +      } else {
 +        z->user.sys.n.dret = 0;
 +      }
 +      break;
 +    }
 +  }
 +  return handled;
 +}
 +
 +static
 +Boolean
 +MainKeyHandleEvent(EventPtr eventP, UInt32 keys)
 +{
 +  Boolean handled = false;
 +  EventType event;
 +
 +  if (FrmGetWindowHandle(FrmGetActiveForm()) != WinGetActiveWindow()) {
 +    /* maybe menu or another widget popping up */
 +    return false;
 +  }
 +
 +  if (eventP->eType == nilEvent) { /* Game PAD */
 +    if (keys & (keyBitPageUp | keyBitPageDown | keyBitHard1 | keyBitHard2)) {
 +      /* move direction */
 +      char *dir = NULL;
 +      if (keys & keyBitPageUp) {
 +        dir = "n";
 +      } else if (keys & keyBitPageDown) {
 +        dir = "s";
 +      } else if (keys & keyBitHard1) {
 +        dir = "w";
 +      } else if (keys & keyBitHard2) {
 +        dir = "e";
 +      }
 +      if (dir) {
 +        FldInsert(GetObjectPtr(ZAMA_COMMAND_FIELD), dir, StrLen(dir));
 +        event.eType = keyDownEvent;
 +        event.data.keyDown.chr = chrLineFeed;
 +        EvtAddEventToQueue(&event);
 +        handled = true;
 +      }
 +    }
 +  }
 +
 +  return handled;
 +}
 +
 +static
 +Boolean
 +KeyHandleEvent(EventPtr eventP)
 +{
 +  UInt32       keys;
 +  Boolean      handled = false;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  if ((keys = KeyCurrentState()) == 0) { /* no key has been pressed */
 +    return false;
 +  }
 +  switch (FrmGetActiveFormID()) {
 +  case ZAMA_MAIN_FORM:
 +    handled = MainKeyHandleEvent(eventP, keys);
 +    break;
 +  default:
 +    handled = false;
 +    break;
 +  }
 +  if (!handled) {
 +    EventType event;
 +    MemSet(&event, 0, sizeof(EventType));
 +    if (eventP->eType == nilEvent && keys & (keyBitHard3 | keyBitHard4)) {
 +      event.eType = keyDownEvent;
 +      event.data.keyDown.chr =(keys & keyBitHard3) ? vchrJogPush : vchrJogBack;
 +      EvtAddEventToQueue(&event);
 +      handled = true;
 +    } else if (eventP->eType == nilEvent &&
 +               keys & (keyBitPageUp | keyBitPageDown)) {
 +      event.eType = keyDownEvent;
 +      event.data.keyDown.chr = (keys & keyBitPageUp) ? vchrJogUp : vchrJogDown;
 +      EvtAddEventToQueue(&event);
 +      handled = true;
 +    }
 +  }
 +  z->_ignoreKey = handled;
 +  return handled;
 +}
 +
 +static
 +Boolean
 +AppHandleEvent(EventPtr eventP)
 +{
 +  UInt16  formId;
 +  FormPtr formP;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  Boolean handled = false;
 +  if (eventP->eType == frmLoadEvent) {
 +    formId = eventP->data.frmLoad.formID;
 +    formP  = FrmInitForm(formId);
 +    FrmSetActiveForm(formP);
 +    FldSetFont(GetObjectPtr(ZAMA_MESSAGE_FIELD), z->prefs._curFont);
 +    switch (formId) {
 +    case ZAMA_MAIN_FORM:
 +      FrmSetEventHandler(formP, MainHandleEvent);
 +#ifdef USE_GRAPH2
 +      if (!tsPatch) {
 +        GFldModifyField(GetObjectPtr(ZAMA_MESSAGE_FIELD));
 +      }
 +#else /* USE_GRAPH2 */
 +      ZamaFldModifyField(GetObjectPtr(ZAMA_MESSAGE_FIELD));
 +#endif /* USE_GRAPH2 */
 +      handled = true;
 +      break;
 +    default:
 +      break;
 +    }
 +  }
 +  return handled;
 +}
 +
 +void
 +EventLoop(void)
 +{
 +  EventType event;
 +  UInt16    err;
 +  UInt16    formID;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  z->_ignoreKey = false;
 +  do {
 +    formID = FrmGetActiveFormID();
 +    EvtGetEvent(&event, evtWaitForever);
 +    if (!z->_ignoreKey && KeyHandleEvent(&event)) {
 +      continue;
 +    }
 +    z->_ignoreKey = false;
 +    if (event.eType == keyDownEvent && event.data.keyDown.chr == chrLineFeed) {
 +      /* accept command */
 +      if (formID == ZAMA_MAIN_FORM) {
 +        CommandLoop();
 +        continue;
 +      }
 +    }
 +    //    if (_silkr && event.eType == menuEvent) SilkLibDisableResize(_silkr);
 +    if (!SysHandleEvent(&event)) {
 +      if (!MenuHandleEvent(NULL, &event, &err)) {
 +#if 0
 +        if (event.eType == menuCmdBarOpenEvent) {
 +          /* command stroke */
 +          event.data.menuCmdBarOpen.preventFieldButtons = true;
 +        }
 +#endif
 +        if(!AppHandleEvent(&event)) {
 +          if (z->_silkr) {
 +            if (z->_silkVer < 0x02) {
 +              SilkLibDisableResize(z->_silkr);
 +            } else {
 +              VskSetState(z->_silkr, vskStateEnable, 0);
 +            }
 +          }
 +          FrmDispatchEvent(&event);
 +          if (z->_silkr) {
 +            if (z->_silkVer < 0x02) {
 +              SilkLibEnableResize(z->_silkr);
 +            } else {
 +              VskSetState(z->_silkr, vskStateEnable, 1);
 +            }
 +          }
 +        }
 +      }
 +    }
 +    //    if (_silkr) SilkLibEnableResize(_silkr);
 +  } while (event.eType != appStopEvent);
 +}
 +/* notification & silk */
 +static
 +Err
 +SilkHeightChange(SysNotifyParamType *paramP_)
 +{
 +  FormPtr       formP, afrmP;
 +  Coord         nx, ny;
 +  RectangleType bounds;
 +  Boolean      *resized;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  afrmP = FrmGetActiveForm();
 +  formP = FrmGetFormPtr(ZAMA_MAIN_FORM);
 +  WinGetBounds(FrmGetWindowHandle(formP), &bounds);
 +  WinGetDisplayExtent(&nx, &ny);
 +  if (afrmP != formP || ny == bounds.topLeft.y + bounds.extent.y) {
 +    /* works only for display hight change */
 +    if (paramP_) paramP_->handled = false;
 +    return errNone;
 +  }
 +  z->_resized = true; /* notify size has changed */
 +  GrfCleanState();
 +  GrfInitState();
 +  GsiInitialize();
 +  GsiSetShiftState(0, gsiShiftNone);
 +  if (paramP_) {
 +    resized = paramP_->userDataP;
 +    if (resized) *resized = true;
 +  }
 +  if (paramP_) paramP_->handled = true;
 +  return errNone;
 +}
 +
 +static
 +Boolean
 +SilkStart(void)
 +{
 +  Err                err;
 +  LocalID            codeResId;
 +  SonySysFtrSysInfoP sonySysFtrSysInfoP;
 +  UInt16             cardNo;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  z->_silkr = 0;
 +  if ((err = FtrGet(sonySysFtrCreator,
 +                    sonySysFtrNumSysInfoP,
 +                    (UInt32*)&sonySysFtrSysInfoP))) {
 +    return false;
 +  }
 +  if ((sonySysFtrSysInfoP->extn & sonySysFtrSysInfoExtnSilk) &&
 +      (sonySysFtrSysInfoP->libr & sonySysFtrSysInfoLibrSilk)) {
 +    if ((err = SysLibFind(sonySysLibNameSilk, &z->_silkr))) {
 +      if (err == sysErrLibNotFound) {
 +        err = SysLibLoad('libr', sonySysFileCSilkLib, &z->_silkr);
 +      }
 +    }
 +  }
 +  z->_resized = false;
 +  if (err || z->_silkr == 0) {
 +    z->_silkr = 0;
 +    return false;
 +  }
 +  if (SilkLibOpen(z->_silkr) == errNone) {
 +    if ((z->_silkVer = VskGetAPIVersion(z->_silkr)) < 0x02) {
 +      SilkLibEnableResize(z->_silkr);
 +    } else {
 +      VskSetState(z->_silkr, vskStateEnable, 1);
 +      VskSetState(z->_silkr, vskStateResize, vskResizeMax);
 +    }
 +  }
 +
 +  if ((err = SysCurAppDatabase(&cardNo, &codeResId)) != errNone) {
 +    return false;
 +  }
 +  err = SysNotifyRegister(cardNo, codeResId, sysNotifyDisplayChangeEvent,
 +                          SilkHeightChange,
 +                          sysNotifyNormalPriority,
 +                          &z->_resized);
 +  return err == errNone;
 +}
 +
 +static
 +Boolean
 +SilkStop(void)
 +{
 +  Err     err;
 +  LocalID codeResId;
 +  UInt16  cardNo;
 +  Boolean res = true;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  if ((err = SysCurAppDatabase(&cardNo, &codeResId)) != errNone) {
 +    res = false;
 +  }
 +  if (res) {
 +    err = SysNotifyUnregister(cardNo, codeResId, sysNotifyDisplayChangeEvent,
 +                              sysNotifyNormalPriority);
 +  }
 +  if (z->_silkr) {
 +    if (z->_silkVer < 0x02) {
 +      SilkLibResizeDispWin(z->_silkr, silkResizeNormal);
 +      SilkLibDisableResize(z->_silkr);
 +    } else {
 +      VskSetState(z->_silkr, vskStateResize, vskResizeMax);
 +      VskSetState(z->_silkr, vskStateEnable, 0);
 +    }
 +    SilkLibClose(z->_silkr);
 +  }
 +  return res && err == errNone;
 +}
 +
 +static
 +void
 +ZamaMapInit(void)
 +{
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +  MemSet(z->map.graphic,  sizeof(z->map.graphic),  0xff);
 +  MemSet(z->map.reaction, sizeof(z->map.reaction), 0);
 +  MemSet(z->map.mesg,     sizeof(z->map.mesg),     0);
 +}
 +
 +static
 +Boolean
 +InitTsPatch(void)
 +{
 +  UInt32  ver;
 +  Boolean ok = false;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +  z->tinyFontID = stdFont;
 +  z->tinyBoldFontID = boldFont;
 +  z->smallFontID = largeFont;
 +  z->smallSymbolFontID = symbolFont;
 +  z->smallSymbol11FontID = symbol11Font;
 +  z->smallSymbol7FontID = symbol7Font;
 +  z->smallLedFontID = ledFont;
 +  z->smallBoldFontID = largeBoldFont;
 +
 +  if (FtrGet(SmallFontAppCreator, SMF_FTR_SMALL_FONT_SUPPORT, &ver) == errNone) {
 +    FtrGet(SmallFontAppCreator, SMF_FTR_TINY_FONT, &z->tinyFontID);
 +    FtrGet(SmallFontAppCreator, SMF_FTR_TINY_BOLD_FONT, &z->tinyBoldFontID);
 +    FtrGet(SmallFontAppCreator, SMF_FTR_SMALL_FONT, &z->smallFontID);
 +    FtrGet(SmallFontAppCreator, SMF_FTR_SYMBOL_FONT, &z->smallSymbolFontID);
 +    FtrGet(SmallFontAppCreator, SMF_FTR_SYMBOL11_FONT, &z->smallSymbol11FontID);
 +    FtrGet(SmallFontAppCreator, SMF_FTR_SYMBOL7_FONT, &z->smallSymbol7FontID);
 +    FtrGet(SmallFontAppCreator, SMF_FTR_LED_FONT, &z->smallLedFontID);
 +    FtrGet(SmallFontAppCreator, SMF_FTR_SMALL_BOLD_FONT, &z->smallBoldFontID);
 +    ok = true;
 +  }
 +  return ok;
 +}
 +
 +static
 +Boolean
 +StartApplication(void)
 +{
 +  UInt16  size, ver;
 +  Boolean res = false;
 +  ZamaGlobalVarType *z = CreateGlobalVariables();
 +
 +#ifdef USE_GRAPH2
 +  if (!GInit()) {
 +    return false;
 +  }
 +#else /* USE_GRAPH2 */
 +  if (!ZamaGraphInit()) {
 +    return false;
 +  }
 +#endif /* USE_GRAPH2 */
 +  res = true;
 +  RctSetRectangle(&z->pict, 32, 32, 256, 152);
 +  LoadInitData();
 +  size = sizeof(ZamaPrefsType);
 +  MemSet(&z->prefs, size, 0);
 +  z->prefs._linedraw = true;
 +  FtrGet(sysFtrCreator, sysFtrDefaultFont, (UInt32*)&z->prefs._curFont);
 +#ifndef USE_GRAPH2
 +  if (ZamaHR()) {
 +    z->prefs._curFont += hrStdFont;
 +  }
 +#endif /* USE_GRAPH2 */
 +  ZamaMapInit();
 +  ver = PrefGetAppPreferences(ZAMA_CREATOR_ID,
 +                              ZAMA_PREFS_ID,
 +                              &z->prefs, &size, true);
 +  if (ver != ZAMA_PREFS_VER) {
 +    /* upgrade ? */
 +  }
 +  SilkStart();
 +  z->tsPatch = InitTsPatch();
 +  return res;
 +}
 +
 +static
 +Boolean
 +StopApplication(void)
 +{
 +  ZamaGlobalVarType *z = GetGlobalVariables();
 +#ifdef USE_GRAPH2
 +  GFinalize();
 +#else /* USE_GRAPH2 */
 +  ZamaGraphClean();
 +#endif /* USE_GRAPH2 */
 +  if (z->user.sys.n.mapID != 76) { /* not opening/clear screen */
 +    SaveGame(0);
 +  }
 +  PrefSetAppPreferences(ZAMA_CREATOR_ID,
 +                        ZAMA_PREFS_ID,
 +                        ZAMA_PREFS_VER,
 +                        &z->prefs,
 +                        sizeof(ZamaPrefsType), true);
 +  SilkStop();
 +  DeleteGlobalVariables();
 +  return true;
 +}
 +
 +static void
 +ZamaSearchDrawName(const Char *strP_, Coord x_, Coord y_, UInt16 width_)
 +{
 +  Char *ptr = StrChr(strP_, linefeedChr);
 +  UInt16 titleLen = (ptr == NULL) ? StrLen(strP_) : (UInt16)(ptr - strP_);
 +  if (FntWidthToOffset(strP_, titleLen, width_, NULL, NULL) == titleLen) {
 +    WinDrawChars(strP_, titleLen, x_, y_);
 +  } else {
 +    Int16 titleWidth;
 +    titleLen = FntWidthToOffset(strP_, titleLen,
 +                                width_ - FntCharWidth(chrEllipsis),
 +                                NULL, &titleWidth);
 +    WinDrawChars(strP_, titleLen, x_, y_);
 +    WinDrawChar (chrEllipsis, x_ + titleWidth, y_);
 +  }
 +}
 +
 +static void
 +ZamaSearch(FindParamsPtr findParams)
 +{
 +  MemHandle     recH;
 +  Char          *headerP;
 +  Boolean       done, match;
 +  RectangleType r;
 +  UInt16        pos, matchLength;
 +  UInt32        longPos;
 +
 +  recH = DmGetResource(strRsc, ZAMA_SEARCH_HEADER);
 +  headerP = MemHandleLock(recH);
 +  done = FindDrawHeader(findParams, headerP);
 +  MemHandleUnlock(recH);
 +  DmReleaseResource(recH);
 +  if (done) return;
 +  findParams->more = false;
 +  if (findParams->recordNum == ZAMA_CODE_ISAKO && EvtSysEventAvail(true)) {
 +    findParams->more = true;
 +    return;
 +  }
 +  match = TxtFindString("������",
 +                        findParams->strToFind,
 +                        &longPos, &matchLength);
 +  pos = longPos;
 +  if (match) {
 +    done = FindSaveMatch(findParams, ZAMA_CODE_ISAKO,
 +                         pos, 0, matchLength, 0, 0);
 +    if (!done) {
 +      FindGetLineBounds(findParams, &r);
 +      ZamaSearchDrawName("������",
 +                         r.topLeft.x + 1, r.topLeft.y, r.extent.x - 2);
 +      ++findParams->lineNumber;
 +    }
 +  }
 +}
 +
 +UInt32
 +PilotMain(UInt16 cmd, void *cmdPBP, UInt16 launchFlags)
 +{
 +  if (cmd == sysAppLaunchCmdNormalLaunch || cmd == sysAppLaunchCmdGoTo) {
 +    _startup = 0;
 +    if (cmd == sysAppLaunchCmdGoTo) {
 +      _startup = ((GoToParamsPtr)cmdPBP)->recordNum;
 +    }
 +    if (StartApplication()) {
 +      FrmGotoForm(ZAMA_MAIN_FORM);
 +      EventLoop();
 +      FrmCloseAllForms();
 +      StopApplication();
 +    }
 +  } else if (cmd == sysAppLaunchCmdFind) {
 +    ZamaSearch((FindParamsPtr)cmdPBP);
 +  } else if (cmd == sysAppLaunchCmdNotify) {
 +    SilkHeightChange(cmdPBP);
 +  }
 +  return 0;
 +}
 +</file>
 +<file c graph2.c>
 +/*
 + * Graphics routine for High-High-School Adventure.
 +  Copyright(c)2003 ZOBplus hiro
 + */
 +
 +#include <PalmOS.h>
 +#include <SonyCLIE.h>
 +#include "high.h"
 +#include "graph2.h"
 +#include "glue.h"
 +
 +#define MAX_QUEUE_SIZE (1024)
 +typedef struct {
 +  int       _Qstart, _Qend;
 +  PointType _Queue[MAX_QUEUE_SIZE];
 +} GPointQueueType;
 +typedef GPointQueueType *GPointQueuePtr;
 +
 +/* global variables */
 +
 +typedef struct {
 +  GPointQueueType  _pointQ;
 +  Boolean          _hDensity; /* OS5 high-density */
 +  UInt16           _hrLib;    /* OS4 CLIe High-Resolution */
 +  UInt16           _hrVer;    /* CLIe High-Resolution API Version */
 +  IndexedColorType _colors[gColorNameCandidate]; /* color map */
 +  RGBColorType     _defrgb[gColorNameCandidate]; /* dafault map */
 +  WinHandle        _canvas;   /* offscreen window */
 +  BitmapPtr        _bmpP;     /* canvas bitmap */
 +  UInt8            *_baseP;   /* canvas bitmap body */
 +  UInt16           _rowBytes; /* row bytes */
 +  RectangleType    _border;   /* canvas border */
 +  UInt32           _width, _height, _depth; /* properties */
 +  FontID           _fntTable[8]; /* for CLIe High Resolution Fonts */
 +} GraphGlobalVarType;
 +
 +static
 +GraphGlobalVarType *
 +CreateGlobalVariables()
 +{
 +  GraphGlobalVarType *ptr = NULL;
 +  Err err;
 +  if ((err = FtrPtrNew(ZAMA_CREATOR_ID, ZAMA_GRAPH_VAR, sizeof(GraphGlobalVarType), &ptr)) != errNone)
 +  {
 +    return NULL;
 +  }
 +  return ptr;
 +}
 +
 +static
 +void
 +DeleteGlobalVariables()
 +{
 +  FtrPtrFree(ZAMA_CREATOR_ID, ZAMA_GRAPH_VAR);
 +}
 +
 +static
 +GraphGlobalVarType *
 +GetGlobalVariables()
 +{
 +  GraphGlobalVarType *ptr;
 +  Err err;
 +  if ((err = FtrGet(ZAMA_CREATOR_ID, ZAMA_GRAPH_VAR, &ptr)) != errNone)
 +  {
 +    return NULL;
 +  }
 +  return ptr;
 +}
 +
 +static void
 +HDWinDrawChars(Char *strP_, UInt16 len_, Coord x_, Coord y_)
 +{
 +  WinHandle     curH, offH;
 +  BitmapPtr     bmpP;
 +  BitmapPtrV3   bmp3P;
 +  RectangleType r;
 +  Coord         w, h;
 +  Err           err;
 +  UInt16        coordSys;
 +
 +  curH = WinGetDrawWindow();
 +  coordSys = WinSetCoordinateSystem(kCoordinatesDouble);
 +  w = FntCharsWidth(strP_, len_);
 +  h = FntCharHeight();
 +  bmpP  = BmpCreate(w, h, 8, NULL, &err);
 +  bmp3P = BmpCreateBitmapV3(bmpP, kCoordinatesStandard,
 +                            BmpGetBits(bmpP), NULL);
 +  offH  = WinCreateBitmapWindow((BitmapPtr)bmp3P, &err);
 +
 +  WinSetDrawWindow(offH);
 +  WinDrawChars(strP_, len_, 0, 0);
 +  WinDeleteWindow(offH, false);
 +  BmpSetDensity((BitmapPtr)bmp3P, kCoordinatesDouble);
 +  offH  = WinCreateBitmapWindow((BitmapPtr)bmp3P, &err);
 +  RctSetRectangle(&r, 0, 0, w / 2, h / 2);
 +  WinCopyRectangle(offH, curH, &r, x_, y_, winOverlay);
 +  WinDeleteWindow(offH, false);
 +  BmpDelete((BitmapPtr)bmp3P);
 +  BmpDelete(bmpP);
 +  WinSetCoordinateSystem(coordSys);
 +}
 +
 +static inline UInt16
 +GCoord2Offset(Coord x_, Coord y_)
 +{
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  if (g->_hDensity || g->_hrLib) { /* High Resolution */
 +    return y_ * g->_rowBytes + x_;
 +  } else {
 +    return y_ * g->_rowBytes + (x_ / 2);
 +  }
 +}
 +
 +static inline void
 +GSetPixel(Coord x_, Coord y_, IndexedColorType c_)
 +{
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  UInt16 o  = GCoord2Offset(x_, y_);
 +  if (g->_hDensity) {
 +#if 0
 +    WinHandle draw = WinGetDrawWindow();
 +    WinSetDrawWindow(_canvas);
 +    WinDrawPixel(x_, y_);
 +    WinSetDrawWindow(draw);
 +#else
 +    g->_baseP[o] = c_;
 +#endif
 +  } else if (_hrLib) {
 +    g->_baseP[o] = c_;
 +  } else {
 +    if (x_ % 2) {
 +      g->_baseP[o] &= 0xf0;
 +      g->_baseP[o] |= (c_ & 0x0f);
 +    } else {
 +      g->_baseP[o] &= 0x0f;
 +      g->_baseP[o] |= (c_ << 4);
 +    }
 +  }
 +}
 +
 +static inline IndexedColorType
 +GFetchPixel(Coord x_, Coord y_)
 +{
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  UInt16 o = GCoord2Offset(x_, y_);
 +  if (g->_hDensity) {
 +#if 0
 +    IndexedColorType c;
 +    WinHandle        draw = WinGetDrawWindow();
 +    WinSetDrawWindow(_canvas);
 +    c = WinGetPixel(x_, y_);
 +    WinSetDrawWindow(draw);
 +    return c;
 +#else
 +    return g->_baseP[o];
 +#endif
 +  } else if (g->_hrLib) {
 +    return g->_baseP[o];
 +  } else {
 +    if (x_ % 2) {
 +      return g->_baseP[o] & 0x0f;
 +    } else {
 +      return (g->_baseP[o] & 0xf0) >> 4;
 +    }
 +  }
 +}
 +
 +#define isSjis(k_) (((k_) >= 0x80 && (k_) < 0xa0)||((k_) >= 0xe0))
 +
 +static inline void
 +GInitQueue(void)
 +{
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  g->_pointQ._Qstart = g->_pointQ._Qend = 0;
 +}
 +
 +static inline void
 +GShiftPoint(Coord x_, Coord y_)
 +{
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  g->_pointQ._Queue[g->_pointQ._Qstart].x = x_;
 +  g->_pointQ._Queue[g->_pointQ._Qstart].y = y_;
 +  if (++g->_pointQ._Qstart == MAX_QUEUE_SIZE) {
 +    g->_pointQ._Qstart = 0;
 +  }
 +}
 +
 +static inline PointType*
 +GUnshiftPoint(void)
 +{
 +  PointType *p;
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  if (g->_pointQ._Qstart == g->_pointQ._Qend) return NULL;
 +  p = &g->_pointQ._Queue[g->_pointQ._Qend++];
 +  if (g->_pointQ._Qend == MAX_QUEUE_SIZE) {
 +    g->_pointQ._Qend = 0;
 +  }
 +  return p;
 +}
 +
 +static void
 +GInitColors(void)
 +{
 +  UInt16 i;
 +  RGBColorType rgb[] = {
 +    { 0, 0x00, 0x00, 0x00},
 +    { 0, 0x00, 0x00, 0xff},
 +    { 0, 0xff, 0x00, 0x00},
 +    { 0, 0xff, 0x00, 0xff},
 +    { 0, 0x00, 0xff, 0x00},
 +    { 0, 0x00, 0xff, 0xff},
 +    { 0, 0xff, 0xff, 0x00},
 +    { 0, 0xff, 0xff, 0xff},
 +    { 0, 0x55, 0x55, 0x55},
 +    { 0, 0x00, 0x00, 0x80},
 +    { 0, 0x80, 0x00, 0x00},
 +    { 0, 0x80, 0x00, 0x80},
 +    { 0, 0x00, 0x80, 0x00},
 +    { 0, 0x00, 0x80, 0x80},
 +    { 0, 0x80, 0x80, 0x00},
 +    { 0, 0xaa, 0xaa, 0xaa},
 +  };
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  for (i = 0 ; i < gColorNameCandidate ; i++) {
 +    g->_colors[i] = WinRGBToIndex(&rgb[i]);
 +    WinIndexToRGB(g->_colors[i], &g->_defrgb[i]);
 +    if (g->_hrLib == 0 && !g->_hDensity) {
 +      g->_colors[i] = i;
 +    }
 +  }
 +}
 +
 +/* API */
 +
 +Boolean
 +GInit(void)
 +{
 +  SonySysFtrSysInfoP sonySysFtrSysInfoP; /* Sony CLIe System Information */
 +  UInt32             wmVer, wmAttr;
 +  Err                err = 0;
 +  Boolean            res = false;
 +  Boolean            col = true;
 +  UInt16             i;
 +  FontID             ftab[] = {
 +    hrTinyFont, hrTinyBoldFont, hrSmallFont, hrSmallBoldFont,
 +    hrStdFont, hrBoldFont, hrLargeFont, hrLargeBoldFont
 +  };
 +  GraphGlobalVarType *g = CreateGlobalVariables();
 +  /* OS5 High Density Check */
 +  g->_hDensity = false;
 +  if (FtrGet(sysFtrCreator, sysFtrNumWinVersion, &wmVer) == errNone) {
 +    if (wmVer >= 4) { /* hd interface existing */
 +      WinScreenGetAttribute(winScreenDensity, &wmAttr);
 +      if (wmAttr == kDensityDouble) {
 +        _hDensity = true;
 +        WinSetCoordinateSystem(kCoordinatesStandard);
 +      }
 +    }
 +  }
 +  /* CLIe High Resolution Check */
 +  if ((err = FtrGet(sonySysFtrCreator,
 +                    sonySysFtrNumSysInfoP,
 +                    (UInt32*)&sonySysFtrSysInfoP)) == 0) {
 +    if (sonySysFtrSysInfoP->libr & sonySysFtrSysInfoLibrHR) {
 +      /* High-resolution library available */
 +      if ((err = SysLibFind(sonySysLibNameHR, &_hrLib))) {
 +        if (err == sysErrLibNotFound) {
 +          err = SysLibLoad('libr', sonySysFileCHRLib, &_hrLib);
 +        }
 +      }
 +    }
 +  }
 +  if (!g->_hDensity && (err || g->_hrLib == 0)) {
 +    g->_hrLib = 0; /* no library existing */
 +    g->_width = g->_height = 160;
 +    g->_depth = 8;
 +    WinScreenMode(winScreenModeSet, &g->_width, &g->_height, &g->_depth, &col);
 +    res = true;
 +  } else {
 +    g->_width = g->_height = 320;
 +    g->_depth = 8;
 +    res = true; /* only High-resolution CLIE/OS5 high density device support */
 +    if (g->_hDensity) {
 +      WinScreenMode(winScreenModeSet, &g->_width, &g->_height, &g->_depth, &col);
 +    } else {
 +      HROpen(g->_hrLib);
 +      HRGetAPIVersion(g->_hrLib, &g->_hrVer);
 +      HRWinScreenMode(g->_hrLib,
 +                      winScreenModeSet, &g->_width, &g->_height, &g->_depth, &col);
 +      for (i = 0 ; i < 8 ; i++) {
 +        g->_fntTable[i] = ftab[i];
 +      }
 +    }
 +  }
 +  WinScreenMode(winScreenModeGet, NULL, NULL, NULL, &col);
 +  if (!col) {
 +    if (g->_hrLib && !g->_hDensity) {
 +      HRClose(g->_hrLib);
 +    }
 +    return false; /* mono-chrome mode */
 +  }
 +  GInitColors();
 +  RctSetRectangle(&g->_border, 0, 0, g->_width, g->_height);
 +  if (g->_hDensity) {
 +    UInt16 coordSys = WinSetCoordinateSystem(kCoordinatesDouble);
 +    g->_canvas = WinCreateOffscreenWindow(g->_width, g->_height,
 +                                       nativeFormat, &err);
 +    WinSetCoordinateSystem(coordSys);
 +  } else if (g->_hrLib) {
 +    g->_canvas = HRWinCreateOffscreenWindow(g->_hrLib,
 +                                         g->_width, g->_height,
 +                                         screenFormat, &err);
 +  }
 +  if (g->_canvas == NULL) {
 +    res = false;
 +  } else {
 +    _bmpP  = WinGetBitmap(g->_canvas);
 +    _baseP = BmpGetBits(g->_bmpP);
 +    GlueBmpGetDimensions(g->_bmpP, NULL, NULL, &g->_rowBytes);
 +  }
 +  return res;
 +}
 +
 +Boolean
 +GFinalize(void)
 +{
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  if (g->_hrLib && !g->_hDensity) {
 +    HRClose(g->_hrLib);
 +  }
 +  if (g->_canvas) {
 +    WinDeleteWindow(g->_canvas, false);
 +  }
 +  DeleteGlobalVariables();
 +  return true;
 +}
 +
 +void
 +GChromakeyPaint(RectanglePtr clipP_, UInt8 *patP_, Boolean line_)
 +{
 +  IndexedColorType c;
 +  WinHandle        cur;
 +  UInt8            r, g, b, off;
 +  Coord            x, y, dx, lx, ox;
 +  UInt16           i, j, n, coordSys;
 +  UInt16           bl, bu, br, bd;
 +  RectangleType    rs;
 +  UInt8            pattern[][3] = {
 +    { 0x00, 0x00, 0x00 },
 +    { 0xff, 0x00, 0x00 },
 +    { 0x00, 0xff, 0x00 },
 +    { 0xff, 0xff, 0x00 },
 +    { 0x00, 0x00, 0xff },
 +    { 0xff, 0x00, 0xff },
 +    { 0x00, 0xff, 0xff },
 +    { 0xff, 0xff, 0xff },
 +  };
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  i = 0;
 +  n = patP_[i++];
 +  for (j = 0 ; j < n ; j++) {
 +    pattern[j + 1][0] = patP_[i + j * 3 + 0];
 +    pattern[j + 1][1] = patP_[i + j * 3 + 1];
 +    pattern[j + 1][2] = patP_[i + j * 3 + 2];
 +  }
 +
 +  bl = clipP_->topLeft.x;
 +  bu = clipP_->topLeft.y;
 +  br = bl + clipP_->extent.x;
 +  bd = bu + clipP_->extent.y;
 +  cur = WinGetDrawWindow();
 +  if (g->_hDensity) {
 +    coordSys = WinSetCoordinateSystem(kCoordinatesDouble);
 +  }
 +  for (y = bu; y < bd ; y++) {
 +    for (x = bl ; x < br ; x += 8) {
 +      lx = (br - x < 8) ? br - x : 8;
 +      for (dx = 0, ox = 7 ; dx < lx ; dx++, ox--) {
 +        c   = GFetchPixel(x + dx, y);
 +        off = 1 << ox;
 +        for (j = 1 ; j <= n ; j++) {
 +          if (_colors[j] == c) {
 +            b = (pattern[j][0] & off) >> ox;
 +            r = (pattern[j][1] & off) >> ox;
 +            g = (pattern[j][2] & off) >> ox;
 +            GSetPixel(x + dx, y, _colors[(r << 1) | (g << 2) | b]);
 +            break;
 +          }
 +        }
 +      }
 +    }
 +    if (line_) {
 +      RctSetRectangle(&rs, bl, y, br - bl, 1);
 +      if (g->_hrLib) {
 +        HRWinCopyRectangle(g->_hrLib, g->_canvas, cur, &rs, bl, y, winPaint);
 +      } else {
 +        WinCopyRectangle(g->_canvas, cur, &rs, bl, y, winPaint);
 +      }
 +    }
 +  }
 +  if (!line_) {
 +    if (g->_hrLib) {
 +      HRWinCopyRectangle(g->_hrLib, g->_canvas, cur, clipP_, bl, bu, winPaint);
 +    } else {
 +      WinCopyRectangle(g->_canvas, cur, clipP_, bl, bu, winPaint);
 +    }
 +  }
 +  if (g->_hDensity) {
 +    WinSetCoordinateSystem(coordSys);
 +  }
 +}
 +
 +static inline Boolean
 +_chk(Coord x_, Coord y_, IndexedColorType c_, IndexedColorType b_)
 +{
 +  IndexedColorType c = GFetchPixel(x_, y_);
 +  return c != c_ && c != b_;
 +}
 +
 +void
 +GPaintSpec(GPaintSpecPtr specP_)
 +{
 +  PointType        *pP;
 +  Coord            bl, bu, br, bd;
 +  Coord            l, r, x, y;
 +  Coord            wx, wy;
 +  WinHandle        cur;
 +  Coord            ltx, lty, lbx, lby;
 +  Boolean          uf, df;
 +  UInt16           coordSys;
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +
 +  bl  = specP_->_clipP->topLeft.x;
 +  bu  = specP_->_clipP->topLeft.y;
 +  br  = bl + specP_->_clipP->extent.x;
 +  bd  = bu + specP_->_clipP->extent.y;
 +  x = specP_->_x + bl;
 +  y = specP_->_y + bu;
 +
 +  ltx = lty = lbx = lby = -1;
 +
 +  cur = WinGetDrawWindow();
 +  if (!_chk(x, y, g->_colors[specP_->_fg], g->_colors[specP_->_bg])){
 +    /* needless to paint */
 +    return;
 +  }
 +  GInitQueue();
 +
 +  GShiftPoint(x, y);
 +  if (g->_hDensity) {
 +    coordSys = WinSetCoordinateSystem(kCoordinatesDouble);
 +  }
 +  WinSetForeColor(g->_colors[specP_->_fg]);
 +  while ((pP = GUnshiftPoint()) != NULL) {
 +    if (!_chk(pP->x, pP->y, g->_colors[specP_->_fg], g->_colors[specP_->_bg])) {
 +      /* needless to paint */
 +      continue;
 +    }
 +    for (l = pP->x ; l >= bl ; l--) {
 +      if (!_chk(l, pP->y, g->_colors[specP_->_fg], g->_colors[specP_->_bg])) {
 +        break;
 +      }
 +    }
 +    ++l;
 +    for (r = pP->x ; r < br ; r++) {
 +      if (!_chk(r, pP->y, g->_colors[specP_->_fg], g->_colors[specP_->_bg])) {
 +        break;
 +      }
 +    }
 +    --r;
 +    /* draw current line */
 +    if (g->_hrLib) {
 +      WinSetDrawWindow(g->_canvas);
 +      HRWinDrawLine(g->_hrLib, l, pP->y, r, pP->y);
 +      WinSetDrawWindow(cur);
 +      HRWinDrawLine(g->_hrLib, l, pP->y, r, pP->y);
 +    } else {
 +      WinSetDrawWindow(g->_canvas);
 +      WinDrawLine(l, pP->y, r, pP->y);
 +      WinSetDrawWindow(cur);
 +      WinDrawLine(l, pP->y, r, pP->y);
 +    }
 +    for (wx = l ; wx <= r ; wx++) {
 +      uf = df = false;
 +      /* scan upper line */
 +      wy = pP->y - 1;
 +      if (wy >= bu) {
 +        uf = _chk(wx, wy, g->_colors[specP_->_fg], g->_colors[specP_->_bg]);
 +        if (uf) {
 +          if (wx + 1 <= r && !_chk(wx + 1, wy,
 +                                   g->_colors[specP_->_fg],
 +                                   g->_colors[specP_->_bg])) {
 +            /* found right edge */
 +            GShiftPoint(wx, wy);
 +            uf = false;
 +          } else if (wx == r) {
 +            GShiftPoint(wx, wy);
 +          }
 +        }
 +      }
 +      /* scan lower line */
 +      wy = pP->y + 1;
 +      if (wy < bd) {
 +        df = _chk(wx, wy, g->_colors[specP_->_fg], g->_colors[specP_->_bg]);
 +        if (df) {
 +          if (wx + 1 <= r && !_chk(wx + 1, wy,
 +                                   g->_colors[specP_->_fg],
 +                                   g->_colors[specP_->_bg])) {
 +            /* found right edge */
 +            GShiftPoint(wx, wy);
 +            df = false;
 +          } else if (wx == r) {
 +            GShiftPoint(wx, wy);
 +          }
 +        }
 +      }
 +    }
 +  }
 +  if (_hDensity) {
 +    WinSetCoordinateSystem(coordSys);
 +  }
 +}
 +
 +void
 +GPaint(RectanglePtr clipP_, Coord x_, Coord y_, GColorName f_, GColorName b_)
 +{
 +  GPaintSpecType spec;
 +  spec._clipP  = clipP_;
 +  spec._x      = x_;
 +  spec._y      = y_;
 +  spec._fg     = f_;
 +  spec._bg     = b_;
 +  spec._bgBmpP = NULL;
 +  GPaintSpec(&spec);
 +}
 +
 +void
 +GDrawLine(RectanglePtr clipP_,
 +          Coord x0_, Coord y0_, Coord x1_, Coord y1_, GColorName c_)
 +{
 +  RectangleType cur;
 +  WinHandle     draw, windows[2];
 +  UInt16        i;
 +  UInt16        coordSys;
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +
 +  if (g->_hDensity) {
 +    coordSys = WinSetCoordinateSystem(kCoordinatesDouble);
 +  }
 +  draw = WinGetDrawWindow();
 +  WinSetForeColor(g->_colors[c_]);
 +  windows[0] = g->_canvas;
 +  windows[1] = draw;
 +  for (i = 0 ; i < 2; i++) {
 +    WinSetDrawWindow(windows[i]);
 +    if (g->_hrLib) {
 +      if (clipP_) {
 +        HRWinGetClip(g->_hrLib, &cur);
 +        HRWinSetClip(g->_hrLib, clipP_);
 +      }
 +      HRWinDrawLine(g->_hrLib, x0_, y0_, x1_, y1_);
 +      if (clipP_) {
 +        HRWinSetClip(g->_hrLib, &cur);
 +      }
 +    } else {
 +      if (clipP_) {
 +        WinGetClip(&cur);
 +        WinSetClip(clipP_);
 +      }
 +      WinDrawLine(x0_, y0_, x1_, y1_);
 +      if (clipP_) {
 +        WinSetClip(&cur);
 +      }
 +    }
 +  }
 +  if (g->_hDensity) {
 +    WinSetCoordinateSystem(coordSys);
 +  }
 +}
 +
 +GColorName
 +GGetPixel(Coord x0_, Coord y0_)
 +{
 +  UInt16           i, coordSys;
 +  IndexedColorType c;
 +  GColorName       r = gColorInvalid;
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  if (g->_hDensity) {
 +    coordSys = WinSetCoordinateSystem(kCoordinatesDouble);
 +  }
 +  c = GFetchPixel(x0_, y0_);
 +  for (i = 0 ; i < gColorNameCandidate ; i++) {
 +    if (g->_colors[i] == c) {
 +      r = i;
 +      break;
 +    }
 +  }
 +  if (g->_hDensity) {
 +    WinSetCoordinateSystem(coordSys);
 +  }
 +  return r;
 +}
 +
 +void
 +GDrawPixel(RectanglePtr clipP_, Coord x0_, Coord y0_, GColorName c_)
 +{
 +  UInt16 coordSys;
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +
 +  if (g->_hDensity) {
 +    coordSys = WinSetCoordinateSystem(kCoordinatesDouble);
 +  }
 +  WinSetForeColor(g->_colors[c_]);
 +  GSetPixel(x0_, y0_, g->_colors[c_]);
 +  if (g->_hrLib) {
 +    HRWinDrawPixel(g->_hrLib, x0_, y0_);
 +  } else {
 +    WinDrawPixel(x0_, y0_);
 +  }
 +  if (g->_hDensity) {
 +    WinSetCoordinateSystem(coordSys);
 +  }
 +}
 +
 +void
 +GDrawRectangle(RectanglePtr rP_, GColorName c_)
 +{
 +  UInt16        coordSys;
 +  WinHandle     draw = WinGetDrawWindow();
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +
 +  if (g->_hDensity) {
 +    coordSys = WinSetCoordinateSystem(kCoordinatesDouble);
 +  }
 +  WinSetForeColor(g->_colors[c_]);
 +  if (g->_hrLib) {
 +    WinSetDrawWindow(g->_canvas);
 +    HRWinDrawRectangle(g->_hrLib, rP_, 0);
 +    WinSetDrawWindow(draw);
 +    HRWinDrawRectangle(g->_hrLib, rP_, 0);
 +  } else {
 +    WinSetDrawWindow(g->_canvas);
 +    WinDrawRectangle(rP_, 0);
 +    WinSetDrawWindow(draw);
 +    WinDrawRectangle(rP_, 0);
 +  }
 +  if (g->_hDensity) {
 +    WinSetCoordinateSystem(coordSys);
 +  }
 +}
 +
 +void
 +GDrawChars(Boolean small_,
 +           Char *strP_, UInt16 len_, Coord x_, Coord y_, GColorName c_)
 +{
 +  UInt16    i;
 +  UInt16    coordSys;
 +  WinHandle windows[2];
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +
 +  if (g->_hDensity) {
 +    coordSys = WinSetCoordinateSystem(kCoordinatesDouble);
 +  }
 +  WinSetTextColor(g->_colors[c_]);
 +
 +  windows[0] = g->_canvas;
 +  windows[1] = WinGetDrawWindow();
 +  if (strP_[len_ - 1] < ' ') {
 +    --len_;
 +  }
 +  for(i = 0 ; i < 2 ; i++) {
 +    WinSetDrawWindow(windows[i]);
 +    if (g->_hDensity) {
 +      if (small_){
 +        HDWinDrawChars(strP_, len_, x_, y_);
 +      } else {
 +        WinDrawChars(strP_, len_, x_, y_);
 +      }
 +    } else {
 +      HRWinDrawChars(g->_hrLib, strP_, len_, x_, y_);
 +    }
 +  }
 +  if (g->_hDensity) {
 +    WinSetCoordinateSystem(coordSys);
 +  }
 +}
 +
 +void
 +GPaletteChange(GColorName c_)
 +{
 +  UInt16       i;
 +  RGBColorType *mapP, rgb;
 +  MemHandle    hRGB;
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +
 +  hRGB = MemHandleNew(sizeof(RGBColorType) * 256);
 +  mapP = (RGBColorType*)MemHandleLock(hRGB);
 +  WinPalette(winPaletteGet, 0, 256, mapP);
 +  if (c_ != gColorInvalid) {
 +    WinIndexToRGB(g->_colors[c_], &rgb);
 +  }
 +  for (i = gColorBlue ; i < gColorWhite ; i++) {
 +    mapP[g->_colors[i]] = (c_ == gColorInvalid) ? g->_defrgb[i] : rgb;
 +  }
 +  WinPalette(winPaletteSet, 0, 256, mapP);
 +  MemHandleUnlock(hRGB);
 +  MemHandleFree(hRGB);
 +}
 +
 +FontID
 +GGetFont(void)
 +{
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  return (!g->_hDensity && g->_hrLib) ? HRFntGetFont(g->_hrLib) : FntGetFont();
 +}
 +
 +FontID
 +GSetFont(FontID id_)
 +{
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  return (!g->_hDensity && g->_hrLib) ? HRFntSetFont(g->_hrLib, id_) : FntSetFont(id_);
 +}
 +
 +void
 +GFldModifyField(FieldPtr fldP)
 +{
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  if (g->_hDensity || g->_hrLib) {
 +    FldSetUsable(fldP, false);
 +  }
 +}
 +
 +void
 +GFldDrawField(FieldPtr fldP)
 +{
 +  UInt16        lines, pos, offset, maxLength;
 +  UInt16        h, w, l;
 +  FontID        curFont = stdFont, fldFont;
 +  Char          *textP;
 +  RectangleType b;
 +  Boolean       small = false;
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +
 +  if (!g->_hDensity && g->_hrLib == 0) {
 +    FldDrawField(fldP);
 +    return;
 +  }
 +  WinPushDrawState();
 +  if (g->_hDensity) {
 +    WinSetCoordinateSystem(kCoordinatesDouble);
 +  }
 +  FldGetBounds(fldP, &b);
 +  if (_hDensity || _hrLib) {
 +    b.topLeft.x <<= 1;
 +    b.topLeft.y <<= 1;
 +    b.extent.x <<= 1;
 +    b.extent.y <<= 1;
 +  }
 +  fldFont = FldGetFont(fldP);
 +  textP = FldGetTextPtr(fldP);
 +  maxLength = FldGetTextLength(fldP);
 +  if (textP) {
 +    GFldEraseField(fldP);
 +    if (g->_hDensity) {
 +      if (fldFont & fntAppFontCustomBase) {
 +        fldFont -= fntAppFontCustomBase;
 +        small    = true;
 +      }
 +      curFont = FntSetFont(fldFont);
 +    } else if (g->_hrLib) {
 +      FontID hrFont;
 +      if (fldFont & fntAppFontCustomBase) {
 +        /* use small font */
 +        fldFont -= fntAppFontCustomBase;
 +        small    = true;
 +      }
 +      hrFont = g->_fntTable[fldFont + ((small) ? 0 : 4)];
 +      if (fldFont == largeBoldFont) {
 +        hrFont = g->_fntTable[(small) ? 3 : 7];
 +      }
 +      curFont = HRFntSetFont(g->_hrLib, hrFont);
 +    }
 +    h = FntLineHeight();
 +    w = b.extent.x;
 +    if (small) {
 +      if (g->_hDensity) {
 +        h /= 2;
 +        w *= 2;
 +      }
 +    }
 +    if (!g->_hDensity && g->_hrLib && g->_hrVer >= HR_VERSION_SUPPORT_FNTSIZE) {
 +      h = HRFntLineHeight(g->_hrLib);
 +    }
 +    lines = FldGetVisibleLines(fldP);
 +    if (g->_hDensity) {
 +      lines = b.extent.y / h;
 +    }
 +    offset = FldGetScrollPosition(fldP);
 +    for (pos = 0 ; pos < lines ; pos++) {
 +      l = FldWordWrap(&textP[offset], w);
 +      GDrawChars(small, &textP[offset],
 +                 l, b.topLeft.x, b.topLeft.y + pos * h, gColorBlue);
 +      offset += l;
 +      if (offset >= maxLength) {
 +        break;
 +      }
 +    }
 +    if (g->_hDensity) {
 +      FntSetFont(curFont);
 +    } else if (g->_hrLib) {
 +      HRFntSetFont(g->_hrLib, curFont);
 +    }
 +  }
 +  WinPopDrawState();
 +}
 +
 +void
 +GFldEraseField(FieldPtr fldP)
 +{
 +  RectangleType b;
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  if (!g->_hDensity && g->_hrLib == 0) {
 +    FldEraseField(fldP);
 +    return;
 +  }
 +  FldGetBounds(fldP, &b);
 +  b.topLeft.x <<= 1;
 +  b.topLeft.y <<= 1;
 +  b.extent.x <<= 1;
 +  b.extent.y <<= 1;
 +  if (g->_hDensity) {
 +    WinPushDrawState();
 +    WinSetCoordinateSystem(kCoordinatesDouble);
 +    WinEraseRectangle(&b, 0);
 +    WinPopDrawState();
 +  } else if (g->_hrLib) {
 +    HRWinEraseRectangle(g->_hrLib, &b, 0);
 +  }
 +}
 +
 +void
 +GGetDisplayExtent(Coord *xP, Coord *yP, Boolean hd)
 +{
 +  WinPushDrawState();
 +  if (_hDensity) {
 +    WinSetCoordinateSystem((hd) ? kCoordinatesDouble : kCoordinatesStandard);
 +  }
 +  WinGetDisplayExtent(xP, yP);
 +  WinPopDrawState();
 +}
 +
 +UInt16
 +GScale(void)
 +{
 +  GraphGlobalVarType *g = GetGlobalVariables();
 +  return (g->_hDensity || g->_hrLib) ? 2 : 1;
 +}
 +</file>
  
ハイハイスクールアドベンチャー_palmos版.1762473288.txt.gz · 最終更新: by araki