知乎周源微信

I had the pleasure of interviewing Pete Brown this last week and talking about the Silverlight 3 Commodore 64 Emulator he's been working on. He just launched the CodePlex site a few minutes ago (my time), but I've had the code for a while to play with. You can read Tim Heuer's blog post for details on how to get started with Silverlight 3 Beta and the tools you'd need or see some video of the emulator in action.

我很高兴在上周采访了Pete Brown,并谈到了他一直在研究的S​​ilverlight 3 Commodore 64 Emulator 。 他是在几分钟前(我的时间)刚刚启动CodePlex网站的,但是我已经有一段代码可以玩了。 您可以阅读Tim Heuer的博客文章,详细了解如何开始使用Silverlight 3 Beta和所需的工具,或者观看运行中的仿真器的一些视频。

Keep in mind that this is a labor of love that Pete's doing, and the code has been written in "gett'er done" mode, so it won't win any awards for aesthetic. A lot of the code as been ported directly over from Open Source C++ in the Frodo Emulator or from Sharp C64.

请记住,这是皮特(Pete)所做的一项热爱工作,并且该代码已以“完成”的方式编写,因此不会赢得任何美观方面的奖项。 许多代码直接从Frodo Emulator中的Open Source C ++或Sharp C64移植过来。

It does have some pretty clever ideas, though, and I thought I'd take a look at those in this Weekly Source Code (which I promise to make more Weekly, starting now).

不过,它确实有一些非常聪明的想法,我想我会看一下本“每周源代码” (我保证从现在开始,将使更多“每周” )中的那些想法。

动态创建视频流 (Dynamically Creating a Video Stream)

Pete wanted the screen to draw as fast as possible, which is 50Hz (50 times a second). He was originally creating PNGs or Bitmaps and throwing it up on the screen as fast as possible, but then a member of the Silverlight team suggesting "making a video." What did he mean by "making a video?" He suggested actually using a Silverlight MediaElement (the "video player" control) and acting as a DataSource for a video. He's dynamically creating a movie that never ends.

皮特希望屏幕尽可能快地绘制,即50Hz(每秒50次)。 他最初是创建PNG或位图,然后将其尽快投放到屏幕上,但是后来Silverlight小组的成员建议“制作视频”。 他所说的“制作视频”是什么意思? 他建议实际上使用Silverlight MediaElement(“视频播放器”控件)并充当视频的数据源。 他正在动态地创作一部永无止境的电影

This means the UI XAML is basically:

这意味着UI XAML基本上是:

<MediaElement x:Name="VideoDisplay"  Grid.Row="0"  Grid.Column="0"  VerticalAlignment="Top"  Stretch="Uniform"  IsHitTestVisible="False"  Margin="4" />

And in the code behind he creates a VideoMediaStreamSource the had blogged about here, deriving from MediaStreamSource:

然后,他在后面的代码中创建了一个VideoMediaStreamSource,该视频来自MediaStreamSource,该博客已在此处发布:

_video = new VideoMediaStreamSource(TheSID.Renderer.AudioStream, C64Display.DISPLAY_X, C64Display.DISPLAY_Y);

and it looks like:

它看起来像:

private byte[][] _frames = new byte[2][];public VideoMediaStreamSource(int frameWidth, int frameHeight){    _frameWidth = frameWidth;    _frameHeight = frameHeight;

    _framePixelSize = frameWidth * frameHeight;    _frameBufferSize = _framePixelSize * BytesPerPixel;

    // PAL is 50 frames per second    _frameTime = (int)TimeSpan.FromSeconds((double)1 / 50).Ticks;

    _frames[0] = new byte[_frameBufferSize];    _frames[1] = new byte[_frameBufferSize];

    _currentBufferFrame = 0;    _currentReadyFrame = 1;}

public void Flip(){    int f = _currentBufferFrame;    _currentBufferFrame = _currentReadyFrame;    _currentReadyFrame = f;}

When he wants to write a pixel to his buffer, as he often does at the low level:

当他想要一个像素写信给他的缓冲,因为他经常做在较低水平:

public void WritePixel(int position, Color color){    int offset = position * BytesPerPixel;

    _frames[_currentBufferFrame][offset++] = color.B;    _frames[_currentBufferFrame][offset++] = color.G;    _frames[_currentBufferFrame][offset++] = color.R;    _frames[_currentBufferFrame][offset++] = color.A;

}

When it comes time to get a sample, the MediaSteamSource calls GetSampleAsync:

当需要获取样本时,MediaSteamSource调用GetSampleAsync:

protected override void GetSampleAsync(MediaStreamType mediaStreamType){    if (mediaStreamType == MediaStreamType.Audio)    {        GetAudioSample();    }    else if (mediaStreamType == MediaStreamType.Video)    {        GetVideoSample();    }}

He grabs a video frame from his buffer, he make a sample and reports he's done:

他从缓冲区中抓取一个视频帧,制作了一个样本并报告了他的完成:

private void GetVideoSample(){    _frameStream = new MemoryStream();    _frameStream.Write(_frames[_currentReadyFrame], 0, _frameBufferSize);

    // Send out the next sample    MediaStreamSample msSamp = new MediaStreamSample(        _videoDesc,        _frameStream,        0,        _frameBufferSize,        _currentVideoTimeStamp,        _emptySampleDict);

    _currentVideoTimeStamp += _frameTime;

    ReportGetSampleCompleted(msSamp);}

His app makes frames as fast as they can, putting them in the buffer at 50Hz, and the MediaElement requests frames from his VideoMediaStreamSource as fast as it can take them.

他的应用程序以最快的速度制作帧,并将其以50Hz的频率放入缓冲区,并且MediaElement尽可能快地从他的VideoMediaStreamSource请求帧。

模拟1541磁盘驱动器 (Emulating a 1541 Disk Drive)

There's a file format in the world of C64 emulators that everyone has standardized on called .d64. The D64Drive.cs file contains the meat of the code to read these image files. "The *.D64 file format is a 1:1 copy of all sectors as they appear on a floppy disk."

C64仿真器世界中有一种文件格式,每个人都对此格式进行了标准化,称为.d64。 D64Drive.cs文件包含读取这些图像文件的代码段。 “ * .D64文件格式是所有扇区出现在软盘上的1:1副本。 ”

Most of it looks like C/C++ code, because it once was. Some of it used to be "unsafe" C# code, writing with the unsafe keyword so the runtime could pin down pointers and use them directly.

因为它曾经是,所以大多数看起来像C / C ++代码。 其中一些曾经是“不安全的” C#代码,使用unsafe关键字编写,因此运行时可以固定指针并直接使用它们。

I love it when there's things like byte[] magic. ;) Seems like every binary file format has them. In this case, we're looking for 0x43, 0x15, 0x41 and 0x64. Notice that 0x43 is "C", while the second and third bites are "1541" with the final "64" in there. ;)

当有byte []魔术之类的东西时,我会喜欢它。 ;)似乎每种二进制文件格式都有它们。 在这种情况下,我们正在寻找0x43、0x15、0x41和0x64。 请注意,0x43是“ C”,而第二和第三位是“ 1541”,最后是“ 64”。 ;)

private void open_close_d64_file(string d64name, Stream fileStream){    long size;    byte[] magic = new byte[4];

    // Close old .d64, if open    if (the_file != null)    {        close_all_channels();        the_file.Dispose();        the_file = null;    }

    // Open new .d64 file    if (fileStream != null)    {        //the_file = new FileStream(d64name, FileMode.Open, FileAccess.Read);        the_file = fileStream;

        // Check length        size = the_file.Length;

        // Check length        if (size < NUM_SECTORS * 256)        {            the_file.Dispose();            the_file = null;            return;        }

        // x64 image?        the_file.Read(magic, 0, 4);        if (magic[0] == 0x43 && magic[1] == 0x15 && magic[2] == 0x41 && magic[3] == 0x64)            image_header = 64;        else            image_header = 0;

        // Preset error info (all sectors no error)        Array.Clear(error_info, 0, error_info.Length);

        // Load sector error info from .d64 file, if present        if (image_header == 0 && size == NUM_SECTORS * 257)        {            the_file.Seek(NUM_SECTORS * 256, SeekOrigin.Begin);            the_file.Read(error_info, 0, NUM_SECTORS);        }    }}

This is all fun stuff, but as Pete said to me in an email:

这些都是好玩的东西,但正如Pete在电子邮件中对我说的那样:

"PS. My “real” code *never* looks like this. This is full of c++-isms and just plain “let me see if I can get this to work” junk."

“ PS。我的“真实”代码*从来没有*看起来像这样。它充满了c ++-isms,只是“让我看看我是否可以使它工作”。

So, take it for what it is. It's awesome.

因此,按原样使用它。 这很棒。

References

参考文献

  • Frodo Emulator: http://frodo.cebix.net/

    Frodo模拟器: http : //frodo.cebix.net/

  • Sharp C64: http://sourceforge.net/projects/sharp-c64

    夏普C64: http : //sourceforge.net/projects/sharp-c64

  • Video of the Emulator in action

    仿真器的视频

翻译自: https://www.hanselman.com/blog/the-weekly-source-code-39-commodore-64-emulator-in-silverlight-3

知乎周源微信

知乎周源微信_每周源代码39-Silverlight 3中的Commodore 64仿真器相关推荐

  1. 知乎周源微信_每周源代码7

    知乎周源微信 In my new ongoing quest to read source code to be a better developer, I now present the seven ...

  2. 知乎周源微信_每周源代码36-PDC,BabySmash和Silverlight图表

    知乎周源微信 First, let me remind you that in my new ongoing quest to read source code to be a better deve ...

  3. 知乎周源微信_每周源代码33-Google Chrome中的Microsoft Open Source

    知乎周源微信 First, let me remind you that in my new ongoing quest to read source code to be a better deve ...

  4. 知乎周源微信_每周源代码42-树修剪,插件和MEF

    知乎周源微信 I really advocate folks reading as much source as they can because you become a better writer ...

  5. 知乎周源微信_每周源代码56-Visual Studio 2010和.NET Framework 4培训套件-代码合同,并行框架和COM互操作...

    知乎周源微信 Do you like a big pile of source code? Well, there is an imperial buttload of source in the V ...

  6. 知乎周源微信_每周源代码24-可扩展性版本-.NET中的插件,提供程序,属性,插件和模块...

    知乎周源微信 I've been getting more and more interested in how folks extend their applications using plugi ...

  7. 知乎周源微信_每周源代码59-开源宝藏:具有讽刺意味的.NET语言实现工具包

    知乎周源微信 One of the best, if not the best way to sharpen the saw and keep your software development sk ...

  8. 知乎周源微信_每周源代码18-深度缩放(Seadragon)Silverlight 2 MultiScaleImage鼠标滚轮缩放和平移版...

    知乎周源微信 Dear Reader, I present to you eighteenth in a infinite number of posts of "The Weekly So ...

  9. 知乎周源微信_每周源代码30-具有XML文字的VB.NET作为ASP.NET MVC的视图引擎

    知乎周源微信 I was literally in the middle of writing the post when I saw a message from Andrew Davey abou ...

最新文章

  1. MICROSOFT SQLSERVER 总结
  2. redis 的一主二从三哨兵模式
  3. 趣谈网络协议笔记-零
  4. 一篇文章教你弄懂SpringMvc中的HttpMessageConverter
  5. android选项菜单源代码,Android应用程序----UI界面控件(菜单menu)
  6. java 数组的冒泡排序
  7. log4j.properties 使用
  8. windows media services 2008外网无法访问
  9. maya对象属性_了解每粒子属性和每对象属性
  10. Redis入门到入土教程_2 远程连接redis
  11. 书单|互联网企业面试案头书之架构师篇
  12. 删除root 家目录,及恢复方法
  13. MT4指标三线KDJ指标下载
  14. namedpipe资料 政治课报告3000字 base64编码 《近世代数引论》冯克勤 P 1-5 - 学习记录 2020/6/5
  15. 世界各国时区表以及与北京时差
  16. 把自己的博客推荐到百度、Google等主要搜索引擎
  17. scratch编程 飞翔的小鸟 开发笔记 0604
  18. 开一间煎饼果子店能挣多少钱?
  19. 宏定义语句的 GPBCON 、GPBDAT、GPBUP 地址(老师布置的作业,没接触过,不懂,求大神解答,万分感谢)
  20. C语言找出数组中最小的数和它的下标

热门文章

  1. Springboot毕业设计毕设作品,车辆大全和AI车牌识别系统
  2. Bzoj1233 [Usaco2009Open]干草堆tower
  3. Java版Word开发工具Aspose.Words基础转换指南:将Word文档和图像转换为PDF
  4. SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  5. java搜索excel表格里的数据_Java读取Excel表格中的数据
  6. 激光雷达传感器以及运动畸变去除
  7. 游戏是如何打动用户的?
  8. uni-app,微信小程序实现全局水印
  9. WPF Grid跨行、跨列
  10. win10夜间模式无效替代解决方案