![](https://habrastorage.org/getpro/habr/post_images/1a8/644/5a2/1a86445a2214e7b61946ec364bfa20a4.gif)
ç§ã¯åŠæ ¡ã®æéã®ããã«ç§ã®ãœãŒã¹ã³ãŒãã§äžåºŠæŽè¡ããããã§ä»¥äžãèŠã€ããŸããïŒ
- å°ææãæã€å®å®è¹ã«é¢ããQBasicã²ãŒã ã dosã®äžã®äžæ°å³ãªã³ãŒãã§ãããã¹ãã©ã€ãã¯3ds Maxã§ã¢ãã¡ãŒã·ã§ã³åãããŸãã
- Pascal / Assemblerã°ã©ãã£ãã¯ã©ã€ãã©ãªãé«éã§
- Win32ã§ã³ãŒããã³ã³ãã€ã«ã§ããã©ã€ã»ã³ã¹ãããTMT Pascalã³ã³ãã€ã©
ç¡é§ã«ããªãã§ãã ããïŒ æ¬¡ã¯ãããããã¹ãŠã®ã¹ããŒãªãŒãå°ãæããã話ããããŠã°ã©ãã£ãã¯çšã®å€ãã¹ãã©ã€ããšã³ãŒãã䜿çšããã²ãŒã ã®ãã¢ãã³ãããŒãžã§ã³ã®å®è£ ã®è©³çŽ°ã§ãã
ã¡ãã£ãšããæŽå²
ããŒã·ãã¯
ç§ã¯æåã«Logo ããã®åŸBasicããããŠPascalãæããããåŠæ ¡ã§ããã°ã©ãã³ã°ã«åºäŒããŸããã
éçºã«èå³ãèµ·ãããã®ã¯Basicã§ããã¡ãããèªåã®ã²ãŒã ãæžãããã£ãã®ã§ãïŒ ãã®ã¹ã¯ãªãŒã³ã·ã§ããã¯ãæçš¿ã®åé ã«æ²èŒãããŠããŸãã 640x480ã256è²ããã¹ãŠã®ã¹ãã©ã€ãã¯ã¢ãã¡ãŒã·ã§ã³åïŒæ¬äŒŒ3Dã§å転ïŒããµãŠã³ãã Futureã©ã€ãã©ãªã䜿çšãããŸããïŒãqbasic futureãã§åŒãç¶ãGoogleã䜿çšã§ããŸãïŒã ãœãŒã¹ã³ãŒãã¯ä¿æãããŸã-1552è¡ãGOTOæŒç®åã®19åã®äœ¿çšã ãã®ã²ãŒã ã¯ã©ã³ããŒãšåŒã°ããææã«å®å®è¹ãçéžãããå¿ èŠãããå€å žçãªã²ãŒã ã«äŒŒãŠããŸãã ããããè¹ãçéžãããã®ã¯éå±ãªã®ã§ãç§ã¯æã£ãŠçç Žãããã®ã§ãçéžããåã«ã2çš®é¡ã®æŠåšãæèŒããå°ææ垯ãçªç Žããªããã°ãªããŸããã
圌ã¯èªåã§ã¹ãã©ã€ãã3DS Maxã§æããŸããïŒå°ææã¯ãã©ã¯ã¿ã«ãã€ãºã®ããçäœã§ãæ®ãã¯åçŽãªåœ¢ç¶ã®çµã¿åããã§ãççŒã«ããççºã§ãïŒã æ®å¿µãªããããœãŒã¹maxãã¡ã€ã«ã¯äœããã®åœ¢ã§å€±ãããŸããããã¬ã³ããªã³ã°ãããã¹ãã©ã€ãã¯ä¿æãããŸããã
ãã¹ã«ã«
次ã®ã¹ãããã¯ãã¹ã«ã«ã§ãã¢ã»ã³ãã©ãŒãçµã¿èŸŒãŸããŠããŸãã åŠæ ¡ã§ã¯ã386å°ã®ãã·ã³ã䜿çšããŠããŸããããã¢ã»ã³ãã©ãŒã€ã³ãµãŒãã®ãã€ã¯ãæé©åã®åããã¹ãŠæããŸããã REP MOWSWãä»ããã¹ãã©ã€ãåºåã¯ãPascalãµã€ã¯ã«ãããã¯ããã«é«éã«æ©èœããŸããã ã³ãŒãã®èª¿æŽãã·ããã«ããä¹ç®ãã¬ãžã¹ã¿ãŒã§ã®æ倧äœæ¥éãããã³ã¡ã¢ãªãŒã§ã®æå°äœæ¥éã
ä¿è·ã¢ãŒã
ãããã¯ãã¹ãŠéåžžã«èå³æ·±ãã楜ãããã®ã§ãããããã€ãã®ãã¢ãäœæãã Ralf Brownã®å²ã蟌ã¿ãªã¹ãã調ã¹ãSVGAã°ã©ãã£ãã¯ã¢ãŒããè©Šãã ãã³ã¯ã®åãæ¿ãã«èŠãã¿ãŸããã
ãããŠãããããã¹ãŠã®ãšã³ã¿ãŒãã€ã¡ã³ããã芧ã«ãªã£ãã³ã³ãã¥ãŒã¿ãŒãµã€ãšã³ã¹ã®å çïŒããããšãïŒããåžå ã®ã³ã³ãã¥ãŒã¿ãŒã·ã§ããã®å€§èŠæš¡ãããã¯ãŒã¯ã®PCã¢ã»ã³ããªéšéã§åããŠãã圌ã®å人ã«ç§ã玹ä»ããŸããã 圌ã¯ãDOSçšã®ã°ã©ãã£ã«ã«ã€ã³ã¿ãŒãã§ã€ã¹ãåãããœãããŠã§ã¢ãå¿ èŠãšããŠãããçµã¿ç«ãŠãããã³ã³ãã¥ãŒã¿ãŒã®ããŒããã©ã€ããç¹å®ã®æ¹æ³ã§æºåããŠããŸããã ããã°ã©ããŒãšããŠã®çã®ä»äºïŒ æåã®ã¿ã¹ã¯ã¯ããã¿ã³ãããã¹ããã£ãŒã«ããªã©ã§ãŠã£ã³ããŠã°ã©ãã£ãã¯ã¹ãäœæããããšã§ããã 確ãã«ãã®ãããªè§£æ±ºçã¯ãã§ã«ååšããŠããŸããããç§ã¯ããã«ã€ããŠãèãããèªåã®èªè»¢è»ãæžãããšã«ç±å¿ã§ããã
æåã®ã¹ãããã¯ãæ¢åã®ã¢ãžã¥ãŒã«ãä¿®æ£ããŠããªããã£ããæç»ããã¹ãã©ã€ããšããã¹ããåºåããããšã§ããã ã¢ã»ã³ããªã®ãã¹ãŠãæ¿å ¥ãããŸãã 次ã«ãWindowsã§Visual Basic 6ãéžæããçµéšãã»ãšãã©ãªãã£ããããPascalã§åæ§ã«ãŠã£ã³ããŠãšã³ã³ãããŒã«ãå®è£ ãããã°ããããŠããçµæã瀺ããŸããã
![](https://habrastorage.org/getpro/habr/post_images/6e4/736/697/6e4736697d8b0e640a210c35ef8a63dd.png)
ãã¹ãŠãæ©èœãããŠã£ã³ããŠããã©ãã°ãããã³ã³ãããŒã«ãMouseOverã«åå¿ããŸãã ããŒãã£ãªãŒãžã§ã³ãæç»ããWindowsã®ã¢ãããŒãã®ä»£ããã«ãç§ã¯å ã«é²ã¿ããã¹ãŠãåæç»ããŸãããã¢ã»ã³ãã©ã®ãããã§éåžžã«è¿ éã«æ©èœããŸããã
ããã«å¿ããŠã320x200ã¯è¯ããªããšèããã®ã§ããã¹ãŠã®èŠçŽ ããã®æç¹ã®Windows XPã®ããã«èŠããããã«ããå¿ èŠããããŸãã ãªã¢ã«ã¢ãŒãã§ã¯å€§ããªè§£å床ã§åé¡ãçºçããŸã.64ãããã€ã以äžã§ç·åœ¢ã«ã¢ãã¬ã¹æå®ã§ãããããé«è§£å床ã®ç»åã衚瀺ããã«ã¯ã ã¡ã¢ãªãã³ã¯ãåãæ¿ããå¿ èŠããããäžè¬ã«ååãªã¡ã¢ãªããããŸããïŒæªåé«ã640ãããã€ãïŒã ãã®ãããBorlandã®ã³ã³ãã€ã©ã¯TMT Pascalã«çœ®ãæããããŸãããããã¯ãdos4gwãä»ããŠ32ãããã§ããã«äœ¿çšã§ããä¿è·ã¢ãŒãã«ãªããŸãã ããã«ãããã¡ã¢ãªãšã°ã©ãã£ãã¯ã®åé¡ã解決ãããã€ã³ã¿ãŒãã§ã€ã¹ãåæç»ãããããžãã¹ããžãã¯ãæ®åœ±ããããããžã§ã¯ããå®äºããŸããã ããã¯ãã§ã«ãããã¯ããã®éžè±ã§ããããã詳现ã«ã¯è§ŠããŸããã
![](https://habrastorage.org/getpro/habr/post_images/c11/1bf/3fc/c111bf3fc6d5fab437a1f3bea5bb203b.png)
ç§ãã¡ã®æ¥ã
ããã¯ã¢ããã䞊ã¹æ¿ãããšãå€ãã³ãŒããèŠã€ãããŸããã 圌ã¯DOSBoxãæã«å ¥ãããããéå§ããå¹³åçãªæ¶ãäžæããã é·å¹ŽåŸãCïŒã¯åã³ãéã«è¿ãããšæãããã£ãã ãããã£ãŠãèšç»ãäœæãããŸãããã¢ã»ã³ãã©ã³ãŒãã䜿çšããŠã¡ã¢ãªã«ã°ã©ãã£ãã¯ãæç»ããçµæãWPFã«åºåããŸãã TMT Pascalã¯Win32 dllããã«ãã§ããŸãããããããªå€æŽã®ã¿ã§æžã¿ãŸãïŒäœåãªãã®ãæšãŠã眲åã«stdcallãè¿œå ããŸãïŒã
ããšãã°ãéæ床ã®ããã¹ãã©ã€ãåºåã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãïŒTransparentColorã®ã«ã©ãŒãã¯ã»ã«ã¯åºåãããŸããïŒã
ããªãã¯ã°ã©ã¹ãªãã§ãããç解ããããšã¯ã§ããŸãããã³ã¡ã³ãã¯ãªãªãžãã«ã§ã
Procedure tPut32 conv arg_stdcall (X,Y,TransparentColor:DWord;Arr:Pointer);Assembler; {Transparent PUT} Var IMSX, IMSY :DWord; Asm Cmp Arr, 0 Je @ExitSub {Check ON-SCREEN POS} Mov Eax, ScreenSY; Mov Ebx, ScreenSX Cmp Y, Eax; Jl @PUT1; Jmp @ExitSub; @PUT1: Cmp X, Ebx; Jl @PUT2; Jmp @ExitSub; @PUT2: {--------} Mov Edi, LFBMem {Set Destination Loct} {Get Sizes} Mov Esi, Arr LodsD; Mov IMSX, Eax LodsD; Mov IMSY, Eax Add Esi, SizeOfSprite-8 {Check ON-SCREEN POS} Mov Eax, IMSY; Neg Eax; Cmp Eax, Y; Jl @PUT3; Jmp @ExitSub; @PUT3: Mov Eax, IMSX; Neg Eax; Cmp Eax, X; Jl @PUT4; Jmp @ExitSub; @PUT4: {VERTICAL Clipping} Mov Eax, Y {Clipping Bottom} Add Eax, IMSY Cmp Eax, ScreenSY Jl @SkipClipYB Sub Eax, ScreenSY Cmp Eax, IMSY Jl @DoClipYB Jmp @ExitSub @DoClipYB: Sub IMSY, Eax @SkipClipYB: Cmp Y, -1 {Clipping Top} Jg @SkipClipYT Xor Eax, Eax Sub Eax, Y Cmp Eax, IMSY Jl @DoClipYT Jmp @ExitSub @DoClipYT: Sub IMSY, Eax Add Y, Eax Mov Ebx, IMSX Mul Ebx Shl Eax, 2 {<>} Add Esi, Eax @SkipClipYT: {End Clipping} {Calculate Destination MemLocation} Mov Eax, Y; Mov Ebx, ScreenSX; Mul Ebx Add Eax, X Shl Eax, 2 {<>} Add Edi, Eax Mov Ecx, IMSY {Size Y} Mov Ebx, IMSX {Size X} Mov Edx, ScreenSX Sub Edx, Ebx {HORIZ.CLIPPING} Push Edx Xor Eax, Eax {RIGHT} Sub Edx, X Cmp Edx, 0 Jge @NoClip1 {IF EDX>=0 THEN JUMP} Mov Eax, Edx; Neg Eax; Sub Ebx, Eax @NoClip1: Pop Edx {LEFT} Cmp X, 0 Jge @NoClip2 Sub Edi, X; Sub Esi, X // \ Sub Edi, X; Sub Esi, X // \ Sub Edi, X; Sub Esi, X // 32 bit!!! Sub Edi, X; Sub Esi, X // / Sub Eax, X; Sub Ebx, Eax @NoClip2: {bitshifts} Shl Eax, 2 {<>} Shl Edx, 2 {<>} ALIGN 4 @PutLn: {DRAW!!!!!} Push Ecx; Push Eax; Mov Ecx, Ebx ALIGN 4 @PutDot: LodsD; Cmp Eax, TransparentColor //Test Al, Al Je @NextDot {if Al==0} StosD; Sub Edi, 4 {<>} @NextDot: Add Edi, 4 {<>} Dec Ecx; Jnz @PutDot {Looping is SLOW} Pop Eax; Add Esi, Eax Add Edi, Edx; Add Edi, Eax Pop Ecx Dec Ecx; Jnz @PutLn {Looping is SLOW} @ExitSub: End;
æ®ãã®ã³ãŒãã¯ãã¡ãïŒ code.google.com/p/lander-net/source/browse/trunk/tmt_pascal/TG_32bit.pas
CïŒ
ãã®åŸããã¹ã¿ã«ãžã¢ã¯çµäºããå®è£ ã®è©³çŽ°ã«é²ã¿ãŸãã ã¹ãããããŠãæçš¿ã®æåŸã«ããã²ãŒã ãã¬ã€ãããªãšããŠã³ããŒããªã³ã¯ã«çŽæ¥ã¢ã¯ã»ã¹ã§ããŸãã
Google Codeã®ãããžã§ã¯ãããŒãžïŒ code.google.com/p/lander-net
é¢æ°ã¯ãDllImportãä»ããŠæšæºçã«ã€ã³ããŒããããŸã
[DllImport("TPSGRAPH", CallingConvention = CallingConvention.StdCall)] public static extern uint tPut32(uint x, uint y, uint transparentColor, uint spritePtr);
ã¹ãã©ã€ãã®ã¡ã¢ãªã¯ã管çãããŠããªãåŽã§å²ãåœãŠããã解æŸãããŸããããã¯ãMarshal.AllocHGlobalãä»ããŠå®è¡ã§ããŸãã ã¹ãã©ã€ãã¯æ¬¡ã®æ§é ã§ãïŒhaãããã®ãœãŒã¹ã¿ã°ã¯PascalããµããŒãããŠããŸãã-Delphiãèšè¿°ããŸãïŒã
Type TSprite = Packed record W : DWord; H : DWord; Bpp : DWord; RESERVED : Array[0..6] of DWORD; End;
ã¢ã³ãããŒãžé¢æ°InitSpriteã¯ã¡ã¢ãªãå²ãåœãŠãŠããããŒãåããFormatConvertedBitmapãšmemcpyã䜿çšããŠç®çã®åœ¢åŒã§ãã¯ã»ã«ãã³ããŒããŸãïŒ code.google.com/p/lander-net/source/browse/trunk/csharp/TpsGraphNet/Sprite.csãåç §ïŒã
ãããã£ãŠããã¬ãŒã ãããã¡ã«ãã·ãŒã³ããæç»ã§ããŸãã ããã§ãããã©ãŒãã³ã¹ã®ãããã©ã°ãåŸ ã£ãŠããŸããã ã¡ã¢ãªå ã®æ°çŸã®ã¹ãã©ã€ãã®FPSã¬ã³ããªã³ã°ã¯æ°ååäœã§æž¬å®ãããŸããããWindowsãŠã£ã³ããŠã«çµæããã°ãã衚瀺ããããšã¯ããã»ã©ç°¡åã§ã¯ãããŸããã§ããã WriteableBitmapãè©ŠããDirectXãïŒSlimDXãä»ããŠïŒè©ŠããŸããããInteropBitmapãä»ããŠæãè¿ éã«å€æããŸããïŒ Sprite.GetOrUpdateBitmapSource
public unsafe BitmapSource GetOrUpdateBitmapSource() { if (_bitmapSourcePtr == null) { var stride = Width*4; // Size of "horizontal row" var section = NativeMethods.CreateFileMapping(NativeMethods.INVALID_HANDLE_VALUE, IntPtr.Zero, (int) NativeMethods.PAGE_READWRITE, 0, (int) _sizeInBytes, null); _bitmapSource = Imaging.CreateBitmapSourceFromMemorySection(section, (int) Width, (int) Height, PixelFormats.Bgr32, (int) stride, 0); _bitmapSourcePtr = (uint)NativeMethods.MapViewOfFile(section, NativeMethods.FILE_MAP_ALL_ACCESS, 0, 0, _sizeInBytes).ToPointer(); NativeMethods.CloseHandle(section); NativeMethods.UnmapViewOfFile(section); } CopyPixelsTo((uint) _bitmapSourcePtr); return _bitmapSource; }
ã芧ã®ãšãããFileMappingã䜿çšããããŒã¯ããžãã¯ã¯1åã ãåŒã³åºããããŠã£ã³ããŠã«è¡šç€ºãããã¡ã¢ãªãžã®çŽæ¥ãã€ã³ã¿ãŒããããŸãã ä»»æã®ã¹ã¬ããããæŽæ°ã§ããŸããUIã¹ã¬ããã§ã¯ãInteropBitmap.InvalidateïŒïŒãåŒã³åºãã ãã§æžã¿ãŸãã
ããç¥ãããŠããLincoln6Echo WPFãWinFormsã®æ¹æ³ïŒBitmap c> 15000 FPSã®æç»ã§ã¯ããã«HDã¢ãã¿ãŒã§ãŠã£ã³ããŠãå šç»é¢ã«æ¡å€§ãããšãå®éã«ã¯120 fpsããåºåãããŸããã åãæ¡ä»¶ã§ã®InteropBitmapã¯ãã800 fpsãæäŸããŸãã CompositionTarget.Renderingã«ãã£ãŠåæãåé€ãããšãåããã·ã³ïŒã³ã¢i5ïŒã§å±éããããŠã£ã³ããŠã®ã²ãŒã èªäœã¯çŽ300 fpsã«ãªããŸãã
ãç»é¢ã®ç Žæããé床ã®CPUè² è·ãåé¿ããWPFã§æšæºã®60ãã¬ãŒã /ç§ã«ã¢ã¿ããããã«ã¯ãCompositionTarget.Renderingã€ãã³ãã䜿çšããŸãã ã¡ã€ã³ã¹ã¬ãããããŒããããWPFã«GameViewModel.RunGameLoopïŒïŒãå®è¡ãããããã«ãããã¯ã°ã©ãŠã³ãã¹ã¬ããã§ã¬ã³ããªã³ã°ãè¡ãããŸãã
WPFããŒã«ã䜿çšããã²ãŒã ç»åã®äžã«ãã²ãŒã æ å ±ïŒå¥åº·ãæŠåšããã€ã³ãïŒãç°¡åãã€å¿«é©ã«è¡šç€ºãããŸãïŒ MainWindow.xaml ã ã¹ã¯ãªãŒã³ã·ã§ããã§ã¯ã MMX ïŒ PADDUSBåœä»€ïŒã䜿çšããŠå®è£ ãããççºã®è¿œââå ãªãŒããŒã¬ã€ã確èªã§ããŸãã
![](https://habrastorage.org/getpro/habr/post_images/ce6/437/bbf/ce6437bbf1763acc1228af7dc72678a1.png)
ãã¹ãŠã®ã²ãŒã ããžãã¯ã¯CïŒã§è¡ãããŸãã 圌ã¯ãæ°Žå¹³ããåçŽã®ã¹ã¯ããŒã©ãŒã«å€æŽãããå°ææã§ã®å°æã ããæ®ããŸããã SlimDXã¯é³å£°ã®ã¿ã«äœ¿çšãããŸãã
ãŸãšã
ç§ã¯ã²ãŒã èªäœãçµããŸããã§ãã-èå³ã倱ãããäºçŽ°ãªã¿ã¹ã¯ãæ®ãã誰ãããããã¬ã€ããŸãã å€ãå·¥èžåã«æ°ããåœãå¹ã蟌ãããšãã§ããŠããã£ãã§ãã ãéã«è¿ãã-ãã¹ãŠã®ã¬ã³ããªã³ã°ã¯ãã¬ãŒã ã¯ãŒã¯ã«ãŸã£ããäŸåãããç¬ç«ããã¹ã¬ããã§å®è¡ãããŸããäž»ã«ã¡ã¢ãªã®åŠçé床ã«äŸåããŸãïŒãããã¡ã€ã©ãŒããïŒã¬ã³ããªã³ã°æéã®40ïŒ ããã¬ãŒã ãããã¡ãŒã®ã¯ãªãŒãã³ã°ã«ã40ïŒ ãInteropBitmapãžã®ã³ããŒã«è²»ããããŸãïŒ ã
GitHubïŒ github.com/kefir0/LanderNet
Googleã³ãŒãïŒ code.google.com/p/lander-net
ã³ã³ãã€ã«æžã¿ãã€ããªïŒwin32ïŒïŒ ge.tt/1YvTlAh1/v/0
ã²ãŒã ãã¬ã€ãããªïŒ