#?? DGEN(SEGADRIVE)クリーンナップ | //www.旧型、PSP開発幼稚園.game.jp/(本館)

#?? DGEN(SEGADRIVE)クリーンナップ

#?? DGEN(SEGADRIVE)クリーンナップ

昨日は、えっと、メモリ関係のクリーンナップをしてた。クリーンナップってのはソースコード見直して、
綺麗にする作業。何か機能が増える訳でもないし、パフォーマンスアップする訳でもない。

「えー、そんなのつまんないよ。」

Yes.つまらない。

でも、バカ言っちゃいけない。クリーンナップってのは、古代VAX11時代から脈々と伝わる由緒正しい技法 てあって、秘伝だ。実はHPにも公開してはイケナイ特殊技法なんだぞ。 ...まあ秘伝だから、この辺でやめとくか。(管理人は口が固い、おそらく)
そもそも管理人の頭のレベルがもっと上だったら、こんな作業要らない。しかし、わいにわ、訳わからんのじゃ。 A20は、うーんよくワカンナイから8MBちょーだい。あ、お金余ってるから、ついでに128kもくれ。とか、 訳解からん、メモリ取得状態だ。から、A21には(永平寺におつかいに出して)少し背筋を伸ばしてもらった。 こんなん。
/* こちらは実メモリ(実機のメモリ、但し、量は一緒でも、インテル、モトローラで違う部分もあるかも?) */ static unsigned char cart_sram[ 0x020000] __attribute__((aligned(64))) ; // [128kb] Cartridge SRAM static unsigned char rom[ 0x400000] __attribute__((aligned(64))) ; /* [4MB] Cartridge ROM (cart_rom) *///0x400000[4MB](4*1024*1024) static unsigned char ram[ 0x010000] __attribute__((aligned(64))) ; /* [64kb] 68K work RAM (work_ram) */ static unsigned char z80ram[ 0x002000] __attribute__((aligned(64))) ; /* [8kb] Z80 work RAM */ static unsigned char vram[0x010000] __attribute__((aligned(64))) ; /* [64kb] VRAM (vdp_wram) */ static unsigned char cram[0x000080] __attribute__((aligned(64))) ; /* [128] CRAM */ static unsigned char vsram[0x000080] __attribute__((aligned(64))) ; /* [128] VSRAM */ /* こちらは実装の都合で、使うメモリ(実機には存在しない) */ static unsigned short highpal[ 64 ] __attribute__((aligned(64))) ; // PSPはshortで良い。 // PCはintが速いが(?) static unsigned char dirt[0x000035] __attribute__((aligned(64))) ; // Bitfield: what has changed VRAM/CRAM/VSRAM/Reg dirty buffer bitfield static unsigned char vdpreg[0x20] __attribute__((aligned(64))) ; /* mem.cpp */ //←あ、これは実機にあるか。
まだ、ちょびちょび。あるよーな気がするケド。忘れたつ。 「ゲームボーイ」は8MBytes(64MBit)ROMとかあって大変らすいーーが、メガドラは、管理人の知る限り 最大でも、4MBytes(32MBit)だな。っていうか2MBytes(16MBit)の奴ならすぐ思い浮かぶが、 4MBytes(32MBit)のROMってなんだったっけ?。 何か(複数)あったような気もするんだが、「ファンタシースター4」あたりがそうじゃなかったっけ?(昔吸い出した経験がある。そんでGenecystで解いた) 「Thor」とか吸い出したけど、容量よくワカンナカッタ(Genecystで動かなかった為。最近のgensとかで試せば ちゃんと吸えてるか判断が付くんだが、めんどくてやってない) 管理人の自作吸い出し機は8MBytes(64MBit)でも吸い出せるんだか。 メガドラ、仮に2MBytes(16MBit)で足切りしたって、主要なROMはみんな動くから、それでも良いんだよね。 でも、PSPメモリ余ってるから、拘る必要がないんだケド。
■そおいやA20から、「 -Werror -Wall」が付いたんだよ。之は古代より伝わる「プログラマー養成キブス」だから、 ちゃぶだいひっくり返されても、外したらあかんよ。管理人「ちゃぶ台」って一度も見たことないから、既に妄想話でもおK。 一度見てみたい気もする。管理人が入手した情報によると、「ちゃぶ台」は「たためる説」と「たためない説」があって、 真相はどちらか判らん。見つけ次第、ひっくり返して調査してみたいが、何処のコンビニにも置いてないよ。 (14:10、そろそろお昼ご飯の心配をするか。え遅い?だって忘れてたんだもん)
■ふう喰った喰った。今14:48。大体なあ。管理人VAX11なんて古いコンピューター見た事も聞いた事も 喰べた事もないよ。知ってる訳ないじゃん。ただこの民明書房の本によるとだなあ、「MIPSという単位は当時 VAX11ちう、こんぴゅーたの処理能力、が丁度1MIPSだったから生まれた。当時は1MIPS==1VAX だったので1VAXとも云われた。VAX11はUNIX互換ましん」って書いてあるから、文句があるなら、民明書房に言え。 PSPは「何VAX」なんじゃろ。既に「かぞえきれん程たくさんVAX」なんじゃろな。(VAXって単位があるとして)
■そおいや、昨日の話なんだけど11025と5512でまた音を変えた。 44100と22050は多分そのままでも本質的に問題がない。 でも、11025は違うの。 メガドラに乗ってるのが76じゃなくて、PSGであったなら、この問題は発生しない。 でも、PSGじゃなくて76なの。
回避する方法は、幾らでもある。
だが、検討した回避案では、どれも重くなる。 11025や5512だけでなく、下手したら44100や22050も重くなる。 本末転倒、意味なしじゃん。だから下手に弄れなくて、難儀してる。 そもそももっとエミュが速くなれば11025自体要らなくなるんだし。
そおいう訳で、保留中。 ■ちゃんとメガドラの音が聞きたい人は22050にすべし。ゲームが重くてかなわんなら、 FSKIPを増やせ。現状こうとしか言えんなあ。 ■FSKIP0に拘るなら、音質を落とせ。11025は鬼門であるので、下手したら5512の方がましな事もある。 もしくは「OFF」という手もある。 ■アウトラン系は「FSKIP0」でも「FSKIP2」でもあまり代り映えしない。という説が、民明書房の本に書いてあつた。 両方欲張れるのは、もちっと未来の話なんだよな。がんばってね。管理人版DGEN10A21! (15:36)
■あつたあつた。 疑問に思ったから2M(メートル)先のこんぴゅーた立ち上げて、メガドラの吸い出したROMないかな? って調査してみた。え?インターネット繋がってるなら、怪しげなROMサイト行って調査しろ? (調査はしても、違法じゃないんだよね。調査だけなら。) だって、それじゃあ同タイトルでも海外版かもしんないジャン。 いづれにしろ、この2M先のPCには管理人が吸い出したROMしか入ってない。 全部元のカードリッジも現存するから、著作権上クリーンだな。 このPCはあくまで作業用途であって、過去何度かHDDが飛び、その度にOSを入れ直したから、 「これで吸い出したROMは全部ではない」っていうかCDに焼いたものはなるべく消してる。 ちなみに、ここの吸出し作業ディレクトリ(フォルダ)には、179個のオブジェクトだって。(現在値) こんなに少ない訳ないから、チョビットしかない。だって200以上はあった記憶がある。 (注:管理人は1000以下はチョビット) ええと大きい順に、 あ、やっぱ「PS4」と「ild_4M」となってる。4MBytes(32MBit)のROMはこんだけ。(でかいのは、 真っ先に消すから当てにならんが) 「PS4」は「ファンタシースターⅣ」もちろん日本版だ。だって、管理人が日本で買ったんだから。 「ild_4M」は「アイラブとなるどなんちゃらって奴」これは容量が解からんから、とりあえず4MBytes(16MBit) 吸出しとけ。って匂いがするから、あてにならん。 次に大きいのはもう3MBytes(24MBit)だよ。「悠々白書」とかそんなんがならんでる。 下のほうみてくと「Thor」(もちろん日本版)は2MBytes(16MBit)にしてある。容量良く判らんが。 エミュレーターで一度も動作させてないから、正常に吸い出せてるのかどうかすら、判らん。 4MBytes(32MBytes)で吸い出して、バイナリエディタで2MBytes(16MBit)に加工したんじゃろ。 当時の事はおもいだせん。 「ファンタシースターⅣ」圧縮、分割してFDDでこっちに持ってこようか?4MBytesのチェック用に。 えっと手順は、 1.インターネットで圧縮分割ソフト、落とす。 2.FDDにしまう。 3.2M(メートル)程、ワープ 4.FDDから出して、野放しにする。 5.「1/3」グライづつFDD運輸経由で、こちらに転送。 うーん、LANカードセットアップより、遥かに楽チンな作業だな。 (16:42)
上のやり方はいささかメンドーな気がしたんで、CF空港に頼んで、ファーストクラスで空輸してもらっちゃった。 航空運賃値下げ合戦で凄い事になってる。28日前に予約しといて良かった。得しちゃった。 やっぱFDD運輸は、ぶーぶかウルサイしな。普段ビジネスクラスしか知らんので、ファーストクラスは新鮮だしな。 (あ。もう17:00)
おし、「ファンタシースターⅣ」動いたよ。やっぱ分割圧縮されると、生きた心地しないって言ってたよ。 じゃあA21で4MBytes(32MBit)の起動チェックは終わりだな。仮に8MBytes(64MBit)のROMが存在するとしても、 管理人が本物のカードリッジを持ってない限り、チェックする気はないよ。 4MBytes(32MBit)上限は仕様な。(っていうか絶対に不便はない筈)民明書房の本にも書いてある。 (17:12)
■やはりRPGはシューティング類と違って、ガンマ補正しないと、色が汚くて見れないな。 仕方ない。メガドラガンマ実装するよ。但しPSPの液晶は中間色の反応がトロくて、異常に残像が残るから、 従来のガンマOFFモードも残しとくから安心してくれ。 えーと、昔管理人が作ったメガドラエミュから、ガンマデーター抜いてくるな。
注:メガドラ実機を遊んだ事がない方へ。 メガドラ実機は、回路の都合(手抜き)上、キツイがガンマがかかる。 ビデオ出力ではなく、RGB改造してあっても同様だ。 メガドラ後期のソフトは、この「メガドラガンマ」を考えて、グラフィックデーターを作成してある為。 「メガドラガンマ」が実装されてないエミュレーターでは、「見れない画質」となる。 っていうか管理人。「メガドラガンマ」が実装してあるエミュレーターって、昔管理人が手作りした奴以外に知らんのですけど。 (ガンマが弄れるエミュはあるかもしれんが、標準できちんと実装されてるのは現存しない筈) もちろんPSPの残像を考えて、「管理人版MDP022A08」も「管理人版DGEN100A20」も敢えて実装しなかった。 (知らなかった訳ではない。開発の優先順位。それに必要性を感じなかったからだ。) 「メガドラガンマ」がとても良く判るソフトのお勧めは「ソーシャルキングダム」と「スーパーハングオンの地面」かな。 実機とエミュの色ガンマを比較すれば、一目瞭然。違いが判る。メガドラのビデオ出力は回路の特性上。 (絶対に電解コンデンサでは駄目な部分に、電解コンデンサを使用してあるため)横に数ドットにじむ。
あの?もし?メガドラ回路担当さん?聞いてます?こんな所に電解使ったら、CXA1145が幾らガンガッテも 速度追いつく訳ないだろタコ!にじむに決まってんじゃねーか。
また色情報もローパスフィルターにより欠損する。(これも実は電解のせい。メガドラは安いからって、 (チップコンデンサ以外は)電解しか入ってない、恐るべきマシンだ)
「デンジャラスシード」をエミュレーターでしか遊んだ事のない方へ。実機では背景の流れる星はすべて単色の グレイの階調だ。RGB改造してしまうとエミュに近い画質になるが。 AC版の「デンジャラスシード」も、もちろん背景の星は、グレイの階調。 メガドラ版は試行錯誤のはて、「ビデオ出力」で最も綺麗に見える「グレイの階調」を検討した結果。現在の形になった。 当時の国内の主要なTVは調べて調査してある。 エミュでしか遊んだ事のない方へ。背景の星は実機ではあんなケバイ色ではないぞ。実機ではローパスフィルター により色情報が欠損する為背景の流れる星はすべて単色のグレイの階調となる。色はまったく含まない。 これをエミュレートするのは簡単だが、ちと負荷が高すぎる。(要FFT) 「メガドラガンマ」は簡単だからエミュレートするよ。仕方がない。今度ね。 (17:47)

■あったあった。えーと。これはPC用のgeneratorだな。もちろん管理人が滅茶苦茶にカスタマイズして、 オリジナルの面影が少ない。過去ソースだ。 ええと、「uiplot.c」ってソースがあってな。この名前で多分オリジナルもあると思う。ここで、一括して、 「レンダー結果をさらにPC用のパレットを考慮してレンダーしなおすルーチン」だ。 つまり、メガドラの画面イメージ画像をメガドラのパレットで作ってある奴が、普通のレンダー。 それをさらに再変換してPCのディスプレイに映し出す。PC側は256色であったり16ビット色だったり 色々だからな。 MAMEも勿論、まったく同じ仕組みになってる。でなきゃあんたのPCで動かないって。管理人が使うのは、 DOS版だが、WIN版も、LINUX版も、その他版も、これに相当する部分がある。(平たくいやあ二度手間なんだが) PSPと違ってハードウェアーがピンからキリまで様々だから、この仕組みは無くす訳にはいかんだろ。 管理人版のDGEN100A21でさえ、この仕組みが少し残ってた様なきがする。忘れたが。MDP022は完全に 残ってるな。もっともPSPで使わない分は削除したが。
MAMEのDOS版はええと、「src/msdos/blit.c」がこの辺。つまりPSP_MAMEなら、「src/psp/blit.c」って事。 昔、管理人がPCのMAME(F3)でここをMMXのアセンブラでblitさせたら、10%~20%は速くなった。(測定値) (注意:MAME、DOS版に標準で添付されてるMMXのアセンブラルーチンは全然まったく参考にならない。 32ビット→32ビット専用だし、あれだけ(殆ど何もしない)じゃ全然駄目) いつの間にやら、違う話になってきてる。ええと、「メガドラガンマ」な。管理人が「デビルアイ」で測定した奴を実装した のはgeneratorではこんなん。ほい、過去ソース。
#if 1 void uiplot_checkpalcache_one(int col ) /* col==palette number */ { //unsigned int col; uint16 *p; /* (LITTLE ENDIAN) */ int red,green,blue; /* do work asemmbled color */ // for (col = 0; col < 64; col++) { /* the CRAM has 64 colours */ // if (/*!flag &&*/ !vdp_cramf[col]) return;//continue; // vdp_cramf[col] = 0; p = (uint16 *)vdp_cram +col; /* point p to the two-byte CRAM entry */ //#ifdef WORDS_BIGENDIAN //ok?(BE) // blue = (*p & 0x0e00)>>6 ; blue =blue +blue +blue ; blue +=87; blue >>=4; blue <<= (uiplot_blueshift +1); // red =((*p & 0x000e)<<2 ); red =red +red +red ; red +=87; red >>=4; red <<= (uiplot_redshift +1); // green=((*p & 0x00e0)>>2 ); green =green +green +green ; green +=87; green >>=4; green <<= (uiplot_greenshift +1); //#else /* MEMO: short conversion... (motolora:m68k)0BGR -> gr0b(intel:i80x86) */ /* sorry dust 4bit ... */ blue = (*p & 0x000e)<<2 ; blue =blue +blue +blue ; blue +=87; blue >>=4; blue <<= (uiplot_blueshift +1); red =((*p & 0x0e00)>>6 ); red =red +red +red ; red +=87; red >>=4; red <<= (uiplot_redshift +1); green=((*p & 0xe000)>>10 ); green =green +green +green ; green +=87; green >>=4; green <<= (uiplot_greenshift +1); //#endif uiplot_palcache[col ] = (blue ) | (red ) | (green) ; /* normal */ blue >>=1; /* do all 1/2 */ red >>=1; green >>=1; blue=(blue ) | (red ) | (green); /* do work(use blue value) */ uiplot_palcache[col + 128] = blue ; /* shadow(1/2 briteness) */ uiplot_palcache[col + 64] = blue | (16 << uiplot_blueshift ) | (16 << uiplot_redshift ) | (16 << uiplot_greenshift); /* hilight(hilight briteness) */ // } } #endif
ええと、おそらくオリジナルの該当部分は、ううん、このソース。メモが沢山ありすぎでどれだかワカラン。山勘で。
#if 00 void uiplot_checkpalcache(int flag) { unsigned int col; uint16 *p; /* intel short */ int red,green,blue; for (col = 0; col < 64; col++) { /* the CRAM has 64 colours */ if (!flag && !vdp_cramf[col]) continue; vdp_cramf[col] = 0; p = (uint16 *)vdp_cram +col; /* point p to the two-byte CRAM entry */ blue = (*p & 0x000e) << (uiplot_blueshift +1); red =((*p & 0x0e00)>>8 )<< (uiplot_redshift +1); green=((*p & 0xe000)>>12 )<< (uiplot_greenshift +1); uiplot_palcache[col] = (blue ) | (red ) | (green) ; /* normal */ blue >>=1; /* do all 1/2 */ red >>=1; green >>=1; blue=(blue ) | (red ) | (green); /* do work(use blue value) */ uiplot_palcache[col + 128] = (blue) ; /* shadow */ uiplot_palcache[col + 64] = (blue) | (16 << uiplot_blueshift ) | (16 << uiplot_redshift ) | (16 << uiplot_greenshift); /* hilight */ } } #endif
これかなあ。まあ違うかもしれんが雰囲気は解かるでしょ?っていうかこれみて雰囲気がワカンナイ奴は、 多分。ワカラン。 (20:18) ■ ええとこれは何をやってるのかな? □まず0から15まで、つまり(0から0x0f)まで、を(0x0e)でマスクして、(つまり、 x & 0x0e) おもむろに一番下のビットを捨てるだろ。 つまり、0と1は0、2と3は2、...、14と15は14(0x0e)。 □次は4倍してますな。(つまり、 x<<2 ) 最大14だから、4倍すると、14x4は56。 最小の0の場合はやっぱし0。 □次は3倍してますな。 最大56だから、3倍すると、14x4x3は168。 最小の0の場合はやっぱし0。 □最後に87を足します。 最大168だから、87を足すと、14x4x3+87は255。つまり0xff 最小の0の場合は87。
メガドラ真っ黒が回路上出ません。パレットにRGB=(0,0,0)を指定すると、 回路上かなり明るいグレーが出る。RGB改造しても事情はまったく同じ。 これを止めるのは、メガドラ実機の本体を開けて、SEGAのカスタムVDPからSONYのCXA1145 (民生用「RGB→コンポジットビデオ」エンコーダーのチップ。あーん専門よーごナノは許して。お願い) までの接続部分を改造する必要がある。 が、そんな改造したつー話は聞いた事ないよ。物好きな管理人が試しただけだよ。ここ手直ししちゃうと、 エミュの画質になっちゃって、メガドラの画質じゃなくなるよ。ちなみにここの回路は過去日記漁ればどっかに あるよ。ただし定数が書いてないから、計算は出来ないんだけどな ところで、その「87」ってどっから出てきたの? はい、256/3は約87(注:85.333)でし。 そう、87/255は、約34.11764% つまり、RGB=(0,0,0)でも1/3グライの明るさのグレイ(灰色)が出てしまう訳。
メガドラ後期のソフトは、この黒が絶対に出せない事を前提に画作りをしてある。 暗めの灰色を使いたいなと思えば、RGB=(0,0,0)を指定する。 総ての「画」がメガドラでは「眠くなる」のだ。これは実機がそうなんだから仕方がないだろ。
が、これは初期の頃には「知られざる事実」だった。当然メガドラ実機は最終調整であって、 グラフィッカーは開発機、例えばPC98とかX68000とかでお絵かきをして、フログラマーに よろしくちゅー。ってデーター渡すんである。(FDD運輸とかHDDに残しっぱなしとかで) もちろん「実機」では予想外に汚い色になる。が、そのうち改良されるもんだと思ってた。 が、何年経っても改良される気配はないし、そもそも世間のメガドラは変な色になっちゃう奴しか 存在しないんだし、最新鋭の「テラドライブ」でも直ってねー。つうわけで、後期のソフトは開き直って、 メガドラガンマに対応した絵づくりをした為、エミュでは非常に色が汚い。 (テラドライブとワンダーメガの画質なら持ってるから判るが、レーザーアクティブのメガLDパックの画質は 持ってないから判らん。管理人の記憶だが、店頭でみた感じでは違いはなかった。つまりありゃ規格だな)
■纏めると、 A.初期のソフト(大部分)は「メガドラガンマ」がない方がキレイ。特にPSPではキレイ。(例えばTF3はこのカテゴリ) B.後期のソフト(の一部)は「メガドラガンマ」がないと、ゲーム画面がみれない程キタナイ。 「ソーシャルキングダム」「ファンタシースターⅣの一部」その他。 「MD版デンジャラスシード」は比較的初期(発売一年後?二年後?グライ。(調べないと解からん)中期にするか)だが、 実機での画質チェックがされてる。 (エミュ(メガドラガンマなし)では一部の面が見れない程キタナイ。genecystで初めて遊んだ時、 あまりに違う画面なので、てっきり吸出し失敗して色がバグったのかと思った) (21:27) ■ところで、ガンマって書いてあるからてっきり(原点と交わる)曲線だとおもったろ。いいんだよ直線(リニアー)でも、 一般的なガンマ式思い浮かべただろ。頭かたいつ。コンパイルのぷよ饅頭でも喰べて(要デストロイヤーorどらえもん) 頭14連鎖させなさい。(義務) ■「ファンタシースターⅣ」って、セガのHPに行ったら、「ファンタシースター~千年紀の終わりに~」って 名前なんですね。(買ったんだから覚えてろよ)そういやタイトルに「Phantasy Star The end of the millennium」 って描いてあるな。だってメガドラのパッケージ無駄にかさばるんだもん。捨てるでしょ普通。 箱の紙と説明書は、どっかにあるが、万一火事になったら絶対に灰になる場所に保管してある(つまり何処にあるのか判らん) 「ファンタシースター」っていえばマークⅢの奴(元祖)を(メガアダプタなしで)メガドラで動作できる限定版が あったから、 マニアは、そっちを連想しちゃうんですわ。それに開発中は確かに「ファンタシースターⅣ」ってタイトルだったし。 ロゴまであって、デモとかしてたじゃん東京おもちゃショーで。発売されたら、改題されてる。 「OutRun2019」だって、メガドライバーの心のタイトルは「ジャンカーズハイ」ですよ。 つい最近、うっかり幻影を見て、ああこんな所で生き残ってたのか。でも東京おもちゃショー版とは内容が全然違うな。 あっちの方が分岐がない分テンポが良いし、ダイジェストだから、ステージが多彩だし。 あれも、ダイジェストモード(おまけ)で付けといてくれれば、良かったのに、とか思ったり。思わなかったり。 (22:35)

■ひいひい。流石に御託は書き疲れたので「メガドラガンマ」テスト実装してみたつ。ソースはこう。 (別にA20改造しても同じでしょ?えっと、「/src/cpp/ras.cpp」ね?変更部は#ifの中だけだよ、判り易い用に多めに表示)
// The main interface function, to generate a scanline void md_vdp::draw_scanline(struct bmap *bits, int line) { unsigned short *ptr, i; // Set the destination in the bmap dest = bits->data + (bits->pitch * (line + 8) ); //+ 16); // If bytes per pixel hasn't yet been set, do it Bpp = 2; // If the palette's been changed, update it if(dirt[0x34] & 2) { ptr = highpal; for(i = 0; i < 128; i += 2){ #if 00 *ptr++ =((cram[i+1]&0x0e) << 1 ) | ((cram[i+1]&0xe0) << 2 ) | ((cram[i ]&0x0e) << 11); /* -GGG GGRR RRRB BBBB grb=555 */ /* -ggg --rr r--b bb-- */ #else /* メガドラガンマ、テスト実装 */ int blue; int red; int green; blue =((cram[i+1]&0x0e)<<2); blue =blue +blue +blue ; blue +=87; red =((cram[i+1]&0xe0)>>2); red =red +red +red ; red +=87; green =((cram[i ]&0x0e)<<2); green =green +green +green ; green +=87; *ptr++ =( (blue &0xf8)>> 3) | /* ここはマスク要らない */ ( (red &0xf8)<< 2) | ( (green&0xf8)<< 7); // *ptr++ =( (blue &0xe0)>> (4-1)) | // ( (red &0xe0)<< 2) | // ( (green&0xe0)<< (11-4)); #endif } // Clean up the dirt dirt[0x34] &= ~2; pal_dirty = 1; } 以下同じ。
初めて見た時は、眠気が強調されすぎてる気がするが、ゲームを進めると、 そうそう、これがメガドラ色って感じ(ファンタシースター千年記、注4)でチェック中。 (次の日の(03/12日)01:05)
どおでもいいけど同ソースの画面消去ルーチンどっかエンバグしてんな。あとで直そ。(きっとlongが使えない)
今度は「サンダーフォースⅢ」の二面でチェック。(あんた二面好きやね。だってメガドラのアイデンティーに関わる問題だし) 実機より多少眠い。あれは「CRT→CRT」のガンマ変換だが、PSPの場合。 「CRT→CRT→液晶」だから、「CRT→液晶」分のガンマ特性を掛けないと辻褄が合わないんだな。 しかし二面でのWAVEを見て考えが吹き飛んだ。 A20ではWAVEは橙色の情けない色。強そうじゃない。 A21ではWAVEははっきり黄色になった。強そうだ。 上のアルゴリズムは、実は単なる掛け算をしてるだけだが、「やねう」氏(注:リンク参照)が言ってたみたいな。 MMXもどき演算で、本質的にパックにまとめられる。 PSPの液晶分のガンマを引くのならば、整数減算で取っといた分を引くか、素直に整数掛け算を使うか。 (どちらも、上の実装例とは違ってRGB三色をパックしたパック演算だよ。上記もパック演算で実装すれば 計算量が「1/3」で済むだろ。だから仮って書いてある。) (03/12、01:35)
■上項の「取っといた分を引く」の意味が解からない方へ。 例えば掛け算命令なんて無い(もしくはとてつもなく遅い)コンピューターがあったとする。 で当然仕事だ。 X*1000を計算してくれ。(注:「*」は掛け算を意味する。Xは正の整数のみ) あなたならどおする。 もちろん、無限にやり方は考えられる。
もちろん計算が速い方が望ましい。 こういうのはパズルだから、直感よりも、もっと良い方法が必ずある。 だが、管理人は見た瞬間に、こう展開するな。 X*1000==X*1024-X*24==X*1024-(X*3)*8==(X<<10)-((X+X+X)<<3) こんなのは何か頭を使わなくても、一瞬で出てくる。(耳で考えてる為、見た瞬間に答えが出ている。) もっともX<<10がトロイのなら、 X<<2とバイト入れ替えに置換しとけ。 (X<<2がトロイならX+X+X+XもしくはX=X+X、X=X+X) (X<<3がトロイならX+X+X+X+X+X+X+XもしくはX=X+X、X=X+X、X=X+X) これのクロックを総て計算して、それで掛け算より少なければ使う、多ければ使わない。それだけの事。 (03/12、01:46)
別解1。(シフトがそこそこだが、シフトの絶対値が多いと遅いコンピューターの場合) (X<<10)-((X+X+X)<<3)==((X<<7)-(X+X+X))<<3 別解2。(<<8が、バイトスワップに置換出来て、シフトが遅いコンピューターの場合) (X<<10)-((X+X+X)<<3)==((X<<8)-((X+X+X)<<1))<<2 「<<8」はバイトスワップに置換。「<<1」、「<<2」はシフトではなく加算の繰り返し。
洋服もプログラムもTPOが大事。何事にも絶対的な回答はない。 (03/12、02:15)
■ちう訳で擬似MMX化(パックド演算)にしてみた。が、上手くいかない。どこか間違えてるらしい。 とりあえず今日は遅いからねる。下記に該当ソースを上げる。
うまくいかない奴(なんでだろ??) #if 1 /* メガドラガンマ、擬似MMX風、実装 */ int grb; grb =((cram[i ]&0x0e)<<9)|((cram[i+1]&0xe0) )|((cram[i+1]&0x0e)>>1); /* -ggG GGrr RRRb bBBB 7:7:7=0x1ce7 */ grb =grb +grb +grb ; // grb = ((10<<10)|(10<<5)|(10)); /* 10==31-21==31-(3*7)==[0001_1111]-(3*[0000_0111]) */ grb = ((10<<10)|(10<<5)|(10)); /* 7*3=21=0x15=[0001_0101], [0001_0101]+[0000_1010]==[0001_1111] */ /* -GGG GGRR RRRB BBBB grb=555 */ /* -ggg --rr r--b bb-- 0x739c */ *ptr++ =( grb & 0x739c ); /* */ #endif
うまくいく奴(さっきと同じもの) #if 00 /* メガドラガンマ、テスト実装 */ int blue; int red; int green; blue =((cram[i+1]&0x0e)<<2); blue =blue +blue +blue ; blue +=87; red =((cram[i+1]&0xe0)>>2); red =red +red +red ; red +=87; green =((cram[i ]&0x0e)<<2); green =green +green +green ; green +=87; *ptr++ =( (blue &0xf8)>> 3) | /* ここはマスク要らない */ ( (red &0xf8)<< 2) | ( (green&0xf8)<< 7); // *ptr++ =( (blue &0xe0)>> (4-1)) | // ( (red &0xe0)<< 2) | // ( (green&0xe0)<< (11-4)); #endif
(03/12、03:49)