晏陽增補
本支(晏陽技術組所修之版)於上游 JCM 2.3.0-prerelease.3 JS 之 API 上所增之能也。上游既有者,照舊可用;本頁惟書其增。
增補一覽
| 增補 | 門戶 | 一言 |
|---|---|---|
| JS 與 C++ 相雜之條 | 宣告之條 | 一條之內,JS 與 C++ 模塊隨意相雜,雙引擎並時而繪 |
| 開門方向之記 | VehicleWrapper.getDirectionOfDoorOpening() | 到站何側啟門——站台之期、正線之測,跨視距者服端為記 |
| 交通類型之細分 | VehicleWrapper.getTransportType() 之屬 | 線路細分類型之 id(與 MAGIC MTR 相連)與轉乘增益之欄 |
| 直寫像素之上傳 | GraphicsTexture.uploadRawABGR() | 字節行陣直書,惟上傳髒區——逐像素高頻更新省頻寬之途 |
| 相容之別名 | 宣告之條 | 受 NTE 文檔示例 script_input 之鍵名;nativeLibrary / nativeLibraries 得與 .js 相雜而用 |
JS 與 C++ 相雜之條
上游之式,一條腳本,其語惟一。晏陽以判定之權付諸文件之徵:scriptLocations 每條各自觀之——*.js(不辨大小寫)者歸 JavaScript,餘者悉按 C++ 模塊解之。一條之內,二種隨意相雜,其數無限:
"vehicleScripts": [
{
"id": "demo:sp1900",
"scriptLocations": [
"demo:js/sp1900_ui.js",
"demo:natives/sp1900_motor",
{"windows": "demo:natives/win-x64/libmotor.dll",
"linux": "demo:natives/linux-x64/libmotor.so",
"macos": "demo:natives/macos-arm64/libmotor.dylib"}
],
"prependExpressions": ["print('JS 側照常執行')"],
"input": { "era": 2004 }
}
]
C++ 之宣告,其式有三:
| 式 | 書法 | 所解 |
|---|---|---|
| 平臺無關之 stem | "demo:natives/sp1900_motor" | 每平臺各自展之:natives/linux-x64/libsp1900_motor.so、natives/windows-x64/sp1900_motor.dll、natives/macos-arm64/libsp1900_motor.dylib……(目錄之布局,詳見 入門) |
| 完整庫之徑 | "demo:natives/linux-x64/libfoo.so" | 按副檔名而繫其系統;他系則略此條 |
| 按平臺而映之表 | {"windows": ..., "linux": ..., "macos": ...} | 鍵得精至架構(macos-arm64、linux-x64……),精確之鍵先於通用之鍵;值之本身,又為 stem 或完整之徑 |
二引擎各繪其所:JS 之部(連 prependExpressions 與 input 併之)拼為一份腳本而解析;C++ 之部悉懸於同一腳本 id 之下,由原生管理器載之。渲染之時,兩側各自捕、各自回放,繪製之令互不相犯;一側缺焉或載敗焉,惟彼側不畫而已,不至累及他側。
language 欄(兜底之關)
| 值 | 其效 |
|---|---|
| 不書(薦) | 按文件之徵自判——諸景之眾,一無配置 |
"cpp" | 純原生之條(舊義也):scriptLocations 中之 .js 見略,日誌留示;配 nativeLibrary / nativeLibraries 而用 |
"javascript" / "js" | 強使全按 JS 而解——無副檔名 JS 文件名之生路也 |
欄名依格式而定:MTR 四代之鍵曰 language,舊式則 scriptLang(駝峰)/ script_lang(下劃線)。nativeLibrary / nativeLibraries(後者使一 id 懸多庫)無論何時,皆按 C++ 處之,亦得與 .js 同條共存。
prependExpressions / input / rateLimit / dataFetchMode 諸 JS 之欄,其義不變;純 JS 之條(悉為 .js),所行與上游全同。C++ 側讀 input 之法,見 C++ 之檔。
開門方向之記
VehicleWrapper.getDirectionOfDoorOpening(): String 所以答「此列將啟何側之門」;其值:"not"(兩側皆弗啟)/ "left"(車頭之左)/ "right"(車頭之右)/ "all"(兩側):
- 泊於站台之時:門未啟、半啟、方闔、既闔,所答皆與全啟無異——站台之塊(或既解鎖之 PSD / APG 門)在何側,何側即謂「將啟」。門值 > 0,則逕讀本幀逐廂之判。
- 行於正線之時:測下一站啟門之側——置列車於當泊之點於自家路徑之上,循 MTR 同款
canOpenDoors察塊之法。停點之區既載,立即可用;逾視距則改由服端作答:服端全圖既掃一遭而恆存之(站台之塊有增刪改,自為增補重掃),按線路緩其兩側之答以應所請——中途登車、重啟遊戲、初至之站,皆行如常。 - 服端未具本模組,或未之應:則退為客端自家視距內之掃;此時遠處站台之測,或不可得。
- 聚之規:一側苟有一廂之門旁具站台之塊,舉側悉記可啟(按側而聚,不按單門)。左右以車頭(轉向架 1 端)為準:每廂於自家坐標系中評之(-X 者,車頭之左,MTR 模型之慣例);行向與折返,皆弗易其讀。
- 純詢而已:惟佐顯示之邏輯(啟門側之指示、車內屏之箭矢),門實啟閉,仍司於 MTR。
function render(ctx, state, vehicle) {
let dir = vehicle.getDirectionOfDoorOpening(); // "not"/"left"/"right"/"all"
if (dir == "left" || dir == "all") drawLamp(ctx, state, "left", 0x00FF00);
if (dir == "right" || dir == "all") drawLamp(ctx, state, "right", 0x00FF00);
}
交通類型之細分
MTR 之 TransportMode,惟基礎之式凡四(train / boat / cable_car / airplane),於顯示有所不贍。MAGIC MTR 附加之模組,許玩家於「列車」復細分顯示之類(存於其 route_types.json,以線路 id 為鍵)。本支使此諸類貫通乎腳本:
VehicleWrapper.getTransportType(): String—— 當前線路規範類型之 id:MAGIC 既指其細分(train_normal/train_light_rail/train_high_speed/train_metro/train_bus/train_tram/train_sbahn)則用之;否則回落基礎模式之 id(train/boat/cable_car/airplane);不可解者為unknown,永不為 null。Stop.routeInterchanges[i](RouteInterchange)所增:getTransportMode(): TransportMode?(轉乘線路交通之模式,舊數據或為 null)、getTransportType(): String(同上規範之 id)、getRouteId(): long(來源線路之 id,服端數據缺者為 0)——轉乘之牌按類擇圖 / 配色之時,不復惟色可讀。- MAGIC 未裝,或該線路未蒙指派,則一切照舊回落基礎之式——腳本無須探附加模組之存亡。類型所詢之果,按線路為之短緩存(約一秒);MTR 之中改其類,俄頃可見。
用之諸處
規範類型之 id,非惟 vehicle.getTransportType() 一處用之——宿主之內、兩側之腳本,凡所用之處,具列於下:
| 用之之處 | 所在之側 | 釋之 |
|---|---|---|
vehicle.getTransportType() | JS · 車輛腳本 | 本節之主門;車若掛 C++ 之腳本,宿主築快照亦呼之(每車每幀一遭),以其字串書入快照字串之池 |
stop.routeInterchanges[i].getTransportType()stop.connectingInterchanges[相連車站之名][i].getTransportType() | JS · 車輛腳本 | 轉乘諸條,逐條同一 id;類型由服端預解,隨轉乘之數據同下(以服端所指為準,客端 MAGIC 有無皆得之);舊版數據缺此字段,客端方按 getRouteId() 自查以補 |
mtr::Vehicle::getTransportType()(舊名 mtr::Train)mtr::Stop::interchange(i).getTransportType() | C++ 快照 · ABI 9 起 | 直讀快照字串之池中宿主預書之串,與 JS 所得全然一致;詳見 數據快照 |
以上諸處所讀,同出一源——一處所得之 id,諸處必同。
直寫像素之上傳
GraphicsTexture.uploadRawABGR(source: byte[], dstOffsetX: int, dstOffsetY: int, width: int, height: int, ppm: int[]): void
以 width × height × 4 字節、行先、BGRA 之序之像素行陣,直書於紋理之緩衝,且惟以此矩形上諸顯存:
- 其位:逐像素高頻更新省頻寬之途也。尋常 AWT 之
upload()搬全圖;4 Mpx 之屏每幀整傳,即十數 MB 之搬運;而逐點之動(進度之條、跳字之屬),尋常惟改一小條——以此法,數百 KB 足矣。 ppm者,4 × 256 項預乘之查表(依次 B / G / R / A 四段,各 256 項),呼者執之;字節按表展開而書,免逐像素為乘。- 既書,自惟上傳該矩形,紋理之餘仍其故——較
upload(x, y, w, h),省「先於 AWT 畫布改之」之一步。 - JS 之中亦得用之(配
Java.newArray以組字節之陣列);然其設計之初衷,乃為 C++ 橋幀像素之回傳;純 JS 之作者,用 AWT 加子域上傳即可。
JS 與 C++ 詞彙之一致
同一數據,二語同名——相雜之條,兩側共繪一物,不致迷亂也:
| JS | C++(SDK) | 所引入 |
|---|---|---|
vehicle.getTransportType() | mtr::Vehicle::getTransportType() | ABI 9 |
Stop.routeInterchanges[i].getTransportType() 等 | mtr::Stop::interchange(i) 之類型欄 | ABI 9 |
vehicle.getDirectionOfDoorOpening() | mtr::Vehicle::doorDirection() / getDirectionOfDoorOpening() | ABI 11 |
純 JS 之讀者,記一事足矣:本頁之增補,C++ 側同樣可用(快照之欄直讀,零搬運之費),見 數據快照。