1989å¹´ã«å¯å£«éãçºå£²ãããã½ã³ã³ãFM TOWNSãã«ã1992å¹´ã«id Softwareãçºå£²ããå ç¥FPSã²ã¼ã ãWolfenstein 3Dãã移æ¤ãã¦ã¿ã¾ãããæå³ãåãããªãã¨æãã¾ããä»ã¯ä»¤åã§ãã
FM TOWNS ãã¼ãã£ã¼ãé¤ãFM TOWNSã·ãªã¼ãºå ¨æ©ç¨®ã§åä½å¯è½ãªã¯ãã(追è¨ï¼ãã¼ãã£ã¼ãã¡ã¢ãª2MB対å¿çä½æ)ã¡ã¢ãª4MB以ä¸ãHDDå¿ é ãTownsOS V2.1以éåãã386 CPUã§ãä¸å¿åãããã¼ã¬ã¾|å ¨ç»é¢è¨å®ã§ã¯8ï½10fpsãããã¬ã¼ã ã¬ã¼ããåºãªãã¨æãã¾ããFM TOWNS II HR (486 20MHz)以ä¸ã§FASTã¢ã¼ãè¨å®èµ·åãä¸å¿æ¨å¥¨ã
FM TOWNSã¨ãã¥ã¬ã¼ã¿ã津軽ãã§äºæBIOSã使ç¨ãã¦CPU 66MHzè¨å®(FM TOWNS II MXç¸å½)ã®ãã¬ã¤åç»ãYM3812ç¨ã®é³æºãã¼ã¿ãç¡çããYM2612(FM TOWNSã®FMé³æº)ã«æµãã¦ããé¢ä¿ä¸ããã©ã é³ãç¡ãã£ããããªããªé³´ãæ¹ã ãã¨ããããé³æ¥½ã¯é³´ãããå¹æé³ãããããªã ãããããªãªã¸ãã«çã«ã¯åå¨ããªããGraphicsãã¨ããããªãã·ã§ã³é ç®ã追å ãæãªããè¬ã®å®æ度ã
ã²ã¼ã ãå®è¡ããã«ã¯è£½åçWolfenstein 3Dã®ã²ã¼ã ãã¼ã¿ãå¿ è¦ã§ããSteamãGOGãªã©ã§å£²ã£ã¦ãã(MSã¹ãã¢çã¯ãã¼ã¿ãã³ãã¼ã§ãããæªç¢ºèª)ã®ã§ãæã£ã¦ãã人ã¯ä¸ã®æ¡å¼µå.WL6群(CONFIG.WL6é¤ã)ãWOLF4FMT.EXPã¨åããã£ã¬ã¯ããªã«å ¥ãã¦FM TOWNS OSä¸ã§å®è¡ããã°éã¹ããã
ã¯ããããããããããããªæéããããã¨ãããªãä»ã©ãã®PCã§ãECWolfã使ã£ã¦éã¹ã°ãããï¼ã¨ããæ£è«ã¯ãã¡ããã¡ã
Â
ã¨ããã§ãªãã§ãããªãã®ãä½ã£ã¦ãã¾ã£ããã¨ããã¨ãäºã®çºç«¯ã¯FM TOWNSçDOOMãä½ã£ãã¨ãã®è¨äºã§ã³ã¡ã³ãæ¬ã«ãWolfenstein 3Dãã¯ç§»æ¤ã§ããï¼ã¨ãã質åãæ¥ããã¨ã
DOOMã¨éããWolfenstein 3Dã¯æãå ¥ãã¯ãªãããIBM PCç¹åã®ã½ã¼ã¹ã³ã¼ãã¨ãªã£ã¦ãã¦ç§»æ¤ãé¢åã ã£ãã®ã§ããäºå®ã¯ãªãã£ãã®ã ããDOSã¨ã¯ã¹ãã³ããçµç±ãã¦32bitããã°ã©ã ãåããã¦ããFM TOWNSã¨åãããã«DOSã¨ã¯ã¹ãã³ãã§32bitåãããWolf4GWãã¨ããã³ã¼ããå ¬éããã¦ããã®ã§ããããã¼ã¹ã«ç§»æ¤ãã¦ããã°ãããã®ã§ã¯ï¼ã¨ã¡ãã£ã¨éãå·®ãã¦ææ¦ãã¦ã¿ãã®ã1å¹´åãä»ããããã¾ããã1å¹´åã§ããããé å¼µã£ã¦ã¿ããã®ã®ã©ããã£ã¦ãã²ã¼ã éå§ç´å¾ã«ããªã¼ãºããããã°ã©ãã£ãã¯ãåå²ããã¦è¡¨ç¤ºããããã°ãåããããã®ãã¡ç§»æ¤ä½æ¥ãé¢åã«ãªã£ã¦æ¾ç½®ãã¦ããã®ã ããä»å¹´ã«å ¥ããCELESTEãããããããï½ã±ãã¨ä½ã£ã¦ãã¦ç´æ¥VRAMãå¼ã£ã¦FM TOWNSã®ã°ã©ãã£ãã¯æç»ãã§ããããã«ãªã£ãã®ã ããããã¡ãã£ã¨é å¼µãã°ã§ãããããã¨ãªãã¨ãããæ°ãæ¯ãçµã£ã¦åéã
ä»ã¾ã§å¼ã£ãã³ã¼ããå ¨é¨ç ´æ£ãã¦ãã°ã®åå ãããããè¦ã¤ããæ¥ã«æ¥ã«ç¾ããæ°ä½ã²ã¼ã (ãDead Space(2023)ãããã°ã¯ã¼ãã»ã¬ã¬ã·ã¼ããé¾ãå¦ã ç¶æ° 極ãããã¤ãªãã¶ã¼ã RE:4ããã©ã¤ã¶ã®ã¢ããªã¨3ããForza Horizon 5 Rally Adventureã)ããã¬ã¤ãã¦ä½åº¦ãä½æ¥ãä¸æãããªããã¨ããããéã¹ãã¬ãã«ã®ãã¬ã¼ã ã¬ã¼ãã»é³ããã§åãããç¶æ ã«ã¾ã§ã§ãã¾ããã
æ¬å½ã¯FM TOWNS ãã¼ãã£ã¼ã§ãåãããããã«ãã¼ã¸ã³ã°æ¹å¼ã®ãã¼ã¿ç®¡ç(ã¡ã¢ãªãå°ãªãç°å¢ã§ã¯ä¸é¨ã®ãã¼ã¿ã ãèªã¿è¾¼ãã§ããã¦ãå¿ è¦ã«ãªã£ããå ¥ãæ¿ãã)æ¹æ³ãå®è£ ããäºå®ã ã£ãã®ã ããæ£ç´æãå ¥ãããªãWolfenstein 3Dã移æ¤ããä½æ¥èªä½ããªããªãã¢ããã¼ã·ã§ã³ãä¸ãããªãã®ã«ããããã¾ãæãå ¥ãããªãFM TOWNS ãã¼ãã£ã¼ã¨ãããæ©ç¨®ã«å¯¾å¿ãããã®ã¯é¢åãä»®ã«å®è£ ã§ããã¨ãã¦CDããã®ãã¼ã¿èªã¿è¾¼ã¿ãªã®ã§ã²ã¼ã ä¸ã«ä½åº¦ãèªã¿è¾¼ã¿ã§åæ¢ãã¦ã²ã¼ã ã«ãªããªãã®ãåããåã£ã¦ããã®ã§ããã«ãã¾ãããã½ã¼ã¹ã³ã¼ãã¯ããã®ã§ãã¼ãã£ã¼å¯¾å¿çã欲ãã人ã¯èªåã§ä½ã£ã¦ãã ãã(ããªã)ã
追è¨ï¼ãã®å¾FM TOWNS ãã¼ãã£ã¼å¯¾å¿çãä½æ
Â
ã¡ãªã¿ã«ãä½æ ä»ã¾ã§åããªãã£ãã¨ããã¨
fixed sintable[ANGLES+ANGLES/4];
fixed *costable = sintable+(ANGLES/4);
ã¨ããSINå¤ãCOSå¤ãæ ¼ç´ããã°ãã¼ãã«é åã®å®£è¨ããã£ã¦ããã®è¨è¿°ã®éãCOSã®å¤ã¯SINã®ä¸é¨ã¨éè¤ãããã¨ãå©ç¨ãã¦SINé åãå ±æãã¦ã¡ã¢ãªç¯ç´ãå ã½ã¼ã¹ã§ã¯è¡ã£ã¦ããã®ã ãããã®è¨è¿°ã¯FM TOWNSã®High Cã³ã³ãã¤ã©ã§ã¯ãcostableã®å é ã®ã¿ã«ç¾æç¹ã®sintable+(ANGLES/4)ã®å¤ãæ ¼ç´ãããã ããã§SINã¨å ±æãããªãã
宣è¨æã«åæã«ãã¤ã³ã¿å ã示ãä¸è¨ã®æ¸ãæ¹ã ã¨
fixed sintable[ANGLES+ANGLES/4];
fixed *costable;*costable = sintable+(ANGLES/4)
ã®ãããªè§£éããããæ§ã ã
sintableã®ä¸èº«ãåæåããé¢æ°å ã§costable = sintable+(ANGLES/4);ã¨è¨è¼ããã¨ãããè¦äºåãã¦ãããã
Â
ATMã§ããã¸ã«ã¡ã§ããªãã«ã§ã移æ¤ããã¦ãããDOOMãã¨éããè¦ãç®çã«è² è·ãå°ãªãããã ããå¤ãã®ã§å®è£ ãç°¡åãããªã®ã«æ®ã©æå¿ç§»æ¤ããªããWolfenstein 3Dãã®ã³ã¼ãã解説ã
ã²ã¼ã èªä½ã¯IBM-PCåãã«åºãããã®ã®NeXT Computerä¸ã§ã¯ãã¹éçºãè¡ã£ã¦ããé¢ä¿ã§æ©ç¨®ä¾åã¨ãªããããªé¨åã¯æ¥µåæãããã¦ãããDOOMãã¨éãããWolfenstein 3Dãã¯ã²ã¼ã ã®å®è¡ç°å¢ãéçºç°å¢ãIBM PCãã½ã¼ã¹ã³ã¼ãã¯Cè¨èªãªãã®ã®16bitããã°ã©ã ãåããDOS&80286ç°å¢ã¨ãããã¨ã§64KBæ¯ã«ã¡ã¢ãªç©ºéãåããã¦ãããã¤ã³ã¿ãæä½ãããé«éåã®ããã«x86ã¢ã»ã³ãã©é¨åã¯å ¨ä½ã®10%以ä¸ããããé«éåã®ããã«VGAã°ã©ãã£ãã¯å°ç¨æ©è½ã使ãã¨ããç¶æ³ãæ°ãã¡ã¤ã«æ¸ãæããã°ãã®ãã·ã³ç¨ã«ç§»æ¤ã§ããDOOMã¨éããWolfenstein 3Dã¯æ¸ãæãä½æ¥ãç¸å½é¢åã
FM TOWNS移æ¤çã§ã¯32bitçã¨ãªããWolf4GWãããã¼ã¹ã«ãããã¨ã§32bitã¡ã¢ãªç©ºéããªãã¢ã«ä½¿ããé¢åãªã¡ã¢ãªæä½é¨åãä¸é¨ã¢ã»ã³ãã©é¨åãCã«ç½®ãæãããã¦ããã®ã§ç§»æ¤è² è·ãæ¸ã£ãããããã§ãVGAå°ç¨æ©è½ã使ã£ãé¨åãé¢åã ã£ãã
ã¾ãVRAMä¸ã§ã®ãã¯ã»ã«æ¯ã®ä¸¦ã³é ã
0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F
ã¨ãã¤ãæ¯ã«ä¸¦ãã§ããã°ããã®ã ãVGAã ã¨256KBã®VRAM空éã64KBã§ãã³ã¯åå²ããã¦ããé¢ä¿ã§Wolfenstein 3Då´ã®ãã¼ã¿ã¯
0|4|8|Cï¿¥1|5|9|Dï¿¥2|6|A|Eï¿¥3|7|B|F (ï¿¥ã¯ãã³ã¯åæ¿é¨å)
ã®ãããªå½¢ã¨ãªã£ã¦ããããããã®ã¾ã¾ã*vram++ = *source++;ãã¨ãããå½¢ã§VRAMã«å±éããã¨ã
ã¨ããã£ã½ããã®ã®ã¡ãã£ã¯ãã£ãªç»åã表示ãããã
ããã§
  int width_2 = width >> 2;
  int offset = VRAMWIDTH - width;
  int y2 = 0;  for(y = 0;y < height; y++)
  {
    for(x = 0;x < width;x++)
    {
      *vram++ = source[(y2 + (x >> 2)) + (x & 3) *  width_2 * height];
    }
    vram += offset;
    y2 += width_2;
  }
}
Â
ã¨ããã(y2 + (x >> 2)) + (x & 3) * width_2 * heightãã¨è¨ç®ãã¦ããã½ã¼ã¹å ã®ãã¼ã¿ãåå¾ãããã¨ã§
ã¨æ£å¸¸ã«è¡¨ç¤ºãããããã«ãªã£ãã
Â
é«éåã«ã¤ãã¦ãVGAã«ã¯1ãã¤ãæ¸ãè¾¼ãã°ãã³ã¯åæ¿ããå¥ã®ãã³ã¯ã®åãã¢ãã¬ã¹ã«ãåãå¤ãæ¸ãè¾¼ããæ©è½(ã¤ã¾ãæ大4ãã¯ã»ã«åä¸åº¦ã«æ´æ°å¯è½)ããããWolfenstein 3Dã§ã¯å·¦æ¨ªå´ãã縦ä¸åãã¤ã°ã©ãã£ãã¯ãæç»ããã®ã§ããã次ã®ãã¯ã»ã«ã§ãåãã°ã©ãã£ãã¯ãæããããã¨ãåãã£ãå ´åã
ifã(ã(pixx&3) && texture == lasttexture) //åã®ç¸¦åã®ãã¯ã¹ãã£ã¨å·®ç°ããªãå ´å
{
    postwidth++;
    wallheight[pixx] = wallheight[pixx-1]; //åã®å£ã®é«ãããã®ã¾ã¾å ¥ãã
    return;
}
ScalePost(); //å£ãæç»ããé¢æ°ãwallheighté åã®é«ãåæããã
wallheight[pixx] = CalcHeight(); //ä¸»äººå ¬ã®è¦ç¹ããã®å£ã¾ã§ã®å¥¥è¡ãããæãå£ã®ãã¯ã»ã«æ°ãè¨ç®ãã¦å ¥ãã
postsource+=texture-lasttexture;
postwidth=1;
postx=pixx;
lasttexture=texture;
return;
ã¨ããããã«å£æç»é¢æ°(ScalePost)èªä½ãé£ã°ãã¦ãæç»é¢æ°å ã§ã¯ãVGAMAPMASK(masks[postwidth-1][postx&3]);ãã¨è¨è¼ãããã¯ãã§ãã³ã¯åææ¸ãè¾¼ã¿ã®ã¬ã¸ã¹ã¿ãå¤æ´ãã¦ãå¾ãã1ï½4ååæ¸ãã¦ãã¾ãé 延æç»ãè¡ã£ã¦ããã
ã ãããã³ã¯åæ¿ãä¸è¦ã§ãªãã¢ã«VRAMã並ãã§ããFM TOWNSã«ã¯ãã¡ãããããªæ©è½ã¯ãªã(ããã®ã¯æå®ãããã®æ¸ãè¾¼ã¿ãç¦æ¢ãããã¹ã¯æ©è½ã®ã¿ï¼)ã
ãã®æç¹ã§åãCPUé度ã ã£ãã¨ãã¦ãé度ãåºãªãã¨ãããã®ã§ãå¥ã®æ段ã§é«éåã
ç»è³ªã¯è«¦ãã¦æ¨ªè§£å度ãååã¨ãã¦1ãã¤ãæ¯ã«æ¸ãè¾¼ã¾ãä¸æ°ã«2ãã¤ãæ¸ãè¾¼ãã§ãã¾ããæ´ã«ãã¯ã¹ãã£åº§æ¨ã®åå¾æ¹æ³ãå¤æ´ãããã¼ã¬ã¾ã¢ã¼ããæ°è¨ããã
void ScalePost_Low(void)
{
  _Far word *vram;
  _FP_SEG(vram) = 0x10c;
  _FP_OFF(vram) = 0x0;  int ywcount, yoffs, yendoffs;
  fixed frac, fracstep;
  int height;
  word col;
  height = wallheight[postx];  ywcount = height >> 3;
  fracstep = 16777216 / height;
  yendoffs = (viewheight >> 1) + ywcount;
  if(yendoffs >= viewheight)
  {
    yendoffs = viewheight;
    frac = (((height >> 2) - viewheight) >> 1) * fracstep;
  }else
  {
    frac = 0x4000;
  }  yoffs = _max(((viewheight >> 1) - ywcount), 0);
  ywcount = yendoffs - yoffs;
  vram += (ã(yoffs * SCREENWIDTH_WORD + (postx >> 1)) + (vbuf >> 1)); // << 9 = * SCREENWIDTH_WORD
  do
  {
    *((byte *)&col+1) = *(byte *)&col = postsource[frac >> 16];
    *vram = col;    vram += SCREENWIDTH_WORD;
    frac += fracstep;
  }while(--ywcount);
}
ãã¯ã¹ãã£è§£å度(64ããã)/å£ã®é«ã(wallheight)ã§ãã¯ã»ã«æ¯ã®å°æ°ããã®ç§»åãããæ°(fracstep)ãå²ãåºãã¦æç»ãã¯ã»ã«æ¯ã«å ç®âæ´æ°é¨ã®ã¿åãåºãã¦æ±ãããã¨ãã§ãããã16777216ã¨ããæ°åã¯ãã¯ã¹ãã£ã®è§£å度ã64ããããå£ã®é«ããã¯ã»ã«ãæ ¼ç´ããwallheightãå°æ°é¨3ãããã®åºå®å°æ°ç¹ãæ´ã«æ¡æ°ãé«ãã¦ç²¾åº¦ãä¸ããããã«ãã®æ°åã«ãã¦ãã(å°æ°é¨16ããã)ã
精度ã®åé¡ã§ä¸¦ã³ããºã¬ã¦å°ãã¸ã£ã®ã¼ãåºã¦ãã¾ããã解å度èªä½ç¸®å°ãã¦ããé¢ä¿ã§ããã¾ã§ç®ç«ã¤ãããªæãã§ã¯ãªãã£ããä¸»äººå ¬ã¨å£ã¨ã®è·é¢ãæ±ããã¬ã¤ãã£ã¹ãèªä½ã®è¨ç®èªä½ç«¯æã£ã¦ããããããã ãã§ä¸æ°ã«2åè¿ããã¬ã¼ã ã¬ã¼ããåä¸ãä¸å¿ãªãªã¸ãã«éãã®è§£å度ã¨æç»æ¹æ³ã«ãåãæ¿ãããã¨ãã§ãã(Graphicsãªãã·ã§ã³ããLow-Res Modeãã°ã«ãåãæ¿ã)
æ°è¨ããã°ã©ãã£ãã¯ãªãã·ã§ã³
Â
ãªãªã¸ãã«éãã®è§£å度
Â
ãã¼ã¬ã¾ã¢ã¼ã
å£ãè¥å¹²èããªããã®ã®è·é¢ã«ãã£ã¦ã¯ç®ç«ããªãããå£ä»¥å¤ã®ã¹ãã©ã¤ãã¯è§£å度ã¯å¤ãã¦ããªãã