A huge jump of progress, & back at square 1?

Hello! What a busy week it has been, and I have some good things to share. In just over a little 3 days of time, I worked for a lot of time to implement the new idea I mentioned I had last week, and it was actually working quite well! I managed to implement the entire basic structure of it, as well as port over 8 of ScummVM's 79 engines to adapt to it!

So, what's the deal with this, and what did I do? The "idea" was just me getting a basic understanding of how things "could" work in a way.

Well, we were at the "createInstance" bridge where I left off last week. This is a member function of either a MetaEngine or an AdvanedMetaEngine class. The problem with this was this had engine code in it, so it couldn't be included in the executable. The basic idea around this was simply to remove it as a class - member function, and instead mark it as an export symbol. What we could then do, is in base class, provide a default functionality. These functions were a Pure Virtual Function, so I simply removed it in order to get what I wanted to achieve.

The "createInstance" method though, would only be exported if we were using a Dynamic-Plugins setup. If the entire engine would be to build into the executable, there wouldn't be any point in doing this, so for those, we still override the base class's function.

If a child class overrode this function, the vtable generated would point correctly to the createInstance method, and now the static plugins work as intended. If a child class didn't override this function, that would mean the class would use it's default implementation wherever used. What could we possibly do here? That's right, we can simply hook up plugins to find a symbol in the engine libraries we have loaded.

Before a game is actually started, we unload all engine-type plugins to save memory and then try to run the game. Running the game usually has the first step of instantiating the engine, so normally when we actually reach to the point where the default "createInstance" is called, we only have 1 engine plugin loaded as a library.

Then, the default implementation basically consisted of fetching this plugin and trying to load a symbol. We have 3 main plugin classes in ScummVM, "Plugins", "StaticPlugins" & "DynamicPlugins". When I fetch a plugin and try to call a function, it would need to be present in the relevant plugin interface, obviously. So, I made pure virtual functions in the Plugins class and overrode those in the Static & DynamicPlugins classes. This way, when I have a "Plugin *plugin", and I use a "plugin->tryInstantiateEngineFuncSymbol()", it looks up in the vtable and proceeds to call the one in DynamicPlugins, as it handles everything dynamic-related things.

Over there, the process is very simple. We find the symbol, and if we can find it, we call it. This way, the engines are instantiated, and then everything proceeds as usual because the bridge has been crossed.

Since we now have a difference between MetaEngines & Engines, they are given different PLUGIN_TYPES, which is basically an identifier. To implement all of this though, I had to make some more changes for the existing functionalities.

For example, we have a unloadPluginsExcept method, which is run before a game starts, and as I mentioned earlier, only keeps a matching plugin in memory. This method takes in a PLUGIN_TYPE, and a plugin itself.

Normally, we just fetch everything in memory of the type mentioned, and comparison between pointers would tell us which one to keep. But, since we now differentiate between MetaEngines & Engines, this method gives in a TYPE_ENGINE and a pointer to a MetaEngine plugin. The way to solve this is pretty simple, we have a method in metaengines called getEngineID. We reconstruct the name of the engine plugin with the help of this, add prefixes and suffixes if necessary (for example on windows, it becomes engine.dll) and then simply fetch each plugin in memory of the type ENGINE, try to match it with our generated filename. This successfully lets us achieve what was intended.

With the basic structure complete, I thought now was the time to go engine by engine and incorporate the new changes. The 8 engines I mentioned were ported earlier were - Agi, Plumbers, Drascula, Dreamweb, Lure, Pink, Sky & Scumm.  There were some things that would need shifting around - we just place the statically linked MetaEngine code into one file. After that, do the whole checking thing for createInstance, exporting it or not etc... For the Scumm engine though, there was a bit of an issue which needed a little more working around.

Great! Everything seems fine, so what's with the "back at square 1" in the title? Well, as it turns out, createInstance is not the only bridge that would need to be crossed over. If you remember when I mentioned what the MetaEngine does, is it usually handles all metadata and things normally the engine wouldn't do. The engine takes care of running the game, while the MetaEngine for other helper stuff. This helper stuff includes instantiating an engine, but it also handles listing saves, creating thumbnails, and querying for metadata for the savefiles, and many more.

It includes listSaves related things, which can have some engine dependencies, something I found when I was looking at the Sword25 engine. What it does, is basically creates an entirely new class, which itself has many engine dependencies, so obviously it cannot be linked statically. So, this is another bridge.

It's different for each engine though. In the 5 engines I ported, each had bare minimum for saving related things, so some shifting around of code made it work well. What that meant is even without loading a plugin, or having one entirely, we could still see savefiles, along with the thumbnail if it supported. It's not the same for all engines, as I pointed out earlier with Sky25 it's a whole different thing altogether.

But wait, with the basic structure done and solving the createInstance problem couldn't we do the same thing with these as well? Well, yes. Implement the base variant in the class, which calls DynamicPlugins to load the symbol and call it. We would then need the individual MetaEngines to not be defining it as a class function, so what I did with createInstance could be replicated and would work.

However, the main issue with this is that we have to include it as a class function if using static, otherwise like a normal function, so the code itself looks like

extern "C" PLUGIN_EXPORT function signaturehere {
class function signature here {
normal definition of function

This doesn't look nice, does it? If it was once, maybe it would've been ok but to do this as many as 3 times would be a bit too much, and code starts looking pretty weird.

So, recent discussions Eugene has pointed out that I could actually try to separate the MetaEngine class itself, so detection related things will be placed in one MetaEngine, while the dynamic things in another. We have so many engines, that I probably need to scope out many more of them and understand how this will work well. For now, I have the basic structure in mind, which involves adding 2 new classes (because we have a MetaEngine & AdvancedMetaEngine), but the work could be done with the addition of just one more class was suggested as well, so I'll have to keep that in mind.

The existing hierarchy/structure is something like this:
- We have PluginObject.
- MetaEngine derives from a PluginObject.
- AdvancedMetaEngine derives from MetaEngine.
- Plugins have as a member variable, a pointer to a PluginObject.
- A PluginProvider, which basically helps in creating the plugins.

The new additions will be 2 new classes, and they'll be related to MetaEngines.Those 2 classes will be called (or at least for now, because the name must be nice enough for everyone) MetaEngineConnect (inherits PluginObject) & AdvancedMetaEngineConnect (inherits MetaEngineConnect) so something like the original structure is replicated. These will then have functions like "createInstance, queryMetaDataForSave, listSaves" at least. I'm not sure if that's exactly going to be it because I have more thinking to do.

So, perhaps not back at square 1 but just the square ahead of it maybe? The engines already ported would need reworking, and many more things, so I just shifted to a new branch today and cherry-picked some of the commits from the old branch, which I think would be helpful. There are 79 engines in ScummVM & 5 engines in ResidualVM, so I best get back to work now! Phew, much more work to do!

That's the main thing I'm focusing this week, division of MetaEngine classes, and connecting everything once again properly! This possible way could be further improved and because this is something that will touch all engines, I should be more careful than ever in my thought process. That's it from me for now, see you again next week with some new progress on this hopefully!

Thanks for reading!


Now we can render our WME games even with shaders. The most work was actually related to setting up the surrounding code and not so much the actual shaders (minus the one which is responsible for rendering .X models). At the moment, things are somewhat unorganized however and the current code should be refactored, interfaces improved and common code factored out. I would claim that at the moment one can see the fact that WME was designed for the old fixed function pipeline and that the addition of the shader renderer is not completely straight forward. In contrast changing from Direct3D to OpenGL was easier, the only real change that I made was using the OpenGL matrix stack, which now turned out to perhaps been the wrong direction. Well, it can be reimplemented (and is so at the moment), but the old WME code didn’t rely on it either, so I might change this back.

I hoped that lighting done by shaders would produce the same results as the original code but this is not the case.


Let me just assure you that Rune is not supposed to look like he is almost getting sick. Apart from that though, things seem to look just fine.


This week, I worked on implementing a few Lingo commands that required some significant backend work, but not much in the rendering code where I have spent so much of my time. I mentioned that I had worked on a custom cursor implementation, and I spent the first part of the week fixing bugs there. Now cursor bitmaps like the starfish on the island are properly displayed at the proper position, whereas after my initial work just a black box showed.

Early in the week, I fixed a subtle rendering bug that had plagued Spaceship Warlock for a while. You’ve seen how the Stambulian policemen in Warlock were bright green; well, this was about the same as the keying colour that the MacGUI was using for border transparency. Once I spotted this, the fix was easy – and also prevented a redundant surface copy. (Yay for performance improvements!) Here you can see how the erroneously applied transparency actually gave a nice look to an otherwise bland wall in Stambul:

I also finished the implementation of custom colour palettes. For a long while the opening to Chop Suey looked all psychedelic. It turns out that a recent refactoring swapped around the order of palette loading so ScummVM was given the wrong palette to use. My partial fix for this revealed that our recently-added target Majestic used a castmember palette, which had been loaded before – albeit improperly. So over the weekend I expanded our Director palette manager to support custom palettes alongside the half-dozen default Mac ones. This also brought along basic support for the puppetPalette command, which controls the palette from Lingo. Now, Chop Suey and Majestic are looking quite handsome:

This project came later in the week, however. I first implemented sound fading, which more intense than I first knew. Since multiple movies can be running at once, my knee-jerk blocking fade loop didn’t work out. Instead, I needed to integrate the sound fade with the existing score stepping methods. I’m amused that that this was one of my largest commits for the week. (Thankfully, though, transitions do seem to block in the original – that would be a pain to refactor.)

Finally, I scratched my head for a while on an issue that @sev has since begun looking into. An interesting Director target is Macromedia’s own guided tour, which takes you “behind the scenes” at their studios to introduce new features of Director. Our renderer implicitly assumed that bitmap sprites had the same dimensions as the underlying castmembers, unless the dimensions had been modified from Lingo. Well, our smartly-dressed friend from the guided tour dismissed that theory:

What’s on the left is the original sprite (plus arms), and on right is the original castmember. ScummVM draws them both the same size. I would never have noticed, except that the sprite for his moving mouth appears all out of place when he isn’t the right size. Director does indeed have an option to scale individual sprites in the score, and we were reading this information in for bitmaps… but when I tried to use it there were puzzling discrepancies in the dimensions we expected and what the file clearly said. I still haven’t figured out why.

It’s been a good week over all, with interesting tasks both in and outside GSoC. You’ve perhaps seen on my bio that I like playing music. One of my friends recruited me to play piano for her upcoming violin competition, so when I need a break from coding I spend a few hours with the interesting sonorities of the great American composer Samuel Barber. And, at university on the weekends, I am working on using machine learning to control dielectric elastomers – smart materials that show much promise for soft robotics.


【方法分享】(无需回复)不用翻墙挂梯子,改host就可以裸 ...:2021-5-30 · 应该有人不知道sstm可以不用挂梯子,直接裸连,只用改host就行了,当然速度稍微慢一点 host如下: sstm.moe 直接粘贴到host文件里就好了,具体方法怎么修改host请百度。

  • Previously, event processing didn’t take into account the fact that multiple movies could be running at the same time, as it was implemented before MIAWs. Events were handled by whatever movie was currently being stepped, even if the event should’ve gone to another movie. I refactored the event handling code, and that’s been fixed.
  • I made the Lingo interpreter pause every 100 operations to process events, preventing long Lingo scripts from blocking mouse position updates and quit events.
  • I changed menu item callbacks to use the event system, whereas before they just haphazardly created and called global functions.
  • I modified the Lingo interpreter so that handlers whose return values aren’t used don’t leave garbage on the stack.
  • Lots of small bug fixes, and a few Lingo features like the title of window

Nothing I did last week is particularly interesting to look at, so here’s a bug in Chop Suey I fixed today: Mud Pup wearing assorted clothes

Before, you couldn’t put clothes on the dog. Now, you can put clothes on the dog. Problem solved. :)

Touching upon all 3 tasks

Hello! So, this week I have done things that ranged across all my tasks. Recently I checked out our sister project, ResidualVM. ResidualVM's codebase is largely similar to ScummVM, but the main difference is the addition of capabilities to run 3D games. They also take regular snapshots from ScummVM to keep up-to-date. So, the work of RTL GUI which was merged in ScummVM was also present there.

When I was running the application with the Hebrew language, some popups and drop-down buttons looked quite different from the normal GUI. Upon a little investigation, it looked like paddings were being set wrong for the RTL-widgets set in the theme. This was because back when I was on my RTL task, I temporarily set a padding of "2" as a placeholder to check, and then completely forgot about it as the difference was ever so subtle. I'm glad though, that I found this, and opened a PR to fix it.

English, proper paddings

Hebrew - Improper paddings

shadowsocks+v2ray配置笔记 – Funny JS:2021-2-21 · 2021年2月21日 shadowsocks+v2ray配置笔记 前提:随着墙的增高,单纯的shadowsocks简单加密也越来越容易被检测和封锁,因此需要更强力的加密与混淆手段,避免流量被检测出来。

Last week I left off saying Eugene had some comments about my U32 task, so this was what I worked on next. After solving the review issues, I decided to review my PR more carefully once again, because many issues were being raised. 

This time, I picked up on many things that could also be done and saw some things I had left out.

浅谈VPN、SS和SSR的区别-筑爱网:2021-5-23 · SS和SSR两者原理相同,都是基于socks5代理。 客户端与服务端没有建立专有通道,客户端和实际要访问的服务端之间通过代理服务器进行通信,客户端发送请求和接受服务端返回的数据都要通过 …

Native-windows dialog. The title, and the buttons for "Choose/Cancel" are in english.

最新免费可用的ssr节点 | Phpvar's Blog:2021-2-7 · 2021年6月15日 星期六 当前位置 : 首页 » 互联网动态 »最新免费可用的ssr节点 最新免费可用的ssr节点 ... //free-ss.site/ 需在梯子或者SSR的帮助下打开,页面中“免费S账号”即免费的ssr节点列表,可点击右侧二维码图标,打开二维码弹层,右键复制 ...

Before, I had written some sloppy code (1 line of code change) and expected it to work to as it used to, without thinking too much about it. It was clearly very wrong, and the translations in the dialog were broken. Nevertheless, I worked on adding support to it properly. I already had text in UTF-32, but our Windows wrapper code didn't have anything to convert the text to an LPWSTR (16-bit Unicode characters). I looked up documentation online and followed it, implementing a UTF8ToUnicode. We have a conversion function for UTF32 to UTF8, and then by using the above function (internally calls MultiByteToWideChar for UTF-8 encoding), it was converted properly to LPWSTR. The implementation now looks proper.
Russian translations for dialog title and "OK" button (The OK button has the label - "Choose")

One of the issues raised was that I was converting a Unicode string back to a normal string because a class called StringTokenizer was involved. I don't know how I missed that, so I implemented a Unicode string tokenizer.

A StringTokenizer simply takes in a string and some delimiting characters and separates the words based on the delimiters present. So, If I have the string "Hello, World - Welcome.... to ScummVM" and provide the delimiters as - " ,-." - I will get the individual words ("Hello", "World"....), which I can simply search, for example, in a list - if it contains those words or not.

One example where they're used is in the game search filter. Let's say I have a game - "Reversion: The Escape, PC" in a list of 100+ games. If I type in either of those words, the search list should show this game. With everything going Unicode, now what would happen is if you have a game title with non-ASCII chars, like かわい- and you start typing in , the game with the title かわいwill show up in the search list. I'm not sure if we really support typing in with any other languages in ScummVM right now, but it is now future-proofed I guess!

Those were pretty much the main things I did for the U32 task. I also cleaned up the PR quite a bit, reviewed it with care so small things get out of the way. 

Yesterday and today I was able to shift focus again to the detection task. The very first thing I did was to drop the previous few commits because the approach was wrong.

So, each engine has an overall engine template. Anything related to detection, the "MetaEngine" or any other related function is supposed to be defined here. It also contains function definitions from classes not declared here. So, my first guess was to restore the function definition to the original files. Say, "example.h" had the declarations, so "example.cpp" will have all the definitions. That's what I did, but I failed to recognize that functions were not defined in the so "example.cpp" for a reason. All detection related code from any classes is grouped over at detection.cpp, so the code overall has a nice structure to it. This also makes it easier for engine maintainers.

After a discussion, what I will now try to do is take code from "detection.cpp" and split it into another file - "detection-static.cpp", which the name suggests, will always build into the executable.

Finally, once again I arrive at the "createInstance" bridge. If you don't remember from last week, a small recap: createInstance is basically a function inside a MetaEngine - which instantiates the proper engine. So, if I am trying to launch the "Plumbers" game, it will instantiate the "Plumbers" engine.

The difficulty with this is that the function itself contains code that is not available in the executable. What I mean by that is,

Say I have an engine, which is used to run the game "exampleGame". This engine is named "exampleEngine".

When we request ScummVM configuration to build this engine as a dynamic module (explicitly linked run-time library), all code in "exampleEngine" goes into the "exampleEngine.dll" file.

Now, the previous dynamic system, everything was in the external library, so we could just load it, and then have "createInstance" instantiate the proper engine. i.e in this case, "engine = new exampleEngine". But now, the MetaEngine is always included in the executable, so that's a problem.

Why a problem? If I include "createInstance" class method inside the executable, it also has the line
"engine = new exampleEngine();"

What is exampleEngine? How will the compiler/linker recognize that, if the engine itself is in an external library? That's the issue of why this particular method cannot live in the executable.

So, what I am doing now, is basically making the createInstance method live outside the executable, and inside the .dll, while still making everything work as it used to.

I tried to approach this in various ways, but most of them had a flaw somewhere. Yesterday, I thought of a good approach, which will make minimal changes across engines and should work correctly. It's still a work in progress though, and no point in expanding on something that could be wrong. So, more on this next week!

I'll basically be focusing on implementing a way to bridge this gap for the next week, & That's it for this week!

Thanks for reading!

Starting rendering with shaders

Ok, what’s so special about the following picture:

Well, nothing, except that the scene was rendered with OpenGL shaders instead of the old fixed function pipeline. Which in this case (2d graphics) was not the biggest change, essentially only the 2d projection matrix has to be setup for the shader. 3d graphics will require more work, though. Also some refactoring will be necessary, some of which has already happened. For example, there is a 3d renderer interface class now with two implementations, which can be selected from the ResidualVM menu (a third one, based on TinyGL, is supposed to follow at some point in the future).

授之以鱼,不如授之以渔 – 第2页 – IACG.RIP:SS/SSR机场 1.NDSS 官网注册地址:https://ndss.top [邀请码08bT] 有一说一,这是第一家主动来找我推广的机场 推广是一回事,好不好用咱还是得试试。 首先在线路方面,他们不仅有SSR,同时也是提供了V2ray的节点,此处应当好评。

[技术宅] 超详细|新手向|教你一步一步自己搭梯子(3 ...:2021-12-23 · [技术宅] 超详细|新手向|教你一步一步自己搭梯子(3)—— SS篇 2021年12月23日 Will 0 Comments [技术宅] 超详细|新手向|教你一步一步自己搭梯子(3)—— SS篇

Learning the Lingo

This week I worked out some longstanding Lingo issues!


The first issue was duplicate scripts in Director 4 movies. Each cast member should have at most one Lingo script associated with it, but we were running into movies in which a cast member seemingly had several scripts. There was no obvious way to deal with this - redefining the script usually led to incorrect behavior, and so did keeping the original definition.

These duplicate scripts were rare in most movies, so the problem went ignored for a while, but in our recently added target Majestic Part 1: Alien Encounter, there were several hundred scripts, and almost every one conflicted with another.

Initially, I thought that there must be something that indicated certain scripts, or at least certain handlers within these scripts, were unused. The first place I investigated was the script’s “handler vectors.” These differed between some of the duplicate scripts, and I thought they might hold the key to how the script conflicts should be handled.

“Handler vectors” were identified as an array of 16-bit integers in Anthony Kleine’s Director documentation, but there was no explanation of their purpose. I got in touch with Anthony, but he couldn’t remember what they were for, and they remained a mystery to me for weeks. Once I began deeper investigation, it quickly became apparent that the “handler vectors” are just used to map event IDs to handler IDs. Totally unrelated.

The next suspect was the Lingo context, a container which maps script IDs to script data:

Section LctX {
	Struct header {
		Uint16 [big] freePtr
	Array scripts(count) {
		Struct scriptLink {
			Uint32 unknown
			Uint32 [big] ID // use MMAP!
			Uint16 [big] used // 0 : unused , 4: used
			Uint12 [big] link // For unused entries: link to next unused, or -1.

(Source: Brian151)

The two areas of interest are:

  1. The script entry’s ssr节点购买网址 field
  2. A linked list of unused scripts, which begins at the script entry at index ssr节点购买网址. The entry’s 怎么挂梯子上外网 field gives the index of the next unused script, or -1.

However, after much investigation, it seems that there is actually no difference in how a script with 手机怎么搭梯子到外网 and a script with used = 4 should be handled. The linked list does indeed indicate unused scripts, but all of the entries in the list seem to have an ID of -1. Thus, these unused scripts have no script data associated with them, and they were never being loaded in the first place. There was no way they could be causing conflicts, since they didn’t really exist.

搭建梯子 – 聚析的博客:2021-3-22 · 如果你只想要上外网而不指定要搭建ssr的话,推荐你一种最简单的搭建方法:如何搭梯子科学上网?,如果你一定要搭建ssr的话请接着往下看。(需要准备一个163邮箱) 第一步:注册并部署 […]

The scripts are not owned by their individual Cast Members in the Key Table [which links cast members to most of their assets] as you may expect. Instead, each Lingo Script has the number of its corresponding Cast Member ss梯子2022年.

After a few days of testing, I noticed that the cast member ID stored within Lingo scripts was sometimes incorrect. Or, as in Majestic, almost always incorrect. There had to be some other way by which cast members were linked to their scripts.

The obvious place to look was in the cast member data, which is split into two parts - data specific to the cast member type, followed by largely standard cast member info. We had previously identified a scriptId field in the data specific to script cast members, and these IDs always seemed to be correct. However, other types of cast members could have scripts as well, and since they wouldn’t have this field, this solution wouldn’t work for them. Or so it seemed.

Long story short, we were treating too many bytes as type-specific data, and the scriptId was actually in the standard cast member info. Once that was fixed, every cast member had a single, correct scriptId associated with it. Use that to link cast members to the scripts, and no more duplicate scripts!


安利一个我正在使用的梯子(2021年5月26日更新) | Kouss博客:2021-5-26 · 安利一个我正在使用的梯子(2021年5月26 日更新) 2021年02月24日 爱搞机 安利一个我正在使用的梯子(2021年5月26日更新 ... iPhone的ss 客户端需要美区账号(且付费)才能下载,有些公众号有小火箭的共享账号,自己搜一下。其他客户端参考他们网站 ...

First, I needed to differentiate between statements and expressions. An expression by itself, like 2 + 2, isn’t a valid Lingo script - it needs to be an argument to a statement, like put 2 + 2. However, we were treating expressions and statements exactly the same, which allowed incorrect scripts and significantly complicated the grammar. Once this was fixed, half of the grammar’s 441 conflicts were gone.

Next, I needed to get rid of the differentiation between Lingo’s subroutine types. Confusingly, Lingo has (at least) 3 different types, with overlapping purposes:

  • Commands - These are built-in, and invoked by a call statement, like foo() or foo.
  • Functions - These are also built-in, and invoked by a call expression, like put foo(). Very rarely, you can also invoke them as statements.
  • 如何使用梯子(手机版)? | 每日区块链:2021-2-3 · 1.访问梯子官网 2.下载对应的手机版 ,安装。点击链接,如果IKEV2不能用就用SS模式

Now, these are separate things, but they should only be treated separately during execution. Previously we were differentiating them in the grammar, which again complicated things.

With that done, I began general cleanup. Reorganizing things where conflicts could be eliminated, reducing the use of right recursion, and adding support for fun statements like this one:

put cast cast

What should this do? Why, of course, it prints the cast member whose ID is equal to the variable ssr节点购买网址:

六月 | 2021 | 搬瓦工优惠码 | 搬瓦工VPS:2021-6-6 · 搬瓦工机场梯子优惠码 – 搬瓦工新增日本梯子29.99美元/月 搬瓦工梯子优惠码 5.2%折扣 500GB、1TB、5TB方案 近期评论 文章归档 2021年六月 2021年四月 2021年三月 2021年十一月 2021年十月 2021年九月 2021年八月 2021年四月 2021年三月 2021年十二月

All in all, the grammar is now truer to the original, and we’re down to 6 conflicts from 441!

Lots of chop suey

Hey there!

My big showcase for the week’s work is a few scenes from the kids’ game Chop Suey, one of our primary Director 4 test cases:

最近的墙怎么了?? - 黑客派:今天发现 GitHub 都上不了。只能显示模糊的字,CSS 效果没有。某歌用梯子也上不去了。 我用的 ssr,ss 的升级版。只能偶尔能出墙。流畅程度想死。 作为一个经常出墙看论文和找资料的人来说,很难受。 有热心人提供解决方案吗?或者谁家的付费稳定,不受最近的墙影响的 ss 或 ssr 服务?

Last week I called Chop Suey a Lingo-heavy game, and I was referring to how much it controls animation via puppets and the 手机怎么搭梯子到外网 command. Because, as you saw, its cursors are bitmaps and certainly do not fit in the standard 16x16 Macintosh cursor box, Chop Suey introduces its own mouse update code and calls for the stage to be updated several dozen times each frame. Most of the inefficiencies were here.

I spent the early part of the week in much trial-and-error, working out the pieces of the renderer that were most inefficient under such repeated application. The idea is to do a little bit of work up front – checking flags and so forth – so the expense of redrawing a region of the screen is saved. (As I have realized, even when working on Chop Suey, very subtle bugs can arise from forgetting to check a rendering flag.) Even at usual framerates without much Lingo that doesn’t matter very much, but Lingo-heavy games like Chop Suey have shown dramatic improvement.

Totoro 🐱 👉🍒🍈🍍: 现在除了ss、ssr、小火箭还有哪些梯子可以 ...:2021-6-13 · 现在除了ss、ssr、小火箭还有哪些梯子可以像ss一样使用节点? - Totoro 🐱 👉🍒🍈🍍 說在 社群 Shadowrocket 在 2021年6月13日星期六 23:37

Oh, and I also spent most of a day trying to discover why some textboxes in Spaceship Warlock weren’t rendering properly, along with some other nettling MacGUI issues. The issue actually lay in the cast loading code, which I hadn’t touched much, but it’s always satisfying to squash a bug and learn more about the codebase in the process – even if your “fix” breaks other stuff. :)

Getting a better understanding & a little progress

Hello! The first few days this week, I spent trying to understand my task, and work on a small number of engines, and try to make games detect/work as a means to see if everything would work as expected. But first, some context.

ScummVM has a MetaEngine and a Engine.


A MetaEngine is responsible for, as the name would suggest, a meta-data related things before we actually start the engine. This is an abstract class, and each specific engine must inherit it and have their own implementation of it.

【福利】两个自用四年的ss+V2ray+Trojan的稳定老牌梯子 ...:2021-6-11 · 国外便宜VPS主机论坛 › 综合讨论 【福利】两个自用四年的ss+V2ray+Trojan的稳定老牌梯子推荐,防封性能超强节点质量极高 mingdao · 1天前 · 30 次点击

AdvancedMetaEngine provides a means for engines to detect games. But, how does it know that a specific game belongs to a particular engine? Each engine provides a set of detector tables i.e a list of games it can support. Then, the default game detection algorithm checks each engine's detection tables for a match. These files are often separated into a new file, and it is called "detection_tables.h"

So, each engine's implementation of their own version of AdvancedMetaEngine (or MetaEngine) and other detection-related code is located in detection.cpp. This file includes the detection_tables header file, so the resulting object file generated has all the necessary information which it would need for detection.


An engine is the actual game engine, which is created when we try to run a game.

So, what is the task exactly? 

I gave a very brief overview in my last post, but basically, the detection related code - which lives in detection.cpp, will need to be isolated in a way that actual detection related code goes to the executable, while the other kind of functions will be available as-is, on-demand at runtime.

So, the detector-tables, and other detection related code - like fallback detection moves in and is linked against the scummvm executable. So, the ScummVM executable depends on these (detection) object files.

Fallback detection is a way for engines to provide a means to find a "closest" match if the detector found no matches in the directory.

So, I have a little progress this week! It's not much, but I worked towards the most basic thing as a few of small steps:
【福利】两个自用四年的ss+V2ray+Trojan的稳定老牌梯子 ...:2021-6-11 · 国外便宜VPS主机论坛 › 综合讨论 【福利】两个自用四年的ss+V2ray+Trojan的稳定老牌梯子推荐,防封性能超强节点质量极高 mingdao · 1天前 · 30 次点击
- For engines, isolate MetaEngine code and temporarily comment a bridge function - createInstance. Creating an instance means we actually try to instantiate an engine. This is a method of MetaEngine and connects an Engine with MetaEngine.

That's it! I did the above for 3 engines - AGI, CINE, PLUMBERS. I had no need for the latter two though, but I wanted more than one engine as part of the preview? or whatever I was doing.

A while back, Eugene had given me a link, which had a huge number (197 or so!) of AGI (fanmade) Games. I thought it would be a good point to see if the above steps worked correctly or not. It worked well, and the result from before/after the work was the same. Fallback detection worked too!

Perhaps it was not a big deal, but I finally had something to share! I'm taking a lot of time to think and understand this task, and many days had passed by without me sharing any update. I could finally share a small update and make a few commits for my mentors or community to check out, so that was good. It feels a little weird that I'd check-in and out without showing code progress for so many days, so for me to actually show something was good.

Detecting 197 AGI-fangames, statically

I also took a small test, I uncommented code in createInstance where engines were being instantiated and added plugins as a dependency for the executable.

That means all engine.dll's depend directly on the executable i.e implicit linking. This type of linking would mean a .dll file to be present for the executable to run. If it does not exist, the application would crash.

That's not really how it should work - engine.dll's are explicitly linked i.e they're not dependent on executable. It's loaded on-demand and if not present, the application would not crash.

However, I just did the test to see if engines could instantiate and run properly - and they did, indeed!

Eugene recently reviewed my newly made commits and left a lot of comments. I made some mistakes, or rather - didn't correctly understand why some things were the way they were. A small discussion in the group took place, and I think I know the way to move forward now and incorporate the changes in a better way. 

Overall, I think I have the basic idea of the end goal, as well as a temporary piece of code that achieves this (with a few incorrect assumptions). Now, I need to implement everything in a correct manner and maintain the engine changes in a clean and maintainable manner.

Though I think there are still some key things I don't fully understand, but the discussion recently should be enough to guide me in the right direction. 

亚马逊云(EC2)搭建教程,可免费使用一年 | 技术拉近你我!:2021-6-30 · 之前分享了谷歌云搭建教程,具体文章可以参见这篇:谷歌云搭建教程,可免费使用一年。谷歌云比较好,免费用户送300美金使用额。而亚马逊云,也可以免费使用一年,不过每个月在使用上也有一些限制,比如流量每个月只能免费使用15G的出口流量,超出就要额外收费,具体免费的限制可以看官网 ...

That's it for this week! My previous PR has some more comments now, which I will have a look now, review it myself and make the necessary changes.

This next week, I want to accomplish the changes (for the new task) in a way that my mentors expect and have a few more commits and enable a few engines regarding that. Once I have the "go" for that / everything seems ok, I can start going engine by engine to incorporate the changes on a bigger scale.


Rendering shadows

Another major step is done, rendering shadow volumes of 3d objects:


The shadow looks beautiful, I have to say, stencil shadows are great. Also Rune does not appear to be floating over the ground anymore in this scene.

【福利】两个自用四年的ss+V2ray+Trojan的稳定老牌梯子 ...:2021-6-11 · 国外便宜VPS主机论坛 › 综合讨论 【福利】两个自用四年的ss+V2ray+Trojan的稳定老牌梯子推荐,防封性能超强节点质量极高 mingdao · 1天前 · 30 次点击

One thing which is bugging me is the fact that lightning does still not give the same results everywhere compared to WME. But I am going to accept this for now. Now is the time to add some more missing stuff and cleanup the existing code.

熊猫加速器下载  云梯更科学的上网工具   小火箭节点二维码分享  起点加速器官方网站   18加速器  快加速网络加速器ios