diff --git a/PROJECT/Project.dsp b/PROJECT/Project.dsp new file mode 100644 index 0000000..558bab0 --- /dev/null +++ b/PROJECT/Project.dsp @@ -0,0 +1,99 @@ +# Microsoft Developer Studio Project File - Name="Project" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=Project - Win32 el +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Project.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Project.mak" CFG="Project - Win32 el" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Project - Win32 el" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Project___Win32_el" +# PROP BASE Intermediate_Dir "Project___Win32_el" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fr /YX /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x411 /d "NDEBUG" +# ADD RSC /l 0x411 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 ddraw.lib dsound.lib dinput.lib d3drm.lib dplayx.lib amstrmid.lib strmbase.lib dxguid.lib uuid.lib ole32.lib imm32.lib kernel32.lib user32.lib advapi32.lib comdlg32.lib gdi32.lib winmm.lib libc.lib /nologo /subsystem:windows /pdb:none /machine:I386 /nodefaultlib /force /out:"..\Game.exe" +# Begin Target + +# Name "Project - Win32 el" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\game.cpp +DEP_CPP_GAME_=\ + ".\bmpsave.cpp"\ + ".\el.h"\ + ".\mouse.cpp"\ + ".\viewer.cpp"\ + +NODEP_CPP_GAME_=\ + ".\dmusicc.h"\ + ".\dmusici.h"\ + ".\dxfile.h"\ + ".\rmxfguid.h"\ + ".\rmxftmpl.h"\ + ".\streams.h"\ + +# End Source File +# Begin Source File + +SOURCE=.\inifile.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\main.ico +# End Source File +# End Group +# End Target +# End Project diff --git a/PROJECT/Project.dsw b/PROJECT/Project.dsw new file mode 100644 index 0000000..fb1dd6c --- /dev/null +++ b/PROJECT/Project.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# 警告: このワークスペース ファイル を編集または削除しないでください! + +############################################################################### + +Project: "Project"=.\Project.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/PROJECT/bmpsave.cpp b/PROJECT/bmpsave.cpp new file mode 100644 index 0000000..493d907 --- /dev/null +++ b/PROJECT/bmpsave.cpp @@ -0,0 +1,1469 @@ + + + +//******************************************************************************* +//* +//******************************************************************************* + +/* +256色bmp画像として保存 +*/ +void pce_rom_FG_DspBMP(); +void pce_rom_BG_DispBMP(); + +/* +アラインメントがあるため、このままファイルに出力しないでください。 +ヘッダサイズは(14+40+1024) +*/ +struct BMAPHEADER_2 { + unsigned char bfType0; //1 データ形式(B) + unsigned char bfType1; //1 データ形式(M) + //<--ここにデータギャップが。以降2ずつずれます。 + unsigned long bfSize; //4 ファイルサイズ + unsigned short bfReserved1; //2 予約 + unsigned short bfReserved2; //2 予約 + unsigned long bfOffBits; //4 ビットマップデータの開始オフセット + unsigned long biSize; //4 ヘッダーのサイズ(以下のデータ) + long biWidth; //4 水平ドット数 + long biHeight; //4 垂直ドット数 + unsigned short biPlanes; //2 プレーン数 + unsigned short biBitCount; //2 1ピクセル当たりのビット数(8) + unsigned long biCompression; //4 圧縮形式(0=無し) + unsigned long biSizeImage; //4 ビットマップデータサイズ + long biXPixPerMeter; //4 水平解像度 + long biYPixPerMeter; //4 垂直解像度 + unsigned long biClrUsed; //4 使用色数 + unsigned long biClrImporant; //4 重要な色? + unsigned char palet[256][4]; //1024 256色パレット +}bitmapstr; + +//#define BMPW 600 //保存する画像の幅 +#define BMPW 640 //保存する画像の幅 +#define BMPH 1280 //高さ 211209 +//#define BMPH 1500 //高さ + +char bmpbuf[BMPW*BMPH+100]; + +char fileNbuf[1024]; + +//******************************************************************************* +//* +//******************************************************************************* + +//フルパスからファイル名だけを取り出します。 +char * GetFilemeiDake( char *fullpath ) +{ + //消えないようにスタティックに + static char szDrive[8], szPath[MAX_PATH], szFName[MAX_PATH], szExt[MAX_PATH]; + + // _splitpath_s(fullpath, + // szDrive, sizeof(szDrive), + // szPath, sizeof(szPath), + // szFName, sizeof(szFName), + // szExt, sizeof(szExt)); + + _splitpath(fullpath, szDrive, szPath, szFName, szExt); + + return szFName; +} + +//******************************************************************************* +//* +//******************************************************************************* + +void bmpsave() +{ + int lp,i; + FILE *fp; + //char fileNbuf[100]; + + bitmapstr.bfType0 = 'B'; + bitmapstr.bfType1 = 'M'; + //bitmapstr.bfSize =BMPW*BMPH+(sizeof BMAPHEADER); //ファイルサイズ + bitmapstr.bfSize =BMPW*BMPH+(14+40+1024); //ファイルサイズ + bitmapstr.bfReserved1 =0; //予約 + bitmapstr.bfReserved2 =0; //予約 + bitmapstr.bfOffBits =(14+40+1024); //ビットマップデータの開始オフセット + bitmapstr.biSize =0x28; // 40;//ヘッダーのサイズ(以下のデータ) + bitmapstr.biWidth =BMPW; //水平ドット数 + bitmapstr.biHeight =BMPH; //垂直ドット数 + bitmapstr.biPlanes =1; //プレーン数 + bitmapstr.biBitCount =8; //1ピクセル当たりのビット数(8) + bitmapstr.biCompression=0; //圧縮形式(0=無し) + bitmapstr.biSizeImage =0; //ビットマップデータサイズ + bitmapstr.biXPixPerMeter=0; //水平解像度 + bitmapstr.biYPixPerMeter=0; //垂直解像度 + bitmapstr.biClrUsed =256; //使用色数 + bitmapstr.biClrImporant=0; //重要な色? + // bitmapstr.palet[256][4]=; //256色パレット + //01234567を32倍して0,32,64, 96,128,160,192,224 + //0以外のとき、+31で 0,63,95,127,159,191,223,255 + bitmapstr.palet[0][0]=0; + bitmapstr.palet[0][1]=0; + bitmapstr.palet[0][2]=0; + bitmapstr.palet[0][3]=0; //reserved; + for(lp=1;lp<16;lp++){ + bitmapstr.palet[lp][0]=lp*16-1; + bitmapstr.palet[lp][1]=lp*16-1; + bitmapstr.palet[lp][2]=lp*16-1; + bitmapstr.palet[lp][3]=0; //reserved; + } + + //255番の色に白をセット + bitmapstr.palet[255][0]=255; //B + bitmapstr.palet[255][1]=255; //G + bitmapstr.palet[255][2]=255; //R + bitmapstr.palet[255][3]=0; //reserved; + + //254番の色に緑をセット + bitmapstr.palet[254][0]=0; //B + bitmapstr.palet[254][1]=255; //G + bitmapstr.palet[254][2]=0; //R + bitmapstr.palet[254][3]=0; //reserved; + + //253番の色に赤をセット + bitmapstr.palet[253][0]=0; //B + bitmapstr.palet[253][1]=100; //G + bitmapstr.palet[253][2]=255; //R + bitmapstr.palet[253][3]=0; //reserved; + + //252番の色に黄色をセット + bitmapstr.palet[252][0]=0; //B + bitmapstr.palet[252][1]=240; //G + bitmapstr.palet[252][2]=255; //R + bitmapstr.palet[252][3]=0; //reserved; + + //------------------------------------------------------ + + for(lp=0;lp='0')&&( code <='9')) + code = code-'0'; + else if((code >='A')&&( code <='Z')) + code = code-'A'+10; + else if((code >='a')&&( code <='z')) + code = code-'a'+10+26; + else if(code ==' ') + code = code-'a'+10+26+26; + else if(code =='(') + code = code-'a'+10+26+26+1; + else if(code ==')') + code = code-'a'+10+26+26+2; + else{} + + code *= 64; + + int PalNo; + if( col == 0 ) PalNo=255; + else PalNo = col; //255 254 253 + + //16x16dot + for(lpy=0;lpy<8;lpy++){ + for(lpx=0;lpx<8;lpx++){ + wok = mojidata[code + lpx+lpy*8]; + if( wok == 'O' ){ + bmpbuf[(BMPW*BMPH) +(ofsx+lpx) + -(ofsy+lpy+1)*(BMPW)] = PalNo; + //-(ofsy+lpy+1)*(BMPW)] = 15; + } + } + } +} + + + +char moji_4x8_data[]={ +" OO "\ +"O O"\ +"O O"\ +"O O"\ +"O O"\ +"O O"\ +" OO "\ +" "\ +\ +" O "\ +" OO "\ +" O "\ +" O "\ +" O "\ +" O "\ +" O "\ +" "\ +\ +" OO "\ +"O O"\ +" O"\ +" O"\ +" O "\ +" O "\ +"OOOO"\ +" "\ +\ +" OO "\ +"O O"\ +" O"\ +" O "\ +" O"\ +"O O"\ +" OO "\ +" "\ +\ +" O "\ +"O O "\ +"O O "\ +"O O "\ +"OOOO"\ +" O "\ +" O "\ +" "\ +\ +"OOOO"\ +"O "\ +"O "\ +"OOO "\ +" O"\ +" O"\ +"OOO "\ +" "\ +\ +" OO "\ +"O O"\ +"O "\ +"OOO "\ +"O O"\ +"O O"\ +" OO "\ +" "\ +\ +"OOOO"\ +" O"\ +" O"\ +" O "\ +" O "\ +" O "\ +" O "\ +" "\ +\ +" OO "\ +"O O"\ +"O O"\ +" OO "\ +"O O"\ +"O O"\ +" OO "\ +" "\ +\ +" OO "\ +"O O"\ +"O O"\ +" OOO"\ +" O"\ +" O"\ +" OO "\ +" "\ +\ +" OO "\ +"O O"\ +"O O"\ +"O O"\ +"OOOO"\ +"O O"\ +"O O"\ +" "\ +\ +"OO "\ +"O O "\ +"O O "\ +"OOO "\ +"O O"\ +"O O"\ +"OOO "\ +" "\ +\ +" OO "\ +"O O"\ +"O "\ +"O "\ +"O "\ +"O O"\ +" OO "\ +" "\ +\ +"OO "\ +"O O "\ +"O O"\ +"O O"\ +"O O"\ +"O O "\ +"OO "\ +" "\ +\ +"OOO0"\ +"O "\ +"O "\ +"OOO "\ +"O "\ +"O "\ +"OOOO"\ +" "\ +\ +"OOOO"\ +"O "\ +"O "\ +"OOO0"\ +"O "\ +"O "\ +"O "\ +" " +}; + + +/* + 0...9 A...F + 8x8=64バイトのドットデータ。 + col==0 白 + col==0以外 緑色 +*/ +void ascii_BMP4X8(int code,int ofsx,int ofsy, int col=0) +{ + int lpx,lpy; + unsigned char wok; + + //if(code==' ')return; + if(code=='\0')return; + if(code=='\n')return; + + if((code >='0')&&( code <='9')) + code = code-'0'; + else if((code >='A')&&( code <='Z')) + code = code-'A'+10; + else{ return; } + + code *= 32; //1文字32byte + + int PalNo; + if( col == 0 ) PalNo=255; + else PalNo = col; //255 254 253 + + //16x16dot + for(lpy=0;lpy<8;lpy++){ + for(lpx=0;lpx<4;lpx++){ + wok = moji_4x8_data[code + lpx+lpy*4]; + if( wok == 'O' ){ + bmpbuf[(BMPW*BMPH) +(ofsx+lpx) + -(ofsy+lpy+1)*(BMPW)] = PalNo; + //-(ofsy+lpy+1)*(BMPW)] = 15; + } + } + } +} + + + +//******************************************************************************* +//* +//******************************************************************************* + +void FG_BoxBMP( unsigned short *romptr,int dispadr_add, int ofsx,int ofsy , int bkno) +{ + int lp,linecnt,dotcnt,lpx,lpy,pln_cnt,wok; + unsigned short linedata; //1ライン16ドットのデータ + unsigned short setbit; //1 2 4 8(プレーンに設定するビット) + + char msgbuf[100]; + //elDraw::ShowFormat( DISP_RU_X+ofsx,DISP_RU_Y-16+ofsy,"ADR:$%06X TYPE=SPR",rom_datacnt+dispadr_add); + + for(lp=0;lp<100;lp++) + msgbuf[100]='\0'; + sprintf(msgbuf,"%06X SPR",rom_datacnt+dispadr_add); + for(lp=0;lp<16;lp++){ + if(msgbuf[lp]=='\0')break; + ascii_BMP(msgbuf[lp], ofsx+lp*8,ofsy-8); + } + + sprintf(msgbuf,"%03X",bkno); + for(lp=0;lp<3;lp++){ + ascii_BMP(msgbuf[lp], ofsx+96+lp*8,ofsy-8,254); + } + + sprintf(msgbuf,"%03X %03X %03X %03X",bkno*4,bkno*4+1,bkno*4+2,bkno*4+3 ); + for(lp=0;lp<16;lp++){ + ascii_BMP(msgbuf[lp], ofsx+lp*8,ofsy-16,253); //253 赤色 + } + + //64個のスプライトを表示 + for(lp=0;lp<64;lp++){ + + for(wok=0;wok<256;wok++){ + dot_wok[wok]=0; //黒でクリア + } + + //0のプレーン=1 1のプレーン=2 2のプレーン=4 3のプレーン=8 + setbit = 0x01; + + for(pln_cnt=0;pln_cnt<4;pln_cnt++){ //プレーン4枚 + + for(linecnt = 0;linecnt<16;linecnt++){ //16ライン + linedata = *romptr; //1ライン分データを取りだし + romptr++; + + for(dotcnt = 0;dotcnt<16;dotcnt++){ //16ビット + //・HIGHのビットを調べます ONならデータをカラーを設定 + if(linedata & 0x8000){ + dot_wok[linecnt*16+dotcnt] |= setbit; + } + //・ワード情報を<<1 + linedata = linedata<<1; + } + } + setbit = setbit <<1 ; //1 2 4 8 + } + + //16x16dot + for(lpy=0;lpy<16;lpy++){ + for(lpx=0;lpx<16;lpx++){ + wok = dot_wok[lpy*16+lpx]; //0...15 palet no. + + //wok = wok+viewer_Pal * 16; //セレクトされている16色パレット + //elDraw::ColorFill( + // ofsx+DISP_RU_X+sprt_disploctbl[lp][0]+lpx, + // ofsy+DISP_RU_Y+sprt_disploctbl[lp][1]+lpy, + // ofsx+DISP_RU_X+sprt_disploctbl[lp][0]+lpx+1, + // ofsy+DISP_RU_Y+sprt_disploctbl[lp][1]+lpy+1, + // RGB16( + // windows_paltbl[ palet[wok].red ], + // windows_paltbl[ palet[wok].green ], + // windows_paltbl[ palet[wok].blue ]) + // ); + bmpbuf[(BMPW*BMPH) +(ofsx+lpx+sprt_disploctbl[lp][0]) + -(ofsy+lpy+1+sprt_disploctbl[lp][1])*(BMPW)] = wok; + } + } + } +} + + + + +//******************************************************************************* +//* +//******************************************************************************* + +void pce_rom_FG_DspBMP() +{ + + int i; + unsigned short *romptr; + + //elDraw::ShowFormat( DISP_RU_X,DISP_RU_Y-16,"ADDRESS:%-8Xh TYPE=SPRITE",rom_datacnt); + + romptr = rom_ptr; //オリジナルの値を壊さないため + + //バンク番号を計算 + int bkNo; + bkNo = rom_datacnt / 0x2000; //端数はとります。その見えている窓がどのバンクに属するか + + int indent=24; + int romofs=0x000; + for( i=0 ; i<8; i++ ) + { + FG_BoxBMP( romptr + romofs , romofs*2 , 24+0, 32+(128*i)+(indent*i) ,bkNo+i*4 ); + FG_BoxBMP( romptr +(romofs+0x1000),(romofs+0x1000)*2, 24+128+32,32+(128*i)+(indent*i) ,bkNo+i*4+1 ); + FG_BoxBMP( romptr +(romofs+0x2000),(romofs+0x2000)*2, 24+256+64,32+(128*i)+(indent*i) ,bkNo+i*4+2 ); + FG_BoxBMP( romptr +(romofs+0x3000),(romofs+0x3000)*2, 24+384+96,32+(128*i)+(indent*i) ,bkNo+i*4+3 ); + + romofs += 0x4000; + } + + +// FG_BoxBMP( romptr ,0x0000, 16+0, 32 ,bkNo ); +// FG_BoxBMP( romptr + 0x1000,0x2000, 16+128+16,32 ,bkNo+1 ); //short*0x1000 = 0x2000byte +// FG_BoxBMP( romptr + 0x2000,0x4000, 16+256+32,32 ,bkNo+2 ); +// FG_BoxBMP( romptr + 0x3000,0x6000, 16+384+48,32 ,bkNo+3 ); +// +// FG_BoxBMP( romptr + 0x4000,0x8000, 16+0, 32+128+16 ,bkNo+4 ); +// FG_BoxBMP( romptr + 0x5000,0xa000, 16+128+16,32+128+16 ,bkNo+5 ); +// FG_BoxBMP( romptr + 0x6000,0xc000, 16+256+32,32+128+16 ,bkNo+6 ); +// FG_BoxBMP( romptr + 0x7000,0xe000, 16+384+48,32+128+16 ,bkNo+7 ); +// +// FG_BoxBMP( romptr + 0x8000,0x10000, 16+0, 32+256+32 ,bkNo+8 ); +// FG_BoxBMP( romptr + 0x9000,0x12000, 16+128+16,32+256+32 ,bkNo+9 ); +// FG_BoxBMP( romptr + 0xa000,0x14000, 16+256+32,32+256+32 ,bkNo+10 ); +// FG_BoxBMP( romptr + 0xb000,0x16000, 16+384+48,32+256+32 ,bkNo+11 ); +// +// FG_BoxBMP( romptr + 0xc000,0x18000, 16+0, 32+384+48 ,bkNo+12 ); +// FG_BoxBMP( romptr + 0xd000,0x1a000, 16+128+16,32+384+48 ,bkNo+13 ); +// FG_BoxBMP( romptr + 0xe000,0x1c000, 16+256+32,32+384+48 ,bkNo+14 ); +// FG_BoxBMP( romptr + 0xf000,0x1e000, 16+384+48,32+384+48 ,bkNo+15 ); +// +// FG_BoxBMP( romptr + 0x10000,0x10000*2, 16+0, 32+128*4+16*4 ,bkNo+16 ); +// FG_BoxBMP( romptr + 0x11000,0x11000*2, 16+128+16,32+128*4+16*4 ,bkNo+17 ); +// FG_BoxBMP( romptr + 0x12000,0x12000*2, 16+256+32,32+128*4+16*4 ,bkNo+18 ); +// FG_BoxBMP( romptr + 0x13000,0x13000*2, 16+384+48,32+128*4+16*4 ,bkNo+19 ); +// +// FG_BoxBMP( romptr + 0x14000,0x14000*2, 16+0, 32+128*5+16*5 ,bkNo+20 ); +// FG_BoxBMP( romptr + 0x15000,0x15000*2, 16+128+16,32+128*5+16*5 ,bkNo+21 ); +// FG_BoxBMP( romptr + 0x16000,0x16000*2, 16+256+32,32+128*5+16*5 ,bkNo+22 ); +// FG_BoxBMP( romptr + 0x17000,0x17000*2, 16+384+48,32+128*5+16*5 ,bkNo+23 ); +// +// FG_BoxBMP( romptr + 0x18000,0x18000*2, 16+0, 32+128*6+16*6 ,bkNo+24 ); +// FG_BoxBMP( romptr + 0x19000,0x19000*2, 16+128+16,32+128*6+16*6 ,bkNo+25 ); +// FG_BoxBMP( romptr + 0x1a000,0x1a000*2, 16+256+32,32+128*6+16*6 ,bkNo+26 ); +// FG_BoxBMP( romptr + 0x1b000,0x1b000*2, 16+384+48,32+128*6+16*6 ,bkNo+27 ); +// +// FG_BoxBMP( romptr + 0x1c000,0x1c000*2, 16+0, 32+128*7+16*7 ,bkNo+28 ); +// FG_BoxBMP( romptr + 0x1d000,0x1d000*2, 16+128+16,32+128*7+16*7 ,bkNo+29 ); +// FG_BoxBMP( romptr + 0x1e000,0x1e000*2, 16+256+32,32+128*7+16*7 ,bkNo+30 ); +// FG_BoxBMP( romptr + 0x1f000,0x1f000*2, 16+384+48,32+128*7+16*7 ,bkNo+31 ); +} + + + +//******************************************************************************* +//* +//******************************************************************************* + +void BG_BoxBMP( unsigned short *romptr,int dispadr_add, int ofsx,int ofsy, int bkno) +{ + int lp,linecnt,dotcnt,lpx,lpy,wok; + unsigned long linedata; //1ライン16ドットのデータ(32ビット幅) + unsigned short setbit; //1 2 4 8(プレーンに設定するビット) + + char msgbuf[100]; + //elDraw::ShowFormat( DISP_RU_X+ofsx,DISP_RU_Y-16+ofsy,"ADR:$%06X TYPE=BG ",rom_datacnt+dispadr_add); + for(lp=0;lp<100;lp++) + msgbuf[100]='\0'; + sprintf(msgbuf,"%06X BG",rom_datacnt+dispadr_add); + for(lp=0;lp<16;lp++){ + if(msgbuf[lp]=='\0')break; + ascii_BMP(msgbuf[lp], ofsx+lp*8,ofsy-8); + } + + //sprintf(msgbuf,"%02X",bkno); + sprintf(msgbuf,"%03X",bkno); + for(lp=0;lp<3;lp++){ + ascii_BMP(msgbuf[lp], ofsx+96+lp*8,ofsy-8,254); + } + + for(int i=0; i<4; i++ ) + { + sprintf(msgbuf,"%03X",bkno*4+i); + ascii_BMP4X8(msgbuf[0], ofsx -12-2 ,ofsy+32*i,253); //253 赤色 + ascii_BMP4X8(msgbuf[1], ofsx+1*4-12-1 ,ofsy+32*i,252); //252 赤っぽい色 + ascii_BMP4X8(msgbuf[2], ofsx+2*4-12 ,ofsy+32*i,253); //253 赤色 + } + + //256個のBGを表示 + //for(lp=0;lp<256;lp++){ + + //※指定幅、高さの画像の表示 + for(lp=0;lp< rom_BG_High*rom_BG_Width;lp++){ + + for(wok=0;wok<256;wok++){ + dot_wok[wok]=0; //黒でクリア + } + + //0のプレーン=1 1のプレーン=2 2のプレーン=4 3のプレーン=8 + for(linecnt = 0;linecnt<8;linecnt++){ //8word(2プレーン分) + setbit = 0x01; + linedata = *romptr; //16bitデータを取りだし + romptr++; + + //上位8ビットだけしらべて、ビットがONなら横8ドットに展開します + for(dotcnt = 0;dotcnt<8;dotcnt++){ + //・HIGHのビットを調べます ONならデータをカラーを設定 + if(linedata & 0x80){ + dot_wok[linecnt*8+dotcnt] |= setbit; + } + //・byte情報を<<1 + linedata = linedata<<1; + } + + //プレーン++ + setbit = setbit <<1 ; //1 2 4 8 + //下位8ビットをしらべて、ビットがONなら横8ドットに展開します + for(dotcnt = 0;dotcnt<8;dotcnt++){ + //・HIGHのビットを調べます ONならデータをカラーを設定 + if(linedata & 0x800000){ + dot_wok[linecnt*8+dotcnt] |= setbit; + } + //・byte情報を<<1 + linedata = linedata<<1; + } + } + + for(linecnt = 0;linecnt<8;linecnt++){ //8word(2プレーン分) + setbit = 0x04; + linedata = *romptr; //16bitデータを取りだし + romptr++; + + //上位8ビットだけしらべて、ビットがONなら横8ドットに展開します + for(dotcnt = 0;dotcnt<8;dotcnt++){ + //・HIGHのビットを調べます ONならデータをカラーを設定 + if(linedata & 0x080){ + dot_wok[linecnt*8+dotcnt] |= setbit; + } + //・byte情報を<<1 + linedata = linedata<<1; + } + + //プレーン++ + setbit = setbit <<1 ; //1 2 4 8 + //下位8ビットをしらべて、ビットがONなら横8ドットに展開します + for(dotcnt = 0;dotcnt<8;dotcnt++){ + //・HIGHのビットを調べます ONならデータをカラーを設定 + if(linedata & 0x800000){ + dot_wok[linecnt*8+dotcnt] |= setbit; + } + //・byte情報を<<1 + linedata = linedata<<1; + } + } + + //8x8dot + for(lpy=0;lpy<8;lpy++){ + for(lpx=0;lpx<8;lpx++){ + wok = dot_wok[lpy*8+lpx]; //0...15 palet no. + bmpbuf[(BMPW*BMPH) +(ofsx+lpx+(lp%rom_BG_Width)*8) + -(ofsy+lpy+1+(lp/rom_BG_High)*8)*(BMPW)] = wok; + + //elDraw::ColorFill( + // //DISP_RU_X+(lp%16)*8 +lpx, + // //DISP_RU_Y+(lp/16)*8 +lpy, + // //DISP_RU_X+(lp%16)*8 +lpx+1, + // //DISP_RU_Y+(lp/16)*8 +lpy+1, + // DISP_RU_X+ofsx+(lp%rom_BG_Width)*8 +lpx,//※指定幅、高さの画像の表示 + // DISP_RU_Y+ofsy+(lp/rom_BG_High)*8 +lpy, + // DISP_RU_X+ofsx+(lp%rom_BG_Width)*8 +lpx+1, + // DISP_RU_Y+ofsy+(lp/rom_BG_High)*8 +lpy+1, + // RGB16( + // windows_paltbl[ palet[wok].red ], + // windows_paltbl[ palet[wok].green ], + // windows_paltbl[ palet[wok].blue ]) + // ); + } + } + } +} + + + +//******************************************************************************* +//* +//******************************************************************************* + +void pce_rom_BG_DispBMP(){ + + int i; + unsigned short *romptr; + romptr = rom_ptr; //オリジナルの値を壊さないため + + //バンク番号を計算 + int bkNo; + bkNo = rom_datacnt / 0x2000; //端数はとります。その見えている窓がどのバンクに属するか + + int indent=24; + int romofs=0x000; + for( i=0 ; i<8; i++ ) + { + + BG_BoxBMP( romptr + romofs , romofs*2 , 24+0, 32+(128*i)+(indent*i) ,bkNo+i*4 ); + BG_BoxBMP( romptr +(romofs+0x1000),(romofs+0x1000)*2, 24+128+32,32+(128*i)+(indent*i) ,bkNo+i*4+1 ); + BG_BoxBMP( romptr +(romofs+0x2000),(romofs+0x2000)*2, 24+256+64,32+(128*i)+(indent*i) ,bkNo+i*4+2 ); + BG_BoxBMP( romptr +(romofs+0x3000),(romofs+0x3000)*2, 24+384+96,32+(128*i)+(indent*i) ,bkNo+i*4+3 ); + + romofs += 0x4000; + } + + +// BG_BoxBMP( romptr ,0x0000, 16+0, 32 ,bkNo ); +// BG_BoxBMP( romptr + 0x1000,0x2000, 16+128+16, 32 ,bkNo+1 ); //short*0x1000 = 0x2000byte +// BG_BoxBMP( romptr + 0x2000,0x4000, 16+256+32, 32 ,bkNo+2 ); +// BG_BoxBMP( romptr + 0x3000,0x6000, 16+384+48, 32 ,bkNo+3 ); +// +// BG_BoxBMP( romptr + 0x4000,0x8000, 16+0, 32+128+16 ,bkNo+4 ); +// BG_BoxBMP( romptr + 0x5000,0xa000, 16+128+16, 32+128+16 ,bkNo+5 ); +// BG_BoxBMP( romptr + 0x6000,0xc000, 16+256+32, 32+128+16 ,bkNo+6 ); +// BG_BoxBMP( romptr + 0x7000,0xe000, 16+384+48, 32+128+16 ,bkNo+7 ); +// +// BG_BoxBMP( romptr + 0x8000,0x10000, 16+0, 32+256+32 ,bkNo+8 ); +// BG_BoxBMP( romptr + 0x9000,0x12000, 16+128+16,32+256+32 ,bkNo+9 ); +// BG_BoxBMP( romptr + 0xa000,0x14000, 16+256+32,32+256+32 ,bkNo+10 ); +// BG_BoxBMP( romptr + 0xb000,0x16000, 16+384+48,32+256+32 ,bkNo+11 ); +// +// BG_BoxBMP( romptr + 0xc000,0x18000, 16+0, 32+384+48 ,bkNo+12 ); +// BG_BoxBMP( romptr + 0xd000,0x1a000, 16+128+16,32+384+48 ,bkNo+13 ); +// BG_BoxBMP( romptr + 0xe000,0x1c000, 16+256+32,32+384+48 ,bkNo+14 ); +// BG_BoxBMP( romptr + 0xf000,0x1e000, 16+384+48,32+384+48 ,bkNo+15 ); +// +// //21/12/09 +// BG_BoxBMP( romptr + 0x10000,0x10000*2, 16+0, 32+128*4+16*4 ,bkNo+16 ); +// BG_BoxBMP( romptr + 0x11000,0x11000*2, 16+128+16,32+128*4+16*4 ,bkNo+17 ); +// BG_BoxBMP( romptr + 0x12000,0x12000*2, 16+256+32,32+128*4+16*4 ,bkNo+18 ); +// BG_BoxBMP( romptr + 0x13000,0x13000*2, 16+384+48,32+128*4+16*4 ,bkNo+19 ); +// +// BG_BoxBMP( romptr + 0x14000,0x14000*2, 16+0, 32+128*5+16*5 ,bkNo+20 ); +// BG_BoxBMP( romptr + 0x15000,0x15000*2, 16+128+16,32+128*5+16*5 ,bkNo+21 ); +// BG_BoxBMP( romptr + 0x16000,0x16000*2, 16+256+32,32+128*5+16*5 ,bkNo+22 ); +// BG_BoxBMP( romptr + 0x17000,0x17000*2, 16+384+48,32+128*5+16*5 ,bkNo+23 ); +// +// BG_BoxBMP( romptr + 0x18000,0x18000*2, 16+0, 32+128*6+16*6 ,bkNo+24 ); +// BG_BoxBMP( romptr + 0x19000,0x19000*2, 16+128+16,32+128*6+16*6 ,bkNo+25 ); +// BG_BoxBMP( romptr + 0x1a000,0x1a000*2, 16+256+32,32+128*6+16*6 ,bkNo+26 ); +// BG_BoxBMP( romptr + 0x1b000,0x1b000*2, 16+384+48,32+128*6+16*6 ,bkNo+27 ); +// +// BG_BoxBMP( romptr + 0x1c000,0x1c000*2, 16+0, 32+128*7+16*7 ,bkNo+28 ); +// BG_BoxBMP( romptr + 0x1d000,0x1d000*2, 16+128+16,32+128*7+16*7 ,bkNo+29 ); +// BG_BoxBMP( romptr + 0x1e000,0x1e000*2, 16+256+32,32+128*7+16*7 ,bkNo+30 ); +// BG_BoxBMP( romptr + 0x1f000,0x1f000*2, 16+384+48,32+128*7+16*7 ,bkNo+31 ); +} diff --git a/PROJECT/data.cpp b/PROJECT/data.cpp new file mode 100644 index 0000000..b083b81 --- /dev/null +++ b/PROJECT/data.cpp @@ -0,0 +1,65 @@ +int exitflg=0; +int rom_BG_High = 16; //BGモード時の表示の大きさ +int rom_BG_Width= 16; + +int rom_Disp_Mode = 0; //0=Sprite 1=BG + + + +int help_flg =0x00; //HELP表示フラグ +int viewer_Pal = 0x00; + +//******************************** +struct palet256_info{ + int red; //8階調あります。 + int green; + int blue; + }; + +struct palet256_info palet[256]; //256色パレット構造体 +struct palet256_info palet_copywok; + +int f1_key; +int f5_key; +int z_key; //palet value ++ +int x_key; //palet value -- +int a_key; //palet value ++ +int s_key; //palet value -- +int q_key; //palet value ++ +int w_key; //palet value -- +int c_key; //copy +int v_key; //past +int up_key; //カーソル移動 +int dn_key; +int lt_key; +int rt_key; + +int num_0key; +int num_1key; +int num_2key; +int num_3key; +int num_4key; +int num_5key; +int num_6key; +int num_7key; +int num_8key; +int num_9key; + +int select_Pal=0; //現在編集中のパレット + +//pce8階調のパレットを256階調に変換 +//int windows_paltbl[8]={0,63,95,127,159,191,223,255}; +//PCE8階調パレットをelの32階調に変換 +//int windows_paltbl[8]={0,6,12,16,20,24,28,31}; + +//int windows_paltbl[8]={0,7,11,15,19,23,27,31}; //2004年 ハイカラーのころ +int windows_paltbl[8]={0,56,88,120,152,184,220,255}; //21/12/08 フルカラー対応 + + + + +int filesize=0; //ファイルサイズが+200hの半端があればヘッダ付き。 +char FileTitle[256]="BMPファイル"; +char FileName[_MAX_PATH]="sample.bmp"; //ディフォルトパレットファイル名 +char RomName[_MAX_PATH]="KungFu.pce"; //ディフォルトロム名 + diff --git a/PROJECT/el.h b/PROJECT/el.h new file mode 100644 index 0000000..92a58b7 --- /dev/null +++ b/PROJECT/el.h @@ -0,0 +1,47148 @@ +/********************************************************************************/ +/* */ +/* Easy Link Library el.h */ +/* */ +/* 2002.9.27 */ +/* */ +/********************************************************************************/ + +/********************************************************************************/ +/* */ +/* 最新版が置いてあるURL */ +/* */ +/* Botchy World */ +/* */ +/* http://www3.justnet.ne.jp/~botchy/index.html */ +/* */ +/* 質問疑問等の発言場所 */ +/* */ +/* 掲示板 */ +/* */ +/* Botchy World の [ Free Talk ] */ +/* */ +/* その他 */ +/* */ +/* ヘルプ */ +/* */ +/* Botchy World の [ Add On ] */ +/* */ +/* サンプル */ +/* */ +/* Botchy World の [ Sample Code ] */ +/* */ +/********************************************************************************/ + +/*---< 各API用ヘッダファイル >--------------------------------------------------*/ + +// 標準API +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// DirectDraw +#include "ddraw.h" + +// Direct3D IM +#ifdef DIRECT3D_IM + + #define D3D_OVERLOADS + + #include "d3d.h" + #include "dxfile.h" + #include "rmxftmpl.h" + #include "rmxfguid.h" + + #ifndef NEWCODE + + #define NEWCODE + + #endif + +#endif + +// DirectSound +#include "dsound.h" + +// DirectInput +#if defined(NEWCODE) && !defined(DIRECTINPUT_VERSION) + + #define DIRECTINPUT_VERSION 0x700 + +#elif DIRECTDRAW_VERSION==0x700 + + #define DIRECTINPUT_VERSION 0x700 + +#endif + +#include "dinput.h" + +// Direct3D RM +#ifdef DIRECT3D + + #include "d3drmwin.h" + + #ifdef NEWCODE + + #pragma message (" el3Dクラスは'NEWCODE'をサポートしておりません。") + + #endif + +#endif + +// DirectMusic +#ifdef DIRECTMUSIC + + #include "dmusicc.h" + #include "dmusici.h" + +#endif + +// DirectPlay +#ifdef DIRECTPLAY + + #include "dplay.h" + +#endif + +// MediaStream ( DirectShow ) +#ifdef MEDIASTREAM + + #include "mmstream.h" + #include "amstream.h" + #include "ddstream.h" + + #ifdef DIRECTSHOW + + #undef DIRECTSHOW + #pragma message (" 'DIRECTSHOW'より'MEDIASTREAM'のほうが優先されます。") + + #endif + + #ifdef ACTIVEMOVIE + + #undef ACTIVEMOVIE + #pragma message (" 'ACTIVEMOVIE'より'MEDIASTREAM'のほうが優先されます。") + + #endif + +#endif + +// DirectShow/ActiveMovie +#ifdef ACTIVEMOVIE + + #ifndef DIRECTSHOW + + #define DIRECTSHOW + + #endif + +#endif + +#ifdef DIRECTSHOW + + #include "streams.h" + +#endif + +// DirectX7以降の新しいコード +#ifdef NEWCODE + + #define LPDIRECTDRAW LPDIRECTDRAW7 + #define LPDIRECTDRAWSURFACE LPDIRECTDRAWSURFACE7 + #define DDSURFACEDESC DDSURFACEDESC2 + #define DDSCAPS DDSCAPS2 + #define IDirectDraw IDirectDraw7 + #define IDirectDrawSurface IDirectDrawSurface7 + + #define DD_UNLOCK(Surface,Para)\ + \ + Surface->Unlock(NULL); + +#else + + #define DD_UNLOCK(Surface,Para)\ + \ + Surface->Unlock(Para); + +#endif + +/*---< 公開変数 >---------------------------------------------------------------*/ + +// ウィンドウハンドル +static HWND hwnd=NULL; + +// ダイアログウィンドウハンドル +static HWND hdlg=NULL; + +// プレビューウィンドウハンドル +static HWND hprv=NULL; + +// デバイスコンテキスト +static HDC hdc; + +// 汎用バッファ +static char Buffer[2048]; + +// elDrawクラスオブジェクト型 ( DirectDraw ) +typedef int DDOBJ; // スプライト + +// elSoundクラスオブジェクト型 ( DirectSound ) +typedef int DSOBJ; // WAVE + +// el3Dクラスオブジェクト型 ( Direct3D RM ) +#ifdef DIRECT3D + + #define D3OBJ LPDIRECT3DRMFRAME // Xファイル + #define D3TXR LPDIRECT3DRMTEXTURE // テクスチャー + typedef int D3SKT; // スケルトン、モーション + +#endif + +// el4Dクラスオブジェクト型 ( Direct3D IM ) +#ifdef DIRECT3D_IM + + typedef int D4OBJ; // ポリゴン + typedef int D4TXR; // テクスチャー + typedef int D4LGT; // ライト + typedef D3DMATRIX D4MTX; // マトリクス + +#endif + +// elMusicクラスオブジェクト型 ( DirectMusic ) +#ifdef DIRECTMUSIC + + typedef int DMOBJ; // ミュージック + +#endif + +// マウス状態 +static int MousePX=0; +static int MousePY=0; +static int MouseLX=0; +static int MouseLY=0; +static int MouseMX=0; +static int MouseMY=0; +static BOOL MousePL=FALSE; +static BOOL MousePR=FALSE; +static BOOL MouseLL=FALSE; +static BOOL MouseLR=FALSE; +static BOOL MouseCL=FALSE; +static BOOL MouseCR=FALSE; +static BOOL MouseDL=FALSE; +static BOOL MouseDR=FALSE; +static BOOL MouseMenu=FALSE; +static UINT MousePush=NULL; +static UINT MouseLast=NULL; + +// キーボード状態 +static UINT PushKey=NULL; +static UINT LastKey=NULL; +static UINT HelpKey=NULL; +static UINT MenuKey=NULL; +static BOOL PushShift=FALSE; + +// [Alt]+[PrintScreen] +#define VK_SNAPSHOT_WINDOW 0x101 + +// float型変換 +#define F(X) (float)(X) + +// フレーム当たりの経過時間 +static float FrameTime=F(0); + +// 点滅フラグ +static BOOL Blink=TRUE; + +// 円周率 +static const double PAI=3.14159265358979323846; +static const double PAI2=PAI*2.0; + +// 回転X座標・ウェーブ座標 ( 360度指定、int型 ) +#define ROUND_X(Angle,Length,Center)\ +\ + (int)(cos((Angle)*PAI2/360)*(Length)+(Center)) + +// 回転Y座標 ( 360度指定、int型 ) +#define ROUND_Y(Angle,Length,Center)\ +\ + (int)(sin((Angle)*PAI2/360)*(Length)+(Center)) + +// 回転X座標・ウェーブ座標 ( ラジアン指定、float型 ) +#define ROTATE_X(Angle,Length,Center)\ +\ + F(cos(F(Angle))*F(Length)+F(Center)) + +// 回転Y座標 ( ラジアン指定、float型 ) +#define ROTATE_Y(Angle,Length,Center)\ +\ + F(sin(F(Angle))*F(Length)+F(Center)) + +// 16ビットRGBの生成 ( 0〜31 ) +#define RGB16(r,g,b)\ +\ + (((WORD)(r)<---------------------------------------------------------------*/ + +// ファイルポインター +static FILE *_Fpt; + +// fps指定によるフレーム更新時間 +#define FPS60 (FrameTime/(F(1)/F(60))) + +// CallBack関数型 +#define CLBKH HRESULT CALLBACK +#define CLBKB BOOL CALLBACK +#define CLBKI int CALLBACK + +// インスタンスハンドル +static HINSTANCE _Instance; + +// ミューテックスハンドル +static HANDLE _Mutex=NULL; + +// コマンドラインのパラメーター +static char _CommandLine[256]; + +// ウィンドウ状態フラグ +static BOOL _WindowActive=FALSE; + +// ダイアログ表示状態フラグ +static BOOL _DialogActive=FALSE; + +// フルウィンドウ表示フラグ ( 画面切り換えなし ) +static BOOL _FullWindow=FALSE; + +// スクリーンNo関係 +static int _ScreenNo=0; +static int _CallScreenNo=0; +static int _LastScreenNo=0; +static BOOL _ChangeScreen=FALSE; + +// キーボードカウント処理 +static UINT _PullKey=NULL; +static int _PullCount=0; + +// 前フレーム更新時間 +static ULONG _WaitTime=timeGetTime(); + +// 点滅時間 +static ULONG _BlinkTime=timeGetTime()+1000UL; + +// ループチェック時間 +#ifdef DIRECTMUSIC + +static ULONG _MusicLoopTime=timeGetTime()+1000UL; + +#endif + +// ムービー動作時の描画スキップフラグ +static BOOL DrawSkip=FALSE; + +// ムービー停止フラグ +static BOOL MovieEnd=TRUE; + +// ウィンドウ座標 +static int _WindowX,_WindowY; + +// ウィンドウサイズ +static int _WindowSizeX,_WindowSizeY; + +// ウィンドウ実行フラグ +static int _SetWindow=0x00; + +// フルスクリーン実行フラグ +static BOOL _FullScreen=TRUE; + +// WM_CLOSEイベント発生フラグ +static int _CloseEvent=0; + +// マウスカーソル表示フラグ +static BOOL _ShowMouse=TRUE; + +// マウスカーソル移動範囲設定フラグ +static BOOL _MouseArea=FALSE; + +// ダイアログとメッセージボックスの表示フラグ +static BOOL _ShowDialog=FALSE; + +// MCI文字列バッファ +static char MciBuffer[32]; + +// デバッグファイル削除 +#define DEBUG_CLEAR\ +\ + remove("DEBUG.TXT"); + +// デバッグ情報出力 +inline void DEBUG(char* Format,...) +{ + if ((_Fpt=fopen("DEBUG.TXT","at"))!=NULL) + { + vfprintf(_Fpt,Format,(char*)(&Format+1)); + fprintf(_Fpt,"\n"); + fclose(_Fpt); + } +} + +#ifdef REPORT + + // レポート出力 ( 開始 ) + #define REP_IN\ + \ + if ((_Fpt=fopen("REPORT.TXT","at"))!=NULL)\ + {\ + fprintf(_Fpt, + + // レポート出力 ( 終了 ) + #define REP_OUT\ + \ + );\ + \ + fclose(_Fpt);\ + } + + // レポート用HAL&HELチェック + DDCAPS RepHal,RepHel; + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= 標準関数定義 =*/ +/*= =*/ +/*==============================================================================*/ + +long CALLBACK WindowProc(HWND,UINT,WPARAM,LPARAM); +void KeyboardProc(WPARAM); +void elCreate(void); +BOOL elMutexCheck(char*); + +#ifdef DIRECTSHOW + + void elMovieProc(int); + +#endif + +#ifdef MENU + + void elMenuProc(int); + +#endif + +#ifdef DIALOG + + BOOL elDialogProc(HWND,UINT,WPARAM,LPARAM); + void elDialogCreate(void); + +#endif + +/*---< メイン関数 >-------------------------------------------------------------*/ + +#define elMain_A(Name)\ +\ + WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,\ + LPSTR lpCmdLine,int nCmdShow)\ + {\ + WNDCLASS wc;\ + MSG msg;\ + time_t tm;\ + char AppName[]=Name;\ + int SizeX=0,SizeY=0;\ + POINT pt;\ + \ + if (!elMutexCheck(Name)) return FALSE;\ + \ + strcpy(_CommandLine,lpCmdLine);\ + \ + wc.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;\ + wc.lpfnWndProc=WindowProc;\ + wc.cbClsExtra=0;\ + wc.cbWndExtra=0;\ + wc.hInstance=hInstance;\ + wc.hIcon=LoadIcon(hInstance,"MAIN");\ + wc.hCursor=LoadCursor(NULL,IDC_ARROW);\ + wc.hbrBackground=GetStockBrush(BLACK_BRUSH);\ + wc.lpszMenuName="DEFAULT";\ + wc.lpszClassName="DEFAULT";\ + \ + RegisterClass(&wc); + +#define elMain_B(Name)\ +\ + WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,\ + LPSTR lpCmdLine,int nCmdShow)\ + {\ + WNDCLASS wc;\ + MSG msg;\ + time_t tm;\ + char AppName[]=Name;\ + int SizeX=0,SizeY=0;\ + POINT pt;\ + RECT rc;\ + \ + if (!elMutexCheck(Name)) return FALSE;\ + \ + strcpy(_CommandLine,lpCmdLine);\ + \ + elSaver::Init();\ + \ + if (lpCmdLine[1]=='c' || lpCmdLine[1]=='C' || lpCmdLine[0]==NULL)\ + {\ + elSaver::Config=TRUE;\ + }\ + else\ + {\ + elSaver::Config=FALSE;\ + }\ + \ + if (lpCmdLine[1]=='p' || lpCmdLine[1]=='P')\ + {\ + hprv=GetWindow((HWND)atol(&lpCmdLine[3]),GW_HWNDFIRST);\ + if (!hprv) return FALSE;\ + \ + GetClientRect(hprv,&rc);\ + elSaver::PrevWidth=rc.right-rc.left;\ + elSaver::PrevHeight=rc.bottom-rc.top;\ + \ + elSaver::Preview=TRUE;\ + \ + elSaver::CheckKeyboard(FALSE);\ + elSaver::CheckMouse(FALSE);\ + \ + elSetWindow(RUN_NOTOP|RUN_INACTIVE);\ + \ + _FullScreen=FALSE;\ + _FullWindow=FALSE;\ + }\ + \ + wc.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;\ + wc.lpfnWndProc=WindowProc;\ + wc.cbClsExtra=0;\ + wc.cbWndExtra=0;\ + wc.hInstance=hInstance;\ + wc.hIcon=LoadIcon(hInstance,"MAIN");\ + wc.hCursor=LoadCursor(NULL,IDC_ARROW);\ + wc.hbrBackground=GetStockBrush(BLACK_BRUSH);\ + wc.lpszMenuName="DEFAULT";\ + wc.lpszClassName="DEFAULT";\ + \ + RegisterClass(&wc); + +#define elMain_C(Name)\ +\ + WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,\ + LPSTR lpCmdLine,int nCmdShow)\ + {\ + WNDCLASS wc;\ + MSG msg;\ + time_t tm;\ + char AppName[]=Name;\ + int SizeX=0,SizeY=0;\ + POINT pt;\ + RECT rc;\ + \ + if (!elMutexCheck(Name)) return FALSE;\ + \ + strcpy(_CommandLine,lpCmdLine);\ + \ + elSaver::Init();\ + \ + if (lpCmdLine[1]=='c' || lpCmdLine[1]=='C' || lpCmdLine[0]==NULL)\ + {\ + MessageBox(NULL,"設定できるオプションはありません",\ + Name,MB_OK|MB_ICONEXCLAMATION);\ + \ + return FALSE;\ + }\ + \ + if (lpCmdLine[1]=='p' || lpCmdLine[1]=='P')\ + {\ + hprv=GetWindow((HWND)atol(&lpCmdLine[3]),GW_HWNDFIRST);\ + if (!hprv) return FALSE;\ + \ + GetClientRect(hprv,&rc);\ + elSaver::PrevWidth=rc.right-rc.left;\ + elSaver::PrevHeight=rc.bottom-rc.top;\ + \ + elSaver::Preview=TRUE;\ + \ + elSaver::CheckKeyboard(FALSE);\ + elSaver::CheckMouse(FALSE);\ + \ + elSetWindow(RUN_NOTOP|RUN_INACTIVE);\ + \ + _FullScreen=FALSE;\ + _FullWindow=FALSE;\ + }\ + \ + wc.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;\ + wc.lpfnWndProc=WindowProc;\ + wc.cbClsExtra=0;\ + wc.cbWndExtra=0;\ + wc.hInstance=hInstance;\ + wc.hIcon=LoadIcon(hInstance,"MAIN");\ + wc.hCursor=LoadCursor(NULL,IDC_ARROW);\ + wc.hbrBackground=GetStockBrush(BLACK_BRUSH);\ + wc.lpszMenuName="DEFAULT";\ + wc.lpszClassName="DEFAULT";\ + \ + RegisterClass(&wc); + +#ifndef SAVER + + #define elMain(Name)\ + \ + elMain_A(Name) + +#else + + #ifndef SAVER_NO_CONFIG + + #define elMain(Name)\ + \ + elMain_B(Name) + + #else + + #define elMain(Name)\ + \ + elMain_C(Name) + + #endif + +#endif + +/*---< ウィンドウ実行関数 >-----------------------------------------------------*/ + +#define FULL_WIN -1 + +#define elWindow(x,y,f)\ +\ + _FullScreen=FALSE;\ + _FullWindow=FALSE;\ + \ + if (x==FULL_WIN)\ + {\ + if (elSystem::ColorBit()>=16)\ + {\ + HDC hdc;\ + \ + hdc=GetDC(hwnd);\ + \ + SizeX=GetDeviceCaps(hdc,HORZRES);\ + SizeY=GetDeviceCaps(hdc,VERTRES);\ + \ + ReleaseDC(hwnd,hdc);\ + \ + _FullWindow=TRUE;\ + }\ + else\ + {\ + SizeX=640;\ + SizeY=480;\ + \ + _FullScreen=TRUE;\ + }\ + }\ + else\ + {\ + SizeX=x;\ + SizeY=y;\ + }\ + \ + _WindowSizeX=SizeX;\ + _WindowSizeY=SizeY;\ + \ + _MouseArea=f + +/*---< ウィンドウ設定 >---------------------------------------------------------*/ + +#define RUN_NOTOP 0x01 // 他のウィンドウが上に重なることを許可 +#define RUN_INACTIVE 0x02 // アクティブになっていなくても実行 +#define RUN_HIDE 0x04 // ウィンドウを隠して、アイコン化の状態で実行 +#define RUN_LOWVRAM 0x08 // 少ないVRAM環境を考慮し、システムメモリを使用 + +#define elSetWindow(m)\ +\ + _SetWindow=m; + +/*---< el3DクラスのHEL使用 >----------------------------------------------------*/ + +#define elHel3D()\ +\ + el3D::HEL=TRUE + +/*---< el3Dクラス設定 >---------------------------------------------------------*/ + +#define TEXTURE_QUALITY 0x0001 // テクスチャーを滑らかに設定 +#define DRAW_BACKLAYER 0x0002 // 裏画面に直接描画 + +#define elSet3D(m)\ +\ + el3D::Mode=m; + +/*---< プログラム二重起動チェック >---------------------------------------------*/ + +BOOL elMutexCheck(char* Name) +{ + #ifndef MUTEX_OFF + + // 名称の設定 + strcpy(Buffer,Name); + strcat(Buffer,":ElMutex"); + + // ミューテックスの生成 + _Mutex=CreateMutex(NULL,TRUE,Buffer); + + // すでに存在している場合 + if (GetLastError()==ERROR_ALREADY_EXISTS) + { + // そのウィンドウをアクティブ化 + SetForegroundWindow(FindWindow("DEFAULT",Name)); + + return FALSE; + } + + #endif + + return TRUE; +} + +/*---< メッセージループ関数 >---------------------------------------------------*/ + +#define elLoop_A\ +\ + if (_FullScreen || _FullWindow)\ + {\ + hwnd=CreateWindowEx(0,"DEFAULT",AppName,WS_POPUP|WS_SYSMENU,0,0,\ + GetSystemMetrics(SM_CXSCREEN),\ + GetSystemMetrics(SM_CYSCREEN),\ + NULL,NULL,hInstance,NULL);\ + }\ + else\ + {\ + hwnd=CreateWindowEx(0,"DEFAULT",AppName,\ + WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,\ + (GetSystemMetrics(SM_CXSCREEN)-\ + (SizeX+GetSystemMetrics(SM_CXBORDER)+\ + GetSystemMetrics(SM_CXEDGE)+\ + GetSystemMetrics(SM_CXDLGFRAME)))/2,\ + (GetSystemMetrics(SM_CYSCREEN)-\ + (SizeY+GetSystemMetrics(SM_CYCAPTION)+\ + GetSystemMetrics(SM_CYEDGE)+\ + GetSystemMetrics(SM_CYBORDER)+\ + GetSystemMetrics(SM_CYDLGFRAME)))/2,\ + SizeX+GetSystemMetrics(SM_CXBORDER)+\ + GetSystemMetrics(SM_CXEDGE)+\ + GetSystemMetrics(SM_CXDLGFRAME),\ + SizeY+GetSystemMetrics(SM_CYCAPTION)+\ + GetSystemMetrics(SM_CYEDGE)+\ + GetSystemMetrics(SM_CYBORDER)+\ + GetSystemMetrics(SM_CYDLGFRAME),\ + NULL,NULL,hInstance,NULL);\ + } + +#define elLoop_B\ +\ + if ((_FullScreen || _FullWindow) && !elSaver::Preview)\ + {\ + hwnd=CreateWindowEx(0,"DEFAULT",AppName,WS_POPUP|WS_SYSMENU,0,0,\ + GetSystemMetrics(SM_CXSCREEN),\ + GetSystemMetrics(SM_CYSCREEN),\ + NULL,NULL,hInstance,NULL);\ + }\ + else\ + {\ + if (elSaver::Preview)\ + {\ + hwnd=CreateWindowEx(0,"DEFAULT",AppName,WS_CHILD,0,0,\ + elSaver::PrevWidth,elSaver::PrevWidth,\ + hprv,NULL,hInstance,NULL);\ + \ + elSaver::CheckKeyboard(FALSE);\ + elSaver::CheckMouse(FALSE);\ + \ + elSetWindow(RUN_NOTOP|RUN_INACTIVE);\ + \ + _FullScreen=FALSE;\ + _FullWindow=FALSE;\ + }\ + else\ + {\ + hwnd=CreateWindowEx(0,"DEFAULT",AppName,\ + WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,\ + (GetSystemMetrics(SM_CXSCREEN)-\ + (SizeX+GetSystemMetrics(SM_CXBORDER)+\ + GetSystemMetrics(SM_CXEDGE)+\ + GetSystemMetrics(SM_CXDLGFRAME)))/2,\ + (GetSystemMetrics(SM_CYSCREEN)-\ + (SizeY+GetSystemMetrics(SM_CYCAPTION)+\ + GetSystemMetrics(SM_CYEDGE)+\ + GetSystemMetrics(SM_CYBORDER)+\ + GetSystemMetrics(SM_CYDLGFRAME)))/2,\ + SizeX+GetSystemMetrics(SM_CXBORDER)+\ + GetSystemMetrics(SM_CXEDGE)+\ + GetSystemMetrics(SM_CXDLGFRAME),\ + SizeY+GetSystemMetrics(SM_CYCAPTION)+\ + GetSystemMetrics(SM_CYEDGE)+\ + GetSystemMetrics(SM_CYBORDER)+\ + GetSystemMetrics(SM_CYDLGFRAME),\ + NULL,NULL,hInstance,NULL);\ + }\ + } + +#define elLoop_C\ +\ + if (!hwnd) return FALSE;\ + \ + if (_SetWindow&RUN_HIDE)\ + {\ + ShowWindow(hwnd,SW_HIDE);\ + }\ + else\ + {\ + ShowWindow(hwnd,nCmdShow);\ + }\ + \ + UpdateWindow(hwnd);\ + \ + if (!_FullScreen)\ + {\ + if (_SetWindow&RUN_NOTOP)\ + {\ + SetWindowPos(hwnd,hwnd,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);\ + }\ + else\ + {\ + SetWindowPos(hwnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);\ + }\ + }\ + \ + _Instance=hInstance;\ + \ + srand((unsigned)time(&tm));\ + \ + elSystem::IME(FALSE);\ + \ + elCreate();\ + \ + elSystem::InitFrame();\ + elSystem::InitMouse(FALSE);\ + \ + while (TRUE)\ + {\ + if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))\ + {\ + if (msg.message==WM_QUIT) break;\ + \ + if (!_DialogActive)\ + {\ + TranslateMessage(&msg);\ + DispatchMessage(&msg);\ + }\ + else\ + {\ + if (_WindowActive)\ + {\ + DestroyWindow(hdlg);\ + }\ + \ + if (!IsDialogMessage(hdlg,&msg))\ + {\ + TranslateMessage(&msg);\ + DispatchMessage(&msg);\ + }\ + else\ + {\ + if (!_ShowMouse)\ + {\ + ShowCursor(TRUE);\ + \ + _ShowMouse=TRUE;\ + }\ + }\ + }\ + }\ + else\ + {\ + if (_WindowActive ||\ + !_WindowActive && _SetWindow&RUN_INACTIVE)\ + {\ + FrameTime=F(timeGetTime()-_WaitTime)/F(1000);\ + _WaitTime=timeGetTime();\ + \ + MouseMX=MousePX-MouseLX;\ + MouseMY=MousePY-MouseLY;\ + \ + if (_LastScreenNo==0 && _ScreenNo!=0)\ + {\ + _ChangeScreen=TRUE;\ + _LastScreenNo=_ScreenNo;\ + } + +#define elLoop_D\ +\ + if (MovieEnd)\ + {\ + elMovieProc(MV_END);\ + MovieEnd=FALSE;\ + } + +#define elLoop_E\ +\ + if (!DrawSkip)\ + {\ + if (elDraw::FadeAdd!=1)\ + { + +#define elLoop_F\ +\ + if (!DrawSkip)\ + {\ + if (elDraw::FadeAdd!=1)\ + {\ + if (elSaver::Preview)\ + {\ + GetWindowRect(hprv,&rc);\ + _WindowX=rc.left;\ + _WindowY=rc.top;\ + } + +#define elLoop_G\ +\ + elSystem::NowTime=timeGetTime();\ + \ + switch (_ScreenNo)\ + { + +#define elLoop_H\ +\ + elSystem::GetInputDevice();\ + elSystem::NowTime=timeGetTime();\ + \ + switch (_ScreenNo)\ + { + +#if defined(SAVER) || defined(SAVER_NO_CONFIG) + + #ifndef DIRECTINPUT + + #ifndef DIRECTSHOW + + #define elLoop()\ + \ + elLoop_B\ + elLoop_C\ + elLoop_F\ + elLoop_G + + #else + + #define elLoop()\ + \ + elLoop_B\ + elLoop_C\ + elLoop_D\ + elLoop_F\ + elLoop_G + + #endif + + #else + + #ifndef DIRECTSHOW + + #define elLoop()\ + \ + elLoop_C\ + elLoop_B\ + elLoop_F\ + elLoop_H + + #else + + #define elLoop()\ + \ + elLoop_B\ + elLoop_C\ + elLoop_D\ + elLoop_F\ + elLoop_H + + #endif + + #endif + +#else + + #ifndef DIRECTINPUT + + #ifndef DIRECTSHOW + + #define elLoop()\ + \ + elLoop_A\ + elLoop_C\ + elLoop_E\ + elLoop_G + + #else + + #define elLoop()\ + \ + elLoop_A\ + elLoop_C\ + elLoop_D\ + elLoop_E\ + elLoop_G + + #endif + + #else + + #ifndef DIRECTSHOW + + #define elLoop()\ + \ + elLoop_A\ + elLoop_C\ + elLoop_E\ + elLoop_H + + #else + + #define elLoop()\ + \ + elLoop_A\ + elLoop_C\ + elLoop_D\ + elLoop_E\ + elLoop_H + + #endif + + #endif + +#endif + +/*---< メイン関数の終了 >-------------------------------------------------------*/ + +#define elExitMain_A\ +\ + }\ + }\ + else\ + {\ + elDraw::Refresh();\ + \ + if (!elDraw::FadeAdd) _ScreenNo=_CallScreenNo;\ + }\ + } + +#define elExitMain_B\ +\ + else\ + {\ + elMovieProc(MV_READY);\ + } + +#define elExitMain_C\ +\ + if (elMusic::PlayMusic && !elMusic::LoopMode)\ + {\ + if (timeGetTime()>=_MusicLoopTime)\ + {\ + if (DMPerformance->IsPlaying(DMSegment,DMState)!=S_OK)\ + {\ + elMusic::Stop();\ + elMusic::LoopMusic=TRUE;\ + }\ + \ + _MusicLoopTime=timeGetTime()+1000UL;\ + }\ + } + +#define elExitMain_D\ +\ + if (_ScreenNo!=_LastScreenNo)\ + {\ + _ChangeScreen=TRUE;\ + \ + if (elDraw::EffectOn>0)\ + {\ + elDraw::Vx1=elDraw::Wx1;\ + elDraw::Vy1=elDraw::Wy1;\ + elDraw::Vx2=elDraw::Wx2;\ + elDraw::Vy2=elDraw::Wy2;\ + elDraw::EffectOn=0;\ + }\ + }\ + else\ + {\ + _ChangeScreen=FALSE;\ + }\ + \ + _LastScreenNo=_ScreenNo;\ + \ + if (timeGetTime()>=_BlinkTime)\ + {\ + Blink=!Blink;\ + _BlinkTime=timeGetTime()+(ULONG)(1000-(Blink==0)*800);\ + }\ + \ + MouseLX=MousePX;\ + MouseLY=MousePY;\ + \ + MouseMX=MousePX;\ + MouseMY=MousePY;\ + \ + MouseCL=FALSE;\ + MouseCR=FALSE;\ + \ + MouseDL=FALSE;\ + MouseDR=FALSE;\ + \ + if (!_FullScreen && !_ShowDialog)\ + {\ + GetCursorPos(&pt);\ + \ + if (pt.x<_WindowX || pt.y<_WindowY ||\ + pt.x>=_WindowX+SizeX || pt.y>=_WindowY+SizeY)\ + {\ + if (!_ShowMouse)\ + {\ + ShowCursor(TRUE);\ + \ + _ShowMouse=TRUE;\ + }\ + } + +#define elExitMain_E\ +\ + else\ + {\ + if (_ShowMouse)\ + {\ + ShowCursor(FALSE);\ + \ + _ShowMouse=FALSE;\ + }\ + }\ + }\ + }\ + else\ + {\ + WaitMessage();\ + }\ + }\ + }\ +} + +#define elExitMain_F\ +\ + else\ + {\ + if (!elSaver::Preview)\ + {\ + if (_ShowMouse)\ + {\ + ShowCursor(FALSE);\ + \ + _ShowMouse=FALSE;\ + }\ + }\ + }\ + }\ + }\ + else\ + {\ + WaitMessage();\ + }\ + }\ + }\ +} + +#if defined(SAVER) || defined(SAVER_NO_CONFIG) + + #ifdef DIRECTMUSIC + + #ifndef DIRECTSHOW + + #define elExitMain()\ + \ + elExitMain_A\ + elExitMain_C\ + elExitMain_D\ + elExitMain_F\ + \ + return 0; + + #define elExitMain2()\ + \ + elExitMain_A\ + elExitMain_C\ + elExitMain_D\ + elExitMain_F + + #else + + #define elExitMain()\ + \ + elExitMain_A\ + elExitMain_B\ + elExitMain_C\ + elExitMain_D\ + elExitMain_F\ + \ + return 0; + + #define elExitMain2()\ + \ + elExitMain_A\ + elExitMain_B\ + elExitMain_C\ + elExitMain_D\ + elExitMain_F + + #endif + + #else + + #ifndef DIRECTSHOW + + #define elExitMain()\ + \ + elExitMain_A\ + elExitMain_D\ + elExitMain_F\ + \ + return 0; + + #define elExitMain2()\ + \ + elExitMain_A\ + elExitMain_D\ + elExitMain_F + + #else + + #define elExitMain()\ + \ + elExitMain_A\ + elExitMain_B\ + elExitMain_D\ + elExitMain_F\ + \ + return 0; + + #define elExitMain2()\ + \ + elExitMain_A\ + elExitMain_B\ + elExitMain_D\ + elExitMain_F + + #endif + + #endif + +#else + + #ifdef DIRECTMUSIC + + #ifndef DIRECTSHOW + + #define elExitMain()\ + \ + elExitMain_A\ + elExitMain_C\ + elExitMain_D\ + elExitMain_E\ + \ + return 0; + + #define elExitMain2()\ + \ + elExitMain_A\ + elExitMain_C\ + elExitMain_D\ + elExitMain_E + + #else + + #define elExitMain()\ + \ + elExitMain_A\ + elExitMain_B\ + elExitMain_C\ + elExitMain_D\ + elExitMain_E\ + \ + return 0; + + #define elExitMain2()\ + \ + elExitMain_A\ + elExitMain_B\ + elExitMain_C\ + elExitMain_D\ + elExitMain_E + + #endif + + #else + + #ifndef DIRECTSHOW + + #define elExitMain()\ + \ + elExitMain_A\ + elExitMain_D\ + elExitMain_E\ + \ + return 0; + + #define elExitMain2()\ + \ + elExitMain_A\ + elExitMain_D\ + elExitMain_E + + #else + + #define elExitMain()\ + \ + elExitMain_A\ + elExitMain_B\ + elExitMain_D\ + elExitMain_E\ + \ + return 0; + + #define elExitMain2()\ + \ + elExitMain_A\ + elExitMain_B\ + elExitMain_D\ + elExitMain_E + + #endif + + #endif + +#endif + +/*---< キーボード関数 >---------------------------------------------------------*/ + +#ifndef USE_PRINTSCREEN + + #define elKeyboard(void)\ + \ + KeyboardProc(WPARAM wParam)\ + {\ + if (!elDraw::HelpOn)\ + {\ + PushKey=wParam;\ + LastKey=wParam;\ + }\ + else\ + {\ + HelpKey=wParam;\ + }\ + \ + switch (wParam)\ + { + +#else + + #define elKeyboard(void)\ + \ + KeyboardProc(WPARAM wParam)\ + {\ + if (wParam!=VK_SNAPSHOT && wParam!=VK_SNAPSHOT_WINDOW)\ + {\ + if (!elDraw::HelpOn)\ + {\ + PushKey=wParam;\ + LastKey=wParam;\ + }\ + else\ + {\ + HelpKey=wParam;\ + }\ + }\ + \ + switch (wParam)\ + { + +#endif + +/*---< キーボード関数の終了 >---------------------------------------------------*/ + +#define elExitKeyboard()\ +\ + case 0:\ + break;\ + }\ + } + +/*---< イベント関数 >-----------------------------------------------------------*/ +#define elEvent_A\ +\ + CALLBACK WindowProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)\ + {\ + switch (msg)\ + {\ + case WM_MOUSEMOVE:\ + {\ + MousePX=LOWORD(lParam);\ + MousePY=HIWORD(lParam);\ + \ + break;\ + }\ + \ + case WM_LBUTTONDOWN:\ + {\ + if (!elSystem::KeyboardLock)\ + {\ + MousePL=TRUE;\ + MouseCL=TRUE;\ + MouseLL=TRUE;\ + MousePush=VK_LBUTTON;\ + MouseLast=VK_LBUTTON;\ + }\ + else\ + {\ + MouseMenu=TRUE;\ + }\ + \ + break;\ + }\ + \ + case WM_RBUTTONDOWN:\ + {\ + if (!elSystem::KeyboardLock)\ + {\ + MousePR=TRUE;\ + MouseCR=TRUE;\ + MouseLR=TRUE;\ + MousePush=VK_RBUTTON;\ + MouseLast=VK_RBUTTON;\ + }\ + \ + break;\ + }\ + \ + case WM_LBUTTONUP:\ + {\ + MousePL=FALSE;\ + if (MousePush==VK_LBUTTON) MousePush=NULL;\ + MouseMenu=FALSE;\ + \ + break;\ + }\ + \ + case WM_RBUTTONUP:\ + {\ + MousePR=FALSE;\ + if (MousePush==VK_RBUTTON) MousePush=NULL;\ + \ + break;\ + }\ + \ + case WM_LBUTTONDBLCLK:\ + {\ + if (!elSystem::KeyboardLock)\ + {\ + MouseDL=TRUE;\ + }\ + \ + return 0L;\ + }\ + \ + case WM_RBUTTONDBLCLK:\ + {\ + if (!elSystem::KeyboardLock)\ + {\ + MouseDR=TRUE;\ + }\ + \ + if (_MouseArea)\ + {\ + if (elSystem::GetMouseArea())\ + {\ + elSystem::ClearMouseArea();\ + }\ + else\ + {\ + elSystem::WindowMouseArea();\ + }\ + }\ + \ + return 0L;\ + }\ + \ + case WM_KEYDOWN:\ + {\ + if (!elSystem::KeyboardLock)\ + {\ + KeyboardProc(wParam);\ + }\ + else\ + {\ + MenuKey=wParam;\ + }\ + \ + break;\ + }\ + \ + case WM_KEYUP:\ + {\ + if (wParam==PushKey) PushKey=NULL;\ + if (wParam==HelpKey) HelpKey=NULL;\ + if (wParam==MenuKey) MenuKey=NULL;\ + if (wParam==VK_SHIFT) PushShift=!PushShift;\ + if (wParam==_PullKey) _PullCount++;\ + \ + break;\ + }\ + \ + case WM_MOVE:\ + {\ + _WindowX=(int)LOWORD(lParam);\ + _WindowY=(int)HIWORD(lParam);\ + \ + if (_WindowX>32768) _WindowX-=65536;\ + if (_WindowY>32768) _WindowY-=65536;\ + \ + elDraw::RefreshPos.left=_WindowX;\ + elDraw::RefreshPos.top=_WindowY;\ + elDraw::RefreshPos.right=_WindowX+elDraw::Width;\ + elDraw::RefreshPos.bottom=_WindowY+elDraw::Height;\ + \ + if (_MouseArea)\ + {\ + elSystem::WindowMouseArea();\ + }\ + \ + break;\ + }\ + \ + case WM_ACTIVATEAPP:\ + {\ + if (!wParam)\ + {\ + ChangeActive(FALSE);\ + \ + if (!_ShowMouse)\ + {\ + ShowCursor(TRUE);\ + \ + _ShowMouse=TRUE;\ + }\ + \ + if (_MouseArea) elSystem::ClearMouseArea();\ + }\ + else\ + {\ + if (!_DialogActive)\ + {\ + ChangeActive(TRUE);\ + \ + elSystem::InitFrame();\ + \ + if (_MouseArea) elSystem::WindowMouseArea();\ + \ + elSystem::InitMouse(TRUE);\ + }\ + }\ + \ + return 0L;\ + }\ + \ + case WM_SETCURSOR:\ + {\ + if (_FullScreen && !_ShowDialog)\ + {\ + SetCursor(NULL);\ + \ + return TRUE;\ + }\ + \ + break;\ + }\ + \ + case WM_SYSKEYDOWN:\ + {\ + if (!elSystem::SystemKeyCheck) return 0L;\ + if (elSystem::SystemKeyCheck==2 && wParam==VK_MENU) return 0L;\ + \ + if (!elSystem::KeyboardLock)\ + {\ + KeyboardProc(wParam);\ + }\ + else\ + {\ + MenuKey=wParam;\ + }\ + \ + break;\ + }\ + \ + case WM_SYSCOMMAND:\ + {\ + if (wParam&0xFFF0==SC_SCREENSAVE) return 0L;\ + \ + break;\ + }\ + \ + case WM_HOTKEY:\ + {\ + if (!elSystem::KeyboardLock)\ + {\ + if ((int)wParam==0xBF01)\ + {\ + KeyboardProc(VK_SNAPSHOT);\ + }\ + else if ((int)wParam==0xBF02)\ + {\ + KeyboardProc(VK_SNAPSHOT_WINDOW);\ + }\ + }\ + \ + return 0L;\ + } + +#define elEvent_B\ +\ + CALLBACK WindowProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)\ + {\ + switch (msg)\ + {\ + case WM_MOUSEMOVE:\ + {\ + if (elSaver::CheckMouseFlag)\ + {\ + if (MousePX!=LOWORD(lParam) && MousePY!=HIWORD(lParam))\ + {\ + if (++elSaver::MouseMoveCount>=3) elDraw::Exit();\ + }\ + }\ + \ + MousePX=LOWORD(lParam);\ + MousePY=HIWORD(lParam);\ + \ + break;\ + }\ + \ + case WM_LBUTTONDOWN:\ + {\ + if (elSaver::CheckMouseFlag) elDraw::Exit();\ + \ + if (!elSystem::KeyboardLock)\ + {\ + MousePL=TRUE;\ + MouseCL=TRUE;\ + MouseLL=TRUE;\ + MousePush=VK_LBUTTON;\ + MouseLast=VK_LBUTTON;\ + }\ + else\ + {\ + MouseMenu=TRUE;\ + }\ + \ + break;\ + }\ + \ + case WM_RBUTTONDOWN:\ + {\ + if (elSaver::CheckMouseFlag) elDraw::Exit();\ + \ + if (!elSystem::KeyboardLock)\ + {\ + MousePR=TRUE;\ + MouseCR=TRUE;\ + MouseLR=TRUE;\ + MousePush=VK_RBUTTON;\ + MouseLast=VK_RBUTTON;\ + }\ + \ + break;\ + }\ + \ + case WM_LBUTTONUP:\ + {\ + MousePL=FALSE;\ + if (MousePush==VK_LBUTTON) MousePush=NULL;\ + MouseMenu=FALSE;\ + \ + break;\ + }\ + \ + case WM_RBUTTONUP:\ + {\ + MousePR=FALSE;\ + if (MousePush==VK_RBUTTON) MousePush=NULL;\ + \ + break;\ + }\ + \ + case WM_LBUTTONDBLCLK:\ + {\ + if (!elSystem::KeyboardLock)\ + {\ + MouseDL=TRUE;\ + }\ + \ + return 0L;\ + }\ + \ + case WM_RBUTTONDBLCLK:\ + {\ + if (!elSystem::KeyboardLock)\ + {\ + MouseDR=TRUE;\ + }\ + \ + if (_MouseArea)\ + {\ + if (elSystem::GetMouseArea())\ + {\ + elSystem::ClearMouseArea();\ + }\ + else\ + {\ + elSystem::WindowMouseArea();\ + }\ + }\ + \ + return 0L;\ + }\ + \ + case WM_KEYDOWN:\ + {\ + if (elSaver::CheckKeyboardFlag) elDraw::Exit();\ + \ + if (!elSystem::KeyboardLock)\ + {\ + KeyboardProc(wParam);\ + }\ + else\ + {\ + MenuKey=wParam;\ + }\ + \ + break;\ + }\ + \ + case WM_KEYUP:\ + {\ + if (wParam==PushKey) PushKey=NULL;\ + if (wParam==HelpKey) HelpKey=NULL;\ + if (wParam==MenuKey) MenuKey=NULL;\ + if (wParam==VK_SHIFT) PushShift=!PushShift;\ + if (wParam==_PullKey) _PullCount++;\ + \ + break;\ + }\ + \ + case WM_MOVE:\ + {\ + _WindowX=(int)LOWORD(lParam);\ + _WindowY=(int)HIWORD(lParam);\ + \ + if (_WindowX>32768) _WindowX-=65536;\ + if (_WindowY>32768) _WindowY-=65536;\ + \ + elDraw::RefreshPos.left=_WindowX;\ + elDraw::RefreshPos.top=_WindowY;\ + elDraw::RefreshPos.right=_WindowX+elDraw::Width;\ + elDraw::RefreshPos.bottom=_WindowY+elDraw::Height;\ + \ + if (_MouseArea)\ + {\ + elSystem::WindowMouseArea();\ + }\ + \ + break;\ + }\ + \ + case WM_ACTIVATEAPP:\ + {\ + if (!wParam)\ + {\ + ChangeActive(FALSE);\ + \ + if (!_ShowMouse)\ + {\ + ShowCursor(TRUE);\ + \ + _ShowMouse=TRUE;\ + }\ + \ + if (_MouseArea) elSystem::ClearMouseArea();\ + }\ + else\ + {\ + if (!_DialogActive)\ + {\ + ChangeActive(TRUE);\ + \ + elSystem::InitFrame();\ + \ + if (_MouseArea) elSystem::WindowMouseArea();\ + \ + elSystem::InitMouse(TRUE);\ + }\ + }\ + \ + return 0L;\ + }\ + \ + case WM_SETCURSOR:\ + {\ + if (_FullScreen && !_ShowDialog)\ + {\ + SetCursor(NULL);\ + \ + return TRUE;\ + }\ + \ + break;\ + }\ + \ + case WM_SYSKEYDOWN:\ + {\ + if (elSaver::CheckKeyboardFlag) elDraw::Exit();\ + \ + if (!elSystem::KeyboardLock)\ + {\ + KeyboardProc(wParam);\ + }\ + else\ + {\ + MenuKey=wParam;\ + }\ + \ + break;\ + }\ + \ + case WM_SYSCOMMAND:\ + {\ + if (wParam&0xFFF0==SC_SCREENSAVE) return 0L;\ + \ + break;\ + }\ + \ + case WM_HOTKEY:\ + {\ + if (elSaver::CheckKeyboardFlag) elDraw::Exit();\ + \ + if (!elSystem::KeyboardLock)\ + {\ + if ((int)wParam==0xBF01)\ + {\ + KeyboardProc(VK_SNAPSHOT);\ + }\ + else if ((int)wParam==0xBF02)\ + {\ + KeyboardProc(VK_SNAPSHOT_WINDOW);\ + }\ + }\ + \ + return 0L;\ + } + +#define elEvent_C\ +\ + case MM_MCINOTIFY:\ + {\ + if (wParam==MCI_NOTIFY_SUCCESSFUL)\ + {\ + if (elMusic::PlayMusic)\ + {\ + mciSendString("status midi mode",MciBuffer,32,NULL);\ + \ + if (MciBuffer[0]=='s' && MciBuffer[1]=='t')\ + {\ + elMusic::Replay();\ + }\ + }\ + }\ + \ + break;\ + } + +#define elEvent_D\ +\ + case MM_MCINOTIFY:\ + {\ + if (wParam==MCI_NOTIFY_SUCCESSFUL)\ + {\ + if (elMusic::PlayMusic)\ + {\ + mciSendString("status midi mode",MciBuffer,32,NULL);\ + \ + if (MciBuffer[0]=='s' && MciBuffer[1]=='t')\ + {\ + elMusic::Replay();\ + }\ + }\ + \ + if (elCD::PlayCD)\ + {\ + mciSendString("status cdaudio mode",MciBuffer,32,NULL);\ + \ + if (MciBuffer[0]=='s' && MciBuffer[1]=='t')\ + {\ + elCD::Replay();\ + }\ + }\ + }\ + \ + break;\ + } + +#define elEvent_E\ +\ + case WM_CLOSE:\ + {\ + if (!_CloseEvent) _CloseEvent=1;\ + \ + if (_CloseEvent<2) elDraw::Exit();\ + \ + DestroyWindow(hwnd);\ + \ + return 0L;\ + } + +#define elEvent_F\ +\ + case WM_CLOSE:\ + {\ + if (elMovie::MovieStart) return 0L;\ + \ + if (!_CloseEvent) _CloseEvent=1;\ + \ + if (_CloseEvent<2) elDraw::Exit();\ + \ + DestroyWindow(hwnd);\ + \ + return 0L;\ + } + +#ifndef WM_CLOSE_EVENT + + #ifndef SAVER + + #ifndef CDDA + + #ifndef DIRECTSHOW + + #define elEvent(void)\ + \ + elEvent_A\ + elEvent_C\ + elEvent_E + + #else + + #define elEvent(void)\ + \ + elEvent_A\ + elEvent_C\ + elEvent_F + + #endif + + #else + + #ifndef DIRECTSHOW + + #define elEvent(void)\ + \ + elEvent_A\ + elEvent_D\ + elEvent_E + + #else + + #define elEvent(void)\ + \ + elEvent_A\ + elEvent_D\ + elEvent_F + + #endif + + #endif + + #else + + #ifndef CDDA + + #ifndef DIRECTSHOW + + #define elEvent(void)\ + \ + elEvent_B\ + elEvent_C\ + elEvent_E + + #else + + #define elEvent(void)\ + \ + elEvent_B\ + elEvent_C\ + elEvent_F + + #endif + + #else + + #ifndef DIRECTSHOW + + #define elEvent(void)\ + \ + elEvent_B\ + elEvent_D\ + elEvent_E + + #else + + #define elEvent(void)\ + \ + elEvent_B\ + elEvent_D\ + elEvent_F + + #endif + + #endif + + #endif + +#else + + #ifndef SAVER + + #ifndef CDDA + + #ifndef DIRECTSHOW + + #define elEvent(void)\ + \ + elEvent_A\ + elEvent_C + + #else + + #define elEvent(void)\ + \ + elEvent_A\ + elEvent_C + + #endif + + #else + + #ifndef DIRECTSHOW + + #define elEvent(void)\ + \ + elEvent_A\ + elEvent_D + + #else + + #define elEvent(void)\ + \ + elEvent_A\ + elEvent_D + + #endif + + #endif + + #else + + #ifndef CDDA + + #ifndef DIRECTSHOW + + #define elEvent(void)\ + \ + elEvent_B\ + elEvent_C + + #else + + #define elEvent(void)\ + \ + elEvent_B\ + elEvent_C + + #endif + + #else + + #ifndef DIRECTSHOW + + #define elEvent(void)\ + \ + elEvent_B\ + elEvent_D + + #else + + #define elEvent(void)\ + \ + elEvent_B\ + elEvent_D + + #endif + + #endif + + #endif + +#endif + +/*---< イベント関数の終了 >-----------------------------------------------------*/ + +#define elExitEvent()\ +\ + }\ + \ + default:\ + {\ + if (msg==WM_DESTROY)\ + {\ + PostQuitMessage(0);\ + \ + return 0L;\ + }\ + }\ + }\ + \ + return DefWindowProc(hwnd,msg,wParam,lParam); + +#ifdef DIRECTSHOW + +/*---< ムービーイベント関数 >---------------------------------------------------*/ + +#define elMovieEvent(void)\ +\ + elMovieProc(int Mode)\ + {\ + switch (Mode)\ + { + +/*---< ムービーイベント関数の終了 >---------------------------------------------*/ + +#define elExitMovieEvent()\ +\ + }\ + } + +#endif + +#ifdef MENU + +/*---< メニューイベント関数 >---------------------------------------------------*/ + +#define elMenuEvent(void)\ +\ + elMenuProc(int No)\ + {\ + switch (No)\ + { + +/*---< メニューイベント関数の終了 >---------------------------------------------*/ + +#define elExitMenuEvent()\ +\ + }\ + } + +#endif + +/*---< デフォルトのセーバーイベント処理 >---------------------------------------*/ + +#define elDefSaver(x,y,s)\ +\ + void elCreate(void)\ + {\ + if (!elDraw::Screen(x,y))\ + {\ + PostMessage(hwnd,WM_CLOSE,0,0);\ + \ + elCallScreen(-999);\ + }\ + else\ + {\ + elCallScreen(s);\ + }\ + }\ + \ + void elKeyboard(void)\ + {\ + elExitKeyboard();\ + }\ + \ + long elEvent(void)\ + {\ + elExitEvent();\ + } + +#ifdef DIALOG + +/*---< ダイアログイベント関数 >-------------------------------------------------*/ + +#define elDialogEvent(void)\ +\ + elDialogProc(HWND hdlg,UINT msg,WPARAM wParam,LPARAM lParam)\ + {\ + switch (msg)\ + {\ + case WM_INITDIALOG:\ + {\ + return TRUE;\ + }\ + \ + case WM_COMMAND:\ + {\ + switch (HIWORD(wParam))\ + { + +/*---< ダイアログイベント関数の終了 >-------------------------------------------*/ + +#define elExitDialogEvent_A\ +\ + }\ + }\ + \ + break;\ + }\ + \ + case WM_CLOSE:\ + {\ + elDialog::Hide();\ + \ + return TRUE;\ + }\ + \ + case WM_NCDESTROY:\ + {\ + _DialogActive=FALSE;\ + \ + return TRUE;\ + }\ + }\ + \ + return FALSE; + +#define elExitDialogEvent_B\ +\ + }\ + }\ + \ + break;\ + }\ + \ + case WM_TIMER:\ + {\ + if (!elNetwork::PlayerOut)\ + {\ + if (elNetwork::Receive(elDialog::ChatBuffer,0))\ + {\ + if (!elNetwork::PlayerOut)\ + {\ + if (elNetwork::ChatClose)\ + {\ + elNetwork::ChatOpen=FALSE;\ + elNetwork::ChatCloseMsg=FALSE;\ + \ + elDialog::CloseChat(TRUE);\ + \ + elDialog::Hide();\ + }\ + else\ + {\ + if (strlen(elDialog::ChatBuffer)>NETMSG_SIZE)\ + {\ + elDialog::ChatBuffer[NETMSG_SIZE]=NULL;\ + }\ + \ + elDialog::AddList(elDialog::ChatListID,\ + elDialog::ChatBuffer);\ + \ + if (elDialog::GetListCount(elDialog::ChatListID)>\ + elDialog::ChatListCount)\ + {\ + elDialog::DeleteList(elDialog::ChatListID,0);\ + }\ + \ + elDialog::SetStatic(elDialog::ChatStaticID,\ + " メッセージを受信しました。");\ + }\ + }\ + }\ + }\ + \ + break;\ + }\ + \ + case WM_CLOSE:\ + {\ + elDialog::CloseChat(TRUE);\ + \ + elDialog::Hide();\ + \ + return TRUE;\ + }\ + \ + case WM_NCDESTROY:\ + {\ + _DialogActive=FALSE;\ + \ + return TRUE;\ + }\ + }\ + \ + return FALSE; + +#ifndef DIRECTPLAY + + #define elExitDialogEvent()\ + \ + elExitDialogEvent_A + +#else + + #define elExitDialogEvent()\ + \ + elExitDialogEvent_B + +#endif + +#endif + +/*---< スクリーン定義 >---------------------------------------------------------*/ + +#define elSetScreen(No,Function)\ +\ + case No:\ + {\ + Function;\ + \ + break;\ + } + +/*---< スクリーン呼び出し >-----------------------------------------------------*/ + +#define elCallScreen(No)\ +\ + {\ + _ScreenNo=No;\ + _LastScreenNo=0;\ + } + +/*---< フェイドアウト後にスクリーン呼び出し >-----------------------------------*/ + +#define elFadeScreen(No)\ +\ + {\ + if (elDraw::FadeType==FADE_MASK)\ + {\ + _CallScreenNo=No;\ + \ + elDraw::FadeOut();\ + }\ + else\ + {\ + if (elDraw::FadeType!=FADE_USER)\ + {\ + RECT rect;\ + \ + rect.left=0;\ + rect.top=0;\ + rect.right=elDraw::Width;\ + rect.bottom=elDraw::Height;\ + \ + elDraw::SpriteScreen(SCREEN_SPRITE,0,0,\ + elDraw::Width,elDraw::Height);\ + }\ + \ + _ScreenNo=No;\ + _LastScreenNo=0;\ + \ + elDraw::FadeNo=elDraw::FadeMax;\ + elDraw::FadeAdd=-1;\ + }\ + } + +/*---< フェイドタイプの指定 >---------------------------------------------------*/ + +static const int FADE_MASK=0; // マスクパターン +static const int FADE_LINE1=1; // 横線 ( スライド ) +static const int FADE_LINE2=2; // 横線 ( 均一 ) +static const int FADE_LINE3=3; // 横線 ( スライド+ランダム ) +static const int FADE_LINE4=4; // 横線 ( 均一+ランダム ) +static const int FADE_SLIDE_UP=5; // スライド ( 上 ) +static const int FADE_SLIDE_DOWN=6; // スライド ( 下 ) +static const int FADE_SLIDE_LEFT=7; // スライド ( 左 ) +static const int FADE_SLIDE_RIGHT=8; // スライド ( 右 ) +static const int FADE_SLIDE_UPDOWN=9; // スライド ( 上下 ) +static const int FADE_SLIDE_LEFTRIGHT=10; // スライド ( 左右 ) +static const int FADE_PAGE_LEFT=11; // ページ ( 左 ) +static const int FADE_PAGE_RIGHT=12; // ページ ( 右 ) +static const int FADE_USER=13; // ユーザーレベル + +#define elFadeType(No,Max)\ +\ + {\ + elDraw::FadeType=No;\ + elDraw::FadeMax=Max;\ + } + +/*---< スクリーン取得 >---------------------------------------------------------*/ + +#define elGetScreen()\ +\ + _ScreenNo + +/*---< スクリーン変更直後 >-----------------------------------------------------*/ + +#define elChangeScreen()\ +\ + _ChangeScreen + +/*---< カメラ制御とモデル制御のサンプル >---------------------------------------*/ + +#ifdef DIRECT3D + +#define elNormalSample3D(ModelName)\ +\ + el3D::InitModel(F(0.5),F(0.5),F(999),F(999));\ + \ + if (PushKey=='A') el3D::MoveModelX(-1);\ + if (PushKey=='S') el3D::MoveModelX(1);\ + if (PushKey=='W') el3D::MoveModelY(-1);\ + if (PushKey=='Z') el3D::MoveModelY(1);\ + if (PushKey=='Q') el3D::MoveModelZ(-1);\ + if (PushKey=='X') el3D::MoveModelZ(1);\ + \ + if (PushKey=='D') el3D::RotateModelX(-1);\ + if (PushKey=='F') el3D::RotateModelX(1);\ + if (PushKey=='R') el3D::RotateModelY(-1);\ + if (PushKey=='C') el3D::RotateModelY(1);\ + if (PushKey=='E') el3D::RotateModelZ(-1);\ + if (PushKey=='V') el3D::RotateModelZ(1);\ + \ + if (PushKey=='1') el3D::StopModel();\ + \ + el3D::UpdateModel(ModelName);\ + \ + el3D::InitCamera(F(0.5),F(0.5));\ + \ + if (PushKey=='G') el3D::MoveCameraX(-1);\ + if (PushKey=='H') el3D::MoveCameraX(1);\ + if (PushKey=='Y') el3D::MoveCameraY(-1);\ + if (PushKey=='B') el3D::MoveCameraY(1);\ + if (PushKey=='T') el3D::MoveCameraZ(-1);\ + if (PushKey=='N') el3D::MoveCameraZ(1);\ + \ + if (PushKey=='J') el3D::RotateCameraX(-1);\ + if (PushKey=='K') el3D::RotateCameraX(1);\ + if (PushKey=='I') el3D::RotateCameraY(-1);\ + if (PushKey=='M') el3D::RotateCameraY(1);\ + if (PushKey=='U') el3D::RotateCameraZ(-1);\ + if (PushKey=='L') el3D::RotateCameraZ(1);\ + \ + if (PushKey=='7') el3D::StopCamera();\ + if (PushKey=='9') el3D::LookAtCamera(ModelName);\ + \ + el3D::UpdateCamera(); + +#define elSearchSample3D(ModelName)\ +\ + el3D::InitModel(F(0.5),F(0.5),F(999),F(999));\ + \ + if (PushKey=='A') el3D::MoveModelX(-1);\ + if (PushKey=='S') el3D::MoveModelX(1);\ + if (PushKey=='W') el3D::MoveModelY(-1);\ + if (PushKey=='Z') el3D::MoveModelY(1);\ + if (PushKey=='Q') el3D::MoveModelZ(-1);\ + if (PushKey=='X') el3D::MoveModelZ(1);\ + \ + if (PushKey=='D') el3D::RotateModelX(-1);\ + if (PushKey=='F') el3D::RotateModelX(1);\ + if (PushKey=='R') el3D::RotateModelY(-1);\ + if (PushKey=='C') el3D::RotateModelY(1);\ + if (PushKey=='E') el3D::RotateModelZ(-1);\ + if (PushKey=='V') el3D::RotateModelZ(1);\ + \ + if (PushKey=='1') el3D::StopModel();\ + \ + el3D::UpdateModel(ModelName);\ + \ + el3D::InitCamera(F(0.5),F(0.5));\ + \ + el3D::SearchCamera(ModelName,F(0),F(0),F(3));\ + \ + el3D::UpdateCamera(); + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= システムクラス宣言 ( elSystem ) =*/ +/*= =*/ +/*==============================================================================*/ + +// 最大値定義 +static const int WAIT_MAX=10+1; // ウェイト数 ( 最後の1個は内部で使用 ) + +#ifdef DIRECTINPUT + +static const int INPUTCHECK_MAX=256; // 入力デバイスバッファ数 +static const int JOYSTICK_MAX=16; // ジョイスティック数 + +// DirectInput制御 +#ifdef NEWCODE + +IDirectInput7* DIObject=NULL; +IDirectInputDevice7* DIKeyboard=NULL; +IDirectInputDevice7* DIMouse=NULL; +IDirectInputDevice7* DIJoystick[JOYSTICK_MAX]; + +#else + +IDirectInput* DIObject=NULL; +IDirectInputDevice* DIKeyboard=NULL; +IDirectInputDevice* DIMouse=NULL; +IDirectInputDevice* DIJoystick[JOYSTICK_MAX]; +IDirectInputDevice2* DIJoystick2[JOYSTICK_MAX]; + +#endif + +// デバイスの種類 +static const int USE_KEYBOARD= 0x01; // キーボード +static const int USE_MOUSE_ABS=0x02; // マウス ( 座標は絶対値 ) +static const int USE_MOUSE_REL=0x04; // マウス ( 座標は直前の相対値 ) +static const int USE_JOYSTICK= 0x08; // ジョイスティック + +// 仮想コード定義 + +// キーボード ( フルキー側 ) +#define VC_RETURN 0x1C // Enter / Return +#define VC_ENTER 0x1C // 〃 +#define VC_SPACE 0x39 // Space +#define VC_ESCAPE 0x01 // Escape +#define VC_ESC 0x01 // 〃 +#define VC_BACKSPACE 0x0E // Back space +#define VC_BACK 0x0E // 〃 +#define VC_TAB 0x0F // Tab + +#define VC_LSHIFT 0x2A // 左 Shift +#define VC_RSHIFT 0x36 // 右 Shift +#define VC_LMENU 0x38 // 左 Alt +#define VC_LALT 0x38 // 〃 +#define VC_RMENU 0xB8 // 右 Alt +#define VC_RALT 0xB8 // 〃 +#define VC_LCONTROL 0x1D // 左 Control +#define VC_LCTRL 0x1D // 〃 +#define VC_RCONTROL 0x9D // 右 Control +#define VC_RCTRL 0x9D // 〃 +#define VC_LWIN 0xDB // 左 Windows +#define VC_RWIN 0xDC // 右 Windows +#define VC_APP 0xDD // Application + +#define VC_UP 0xC8 // ↑ +#define VC_DOWN 0xD0 // ↓ +#define VC_LEFT 0xCB // ← +#define VC_RIGHT 0xCD // → + +#define VC_INSERT 0xD2 // Insert +#define VC_HOME 0xC7 // Home +#define VC_PAGEUP 0xC9 // Page Up +#define VC_PGUP 0xC9 // 〃 +#define VC_DELETE 0xD3 // Delete +#define VC_END 0xCF // End +#define VC_PAGEDOWN 0xD1 // Page Down +#define VC_PGDN 0xD1 // 〃 + +#define VC_KANJI 0x94 // 半角/全角 +#define VC_CAPS 0x3A // Caps Lock/英数 +#define VC_KANA 0x70 // ひらがな/ローマ字 +#define VC_CONVERT 0x79 // 変換 +#define VC_NOCONVERT 0x7B // 無変換 + +#define VC_PRINT 0xB7 // Print Scrn +#define VC_SCROLL 0x46 // Scroll Lock +#define VC_PAUSE 0xC5 // Pause/Break + +#define VC_MINUS 0x0C // − +#define VC_FLEX 0x90 // ^ +#define VC_YEN 0x7D // ¥ +#define VC_AT 0x91 // @ +#define VC_LBRCT 0x1A // [ +#define VC_SCOLON 0x27 // ; +#define VC_COLON 0x92 // : +#define VC_RBRCT 0x1B // ] +#define VC_COMMA 0x33 // , +#define VC_PERIOD 0x34 // . +#define VC_SLASH 0x35 // / +#define VC_BSLASH 0x2B // \ + +#define VC_1 0x02 // 数字 +#define VC_2 0x03 +#define VC_3 0x04 +#define VC_4 0x05 +#define VC_5 0x06 +#define VC_6 0x07 +#define VC_7 0x08 +#define VC_8 0x09 +#define VC_9 0x0A +#define VC_0 0x0B + +#define VC_A 0x1E // アルファベット +#define VC_B 0x30 +#define VC_C 0x2E +#define VC_D 0x20 +#define VC_E 0x12 +#define VC_F 0x21 +#define VC_G 0x22 +#define VC_H 0x23 +#define VC_I 0x17 +#define VC_J 0x24 +#define VC_K 0x25 +#define VC_L 0x26 +#define VC_M 0x32 +#define VC_N 0x31 +#define VC_O 0x18 +#define VC_P 0x19 +#define VC_Q 0x10 +#define VC_R 0x13 +#define VC_S 0x1F +#define VC_T 0x14 +#define VC_U 0x16 +#define VC_V 0x2F +#define VC_W 0x11 +#define VC_X 0x2D +#define VC_Y 0x15 +#define VC_Z 0x2C + +#define VC_F1 0x3B // ファンクション +#define VC_F2 0x3C +#define VC_F3 0x3D +#define VC_F4 0x3E +#define VC_F5 0x3F +#define VC_F6 0x40 +#define VC_F7 0x41 +#define VC_F8 0x42 +#define VC_F9 0x43 +#define VC_F10 0x44 +#define VC_F11 0x57 +#define VC_F12 0x58 + +// キーボード ( テンキー側 ) +#define VC_NUMRETURN 0x9C // Enter / Return +#define VC_NUMENTER 0x9C // 〃 +#define VC_NUMLOCK 0x45 // Num Lock +#define VC_NUMMINUS 0x4A // − +#define VC_NUMPLUS 0x4E // + +#define VC_MUMAST 0x37 // * +#define VC_NUMSLASH 0xB5 // / +#define VC_NUMPERIOD 0x53 // . + +#define VC_NUM1 0x4F // 数字 +#define VC_NUM2 0x50 +#define VC_NUM3 0x51 +#define VC_NUM4 0x4B +#define VC_NUM5 0x4C +#define VC_NUM6 0x4D +#define VC_NUM7 0x47 +#define VC_NUM8 0x48 +#define VC_NUM9 0x49 +#define VC_NUM0 0x52 + +// マウス +#define VC_MB1 (0x100+DIMOFS_BUTTON0) // ボタン1 ( 左 ) +#define VC_MLB (0x100+DIMOFS_BUTTON0) //    〃 +#define VC_LBUTTON (0x100+DIMOFS_BUTTON0) //    〃 +#define VC_MB2 (0x100+DIMOFS_BUTTON1) // ボタン2 ( 右 ) +#define VC_MRB (0x100+DIMOFS_BUTTON1) //    〃 +#define VC_RBUTTON (0x100+DIMOFS_BUTTON1) //    〃 +#define VC_MB3 (0x100+DIMOFS_BUTTON2) // ボタン3 +#define VC_MB4 (0x100+DIMOFS_BUTTON3) // ボタン4 + +#define VC_MX (0x1000+DIMOFS_X) // X位置 +#define VC_MY (0x1000+DIMOFS_Y) // Y位置 +#define VC_MZ (0x1000+DIMOFS_Z) // Z位置 + +static int VC_INITMX=0; // X位置初期化 +static int VC_INITMY=0; // Y位置初期化 + +// ジョイスティック +#define VC_JB1 (0x200+DIJOFS_BUTTON0) // ボタン +#define VC_JB2 (0x200+DIJOFS_BUTTON1) +#define VC_JB3 (0x200+DIJOFS_BUTTON2) +#define VC_JB4 (0x200+DIJOFS_BUTTON3) +#define VC_JB5 (0x200+DIJOFS_BUTTON4) +#define VC_JB6 (0x200+DIJOFS_BUTTON5) +#define VC_JB7 (0x200+DIJOFS_BUTTON6) +#define VC_JB8 (0x200+DIJOFS_BUTTON7) +#define VC_JB9 (0x200+DIJOFS_BUTTON8) +#define VC_JB10 (0x200+DIJOFS_BUTTON9) +#define VC_JB11 (0x200+DIJOFS_BUTTON10) +#define VC_JB12 (0x200+DIJOFS_BUTTON11) +#define VC_JB13 (0x200+DIJOFS_BUTTON12) +#define VC_JB14 (0x200+DIJOFS_BUTTON13) +#define VC_JB15 (0x200+DIJOFS_BUTTON14) +#define VC_JB16 (0x200+DIJOFS_BUTTON15) +#define VC_JB17 (0x200+DIJOFS_BUTTON16) +#define VC_JB18 (0x200+DIJOFS_BUTTON17) +#define VC_JB19 (0x200+DIJOFS_BUTTON18) +#define VC_JB20 (0x200+DIJOFS_BUTTON19) +#define VC_JB21 (0x200+DIJOFS_BUTTON20) +#define VC_JB22 (0x200+DIJOFS_BUTTON21) +#define VC_JB23 (0x200+DIJOFS_BUTTON22) +#define VC_JB24 (0x200+DIJOFS_BUTTON23) +#define VC_JB25 (0x200+DIJOFS_BUTTON24) +#define VC_JB26 (0x200+DIJOFS_BUTTON25) +#define VC_JB27 (0x200+DIJOFS_BUTTON26) +#define VC_JB28 (0x200+DIJOFS_BUTTON27) +#define VC_JB29 (0x200+DIJOFS_BUTTON28) +#define VC_JB30 (0x200+DIJOFS_BUTTON29) +#define VC_JB31 (0x200+DIJOFS_BUTTON30) +#define VC_JB32 (0x200+DIJOFS_BUTTON31) + +#define VC_JX (0x2000+DIJOFS_X) // X位置 +#define VC_JY (0x2000+DIJOFS_Y) // Y位置 +#define VC_JZ (0x2000+DIJOFS_Z) // Z位置 +#define VC_JRX (0x2000+DIJOFS_RX) // X角度 +#define VC_JRY (0x2000+DIJOFS_RY) // Y角度 +#define VC_JRZ (0x2000+DIJOFS_RZ) // Z角度 +#define VC_JSLI1 (0x2000+DIJOFS_SLIDER(0)) // スライダー1 +#define VC_JSLI2 (0x2000+DIJOFS_SLIDER(1)) // スライダー2 +#define VC_JPOV1 (0x2000+DIJOFS_POV(0)) // POV1 +#define VC_JPOV2 (0x2000+DIJOFS_POV(1)) // POV2 + +// キー&ボタン判定用 +#define VC_FREE 0xFF00 // 押されていない状態 +#define VC_PUSH 0xFF01 // 押された瞬間 +#define VC_PULL 0xFF02 // 放された瞬間 +#define VC_HOLD 0xFF03 // 押されている状態 + +// デバイス判別用 +#define VC_KEYBOARD 1 // キーボード +#define VC_MOUSE 2 // マウス +#define VC_JOYSTICK 3 // ジョイスティック + +#endif + +// クラス定義 +class elSystem +{ + public: + + static BOOL Init(void); + static void DestroyObject(void); + static BOOL SetWait(int,int); + static BOOL InitWait(int); + static BOOL Wait(int); + static void InitFrame(void); + static void UpdateFrame(void); + static void Message(char*,...); + static BOOL YesNo(char*,...); + static void GetKey(UINT,int*); + static UINT CheckKey(UINT,...); + static void InitMouse(BOOL); + + #ifdef DIRECTINPUT + + static CLBKB SearchDevice(LPCDIDEVICEINSTANCE,LPVOID); + static void GetInputDevice(void); + static BOOL InputLoop(BOOL); + static void UseInputDevice(WORD); + static void GetInput(WORD,int*,float*); + + #endif + + static DWORD FreeDisk(char); + static DWORD FreeMemory(void); + static void MouseMove(int,int); + static char* Directory(BOOL); + static char* Parameter(void); + static void Stop(int); + static void LockKey(void); + static void UnlockKey(void); + static int ColorBit(void); + static BOOL WindowMode(void); + static void MouseArea(int,int,int,int); + static void WindowMouseArea(void); + static void ClearMouseArea(void); + static BOOL GetMouseArea(void); + static void SaveScreenMode(char*,int); + static int LoadScreenMode(char*); + static void SaveMidiMode(char*,int); + static int LoadMidiMode(char*); + static void GetDate(int*,int*,int*,char*); + static void GetTime(int*,int*,int*); + static void SetPullCount(UINT); + static int GetPullCount(void); + static void IME(BOOL); + static BOOL WarningColorBit(char*); + static void CheckInstall(char*); + static void SystemKey(int); + static int GetWindowsVersion(void); + + static DWORD NowTime; + static ULONG WaitTime[]; + static BOOL KeyboardLock; + static BOOL MouseAreaReady; + static BOOL StatusIME; + static int SystemKeyCheck; + static char InstallDirectory[]; + + #ifdef DIRECTINPUT + + static int JoystickCount; + static WORD InputDevice; + static int InputNow; + static DWORD InputCount; + static DIDEVICEOBJECTDATA InputData[]; + static BYTE InputDeviceNo[]; + static RECT MouseMoveLockArea; + static BOOL MakeMousePosition; + + struct _get + { + char Device; // デバイスの種類 ( VC_KEYBOARD、VC_MOUSE、VC_JOYSTICK ) + char DeviceNo; // デバイスNo + WORD Code; // 仮想コード ( VC_…… ) + long Status; // 状態 + //  キーやボタンの場合 ( TRUE=押された / FALSE=放された ) + //  座標の場合 ( 絶対位置または相対位置 ) + float Time; // 処理された時間 + }; + + static struct _get Get; + + #endif +}; + +// フレーム更新直後の時間 +DWORD elSystem::NowTime; + +// 経過時間 +ULONG elSystem::WaitTime[WAIT_MAX]; + +// キーボードロック状態 +BOOL elSystem::KeyboardLock; + +// マウス移動範囲設定フラグ +BOOL elSystem::MouseAreaReady=FALSE; + +// IMEの状態 +BOOL elSystem::StatusIME; + +// システムキー使用可能フラグ +int elSystem::SystemKeyCheck; + +// インストール先のディレクトリィ名 +char elSystem::InstallDirectory[256]=""; + +#ifdef DIRECTINPUT + +// 入力デバイス情報 +int elSystem::JoystickCount; +WORD elSystem::InputDevice; +int elSystem::InputNow; +DWORD elSystem::InputCount; +DIDEVICEOBJECTDATA elSystem::InputData[INPUTCHECK_MAX]; +BYTE elSystem::InputDeviceNo[INPUTCHECK_MAX]; +RECT elSystem::MouseMoveLockArea; +BOOL elSystem::MakeMousePosition; +struct elSystem::_get elSystem::Get; + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= 内部使用システムクラス関数宣言 =*/ +/*= =*/ +/*==============================================================================*/ + +void ChangeActive(BOOL Active) +{ + _WindowActive=Active; + + #ifdef DIRECTINPUT + + static int i; + + if (DIObject) + { + if (elSystem::InputDevice&USE_KEYBOARD && DIKeyboard) + { + if (Active) + { + DIKeyboard->Acquire(); + } + else + { + DIKeyboard->Unacquire(); + } + } + + if (elSystem::InputDevice&(USE_MOUSE_ABS|USE_MOUSE_REL) && DIMouse) + { + if (Active) + { + DIMouse->Acquire(); + } + else + { + DIMouse->Unacquire(); + } + } + + if (elSystem::InputDevice&USE_JOYSTICK) + { + for (i=0;iAcquire(); + } + else + { + DIJoystick[i]->Unacquire(); + } + } + } + } + } + + #endif +} + +/*==============================================================================*/ +/*= =*/ +/*= 内部使用ドロークラス関数宣言 =*/ +/*= =*/ +/*==============================================================================*/ + +// スプライト保存先定義 +static const int LOAD_RAM=1; // RAMに保存 +static const int LOAD_DEFAULT=2; // VRAMかRAMに保存 + +#ifdef DIRECT3D_IM + +static const int LOAD_TEXTURE=3; // テクスチャーとして保存 + +#endif + +HRESULT DDCopyBitmap(IDirectDrawSurface* pdds,HBITMAP hbm, + int x,int y,int dx,int dy) +{ + HDC hdcImage; + HDC hdc; + BITMAP bm; + HRESULT hr; + DDSURFACEDESC ddsd; + + if (hbm==NULL || pdds==NULL) return E_FAIL; + + pdds->Restore(); + + hdcImage=CreateCompatibleDC(NULL); + + SelectObject(hdcImage,hbm); + GetObject(hbm,sizeof(bm),&bm); + + dx=dx==0 ? bm.bmWidth : dx; + dy=dy==0 ? bm.bmHeight : dy; + + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + ddsd.dwFlags=DDSD_HEIGHT|DDSD_WIDTH; + pdds->GetSurfaceDesc(&ddsd); + + if ((hr=pdds->GetDC(&hdc))==DD_OK) + { + StretchBlt(hdc,0,0,ddsd.dwWidth,ddsd.dwHeight,hdcImage,x,y,dx,dy,SRCCOPY); + pdds->ReleaseDC(hdc); + } + + DeleteDC(hdcImage); + + return hr; +} + +DWORD DDColorMatch(IDirectDrawSurface* pdds,COLORREF rgb) +{ + COLORREF rgbT; + HDC hdc; + DWORD dw=CLR_INVALID; + HRESULT hres; + DDSURFACEDESC ddsd; + + if (rgb!=CLR_INVALID && pdds->GetDC(&hdc)==DD_OK) + { + rgbT=GetPixel(hdc,0,0); + SetPixel(hdc,0,0,rgb); + pdds->ReleaseDC(hdc); + } + + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + + while ((hres=pdds->Lock(NULL,&ddsd,0,NULL))==DDERR_WASSTILLDRAWING); + + if (hres==DD_OK) + { + dw=*(DWORD*)ddsd.lpSurface; + + if(ddsd.ddpfPixelFormat.dwRGBBitCount<32) + { + dw&=(1<Unlock(NULL); + } + + if (rgb!=CLR_INVALID && pdds->GetDC(&hdc)==DD_OK) + { + SetPixel(hdc,0,0,rgbT); + pdds->ReleaseDC(hdc); + } + + return dw; +} + +HRESULT DDSetColorKey(IDirectDrawSurface* pdds,COLORREF rgb) +{ + DDCOLORKEY ddck; + + ddck.dwColorSpaceLowValue=DDColorMatch(pdds,rgb); + ddck.dwColorSpaceHighValue=ddck.dwColorSpaceLowValue; + + return pdds->SetColorKey(DDCKEY_SRCBLT,&ddck); +} + +#ifdef DIRECT3D_IM + +IDirectDrawSurface* DDLoadBitmap(IDirectDraw* pdd,LPCSTR szBitmap, + WORD* dx,WORD* dy,int Memory,WORD Texture, + DWORD MinWidth,DWORD MinHeight, + DWORD MaxWidth,DWORD MaxHeight,BOOL AtmMode, + DDPIXELFORMAT* Format) + +#else + +IDirectDrawSurface* DDLoadBitmap(IDirectDraw* pdd,LPCSTR szBitmap, + WORD* dx,WORD* dy,int Memory) + +#endif + +{ + HBITMAP hbm; + BITMAP bm; + DDSURFACEDESC ddsd; + IDirectDrawSurface* pdds; + + hbm=(HBITMAP)LoadImage(GetModuleHandle(NULL),szBitmap,IMAGE_BITMAP, + 0,0,LR_CREATEDIBSECTION); + + if (hbm==NULL) + { + hbm=(HBITMAP)LoadImage(NULL,szBitmap,IMAGE_BITMAP, + 0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION); + } + + if (hbm==NULL) return NULL; + + #ifdef REPORT + + REP_IN + "ファイル / " + REP_OUT + + #endif + + GetObject(hbm,sizeof(bm),&bm); + + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH; + ddsd.dwWidth=bm.bmWidth; + ddsd.dwHeight=bm.bmHeight; + + #ifdef DIRECT3D_IM + + if (Texture) + { + ddsd.dwFlags|=DDSD_TEXTURESTAGE; + ddsd.ddsCaps.dwCaps=DDSCAPS_TEXTURE; + + // アルファが必要な場合 + if (Format) + { + ddsd.dwFlags|=DDSD_PIXELFORMAT; + + memcpy(&ddsd.ddpfPixelFormat,Format,sizeof(DDPIXELFORMAT)); + } + + #ifdef REPORT + + REP_IN + "テクスチャー / " + REP_OUT + + #endif + + if (Texture&0x1000 && AtmMode) + { + ddsd.ddsCaps.dwCaps2|=DDSCAPS2_TEXTUREMANAGE; + } + + if (Texture&0x2000) ddsd.ddsCaps.dwCaps|=DDSCAPS_SYSTEMMEMORY; + + if (Texture&0001) + { + for (ddsd.dwWidth=1;(DWORD)bm.bmWidth>ddsd.dwWidth;ddsd.dwWidth<<=1); + for (ddsd.dwHeight=1;(DWORD)bm.bmHeight>ddsd.dwHeight; + ddsd.dwHeight<<=1); + } + + if (ddsd.dwWidthMaxWidth) ddsd.dwWidth=MaxWidth; + if (ddsd.dwHeightMaxHeight) ddsd.dwHeight=MaxHeight; + + if (Texture&0002) + { + if (ddsd.dwWidth>ddsd.dwHeight) + { + ddsd.dwHeight=ddsd.dwWidth; + } + else + { + ddsd.dwWidth=ddsd.dwHeight; + } + } + } + + if (Texture==0x0000) + + #endif + + { + if (Memory==LOAD_DEFAULT) + { + ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN; + } + else + { + ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY; + + #ifdef REPORT + + REP_IN + "RAMを要求 / " + REP_OUT + + #endif + } + } + + *dx=(WORD)ddsd.dwWidth; + *dy=(WORD)ddsd.dwHeight; + + if (pdd->CreateSurface(&ddsd,&pdds,NULL)!=DD_OK) return NULL; + + DDCopyBitmap(pdds,hbm,0,0,0,0); + + DeleteObject(hbm); + + return pdds; +} + +#ifdef REPORT + +char* GetError(HRESULT Code) +{ + switch (Code) + { + case DDERR_ALREADYINITIALIZED: + return "DDERR_ALREADYINITIALIZED"; + case DDERR_BLTFASTCANTCLIP: + return "DDERR_BLTFASTCANTCLIP"; + case DDERR_CANNOTATTACHSURFACE: + return "DDERR_CANNOTATTACHSURFACE"; + case DDERR_CANNOTDETACHSURFACE: + return "DDERR_CANNOTDETACHSURFACE"; + case DDERR_CANTCREATEDC: + return "DDERR_CANTCREATEDC"; + case DDERR_CANTDUPLICATE: + return "DDERR_CANTDUPLICATE"; + case DDERR_CLIPPERISUSINGHWND: + return "DDERR_CLIPPERISUSINGHWND"; + case DDERR_COLORKEYNOTSET: + return "DDERR_COLORKEYNOTSET"; + case DDERR_CURRENTLYNOTAVAIL: + return "DDERR_CURRENTLYNOTAVAIL"; + case DDERR_DIRECTDRAWALREADYCREATED: + return "DDERR_DIRECTDRAWALREADYCREATED"; + case DDERR_EXCEPTION: + return "DDERR_EXCEPTION"; + case DDERR_EXCLUSIVEMODEALREADYSET: + return "DDERR_EXCLUSIVEMODEALREADYSET"; + case DDERR_GENERIC: + return "DDERR_GENERIC or DSERR_GENERIC"; + case DDERR_HEIGHTALIGN: + return "DDERR_HEIGHTALIGN"; + case DDERR_HWNDALREADYSET: + return "DDERR_HWNDALREADYSET"; + case DDERR_HWNDSUBCLASSED: + return "DDERR_HWNDSUBCLASSED"; + case DDERR_IMPLICITLYCREATED: + return "DDERR_IMPLICITLYCREATED"; + case DDERR_INCOMPATIBLEPRIMARY: + return "DDERR_INCOMPATIBLEPRIMARY"; + case DDERR_INVALIDCAPS: + return "DDERR_INVALIDCAPS"; + case DDERR_INVALIDCLIPLIST: + return "DDERR_INVALIDCLIPLIST"; + case DDERR_INVALIDDIRECTDRAWGUID: + return "DDERR_INVALIDDIRECTDRAWGUID"; + case DDERR_INVALIDMODE: + return "DDERR_INVALIDMODE"; + case DDERR_INVALIDOBJECT: + return "DDERR_INVALIDOBJECT"; + case DDERR_INVALIDPARAMS: + return "DDERR_INVALIDPARAMS or DSERR_INVALIDPARAM"; + case DDERR_INVALIDPIXELFORMAT: + return "DDERR_INVALIDPIXELFORMAT"; + case DDERR_INVALIDPOSITION: + return "DDERR_INVALIDPOSITION"; + case DDERR_INVALIDRECT: + return "DDERR_INVALIDRECT"; + case DDERR_LOCKEDSURFACES: + return "DDERR_LOCKEDSURFACES"; + case DDERR_NO3D: + return "DDERR_NO3D"; + case DDERR_NOALPHAHW: + return "DDERR_NOALPHAHW"; + case DDERR_NOBLTHW: + return "DDERR_NOBLTHW"; + case DDERR_NOCLIPLIST: + return "DDERR_NOCLIPLIST"; + case DDERR_NOCLIPPERATTACHED: + return "DDERR_NOCLIPPERATTACHED"; + case DDERR_NOCOLORCONVHW: + return "DDERR_NOCOLORCONVHW"; + case DDERR_NOCOLORKEY: + return "DDERR_NOCOLORKEY"; + case DDERR_NOCOLORKEYHW: + return "DDERR_NOCOLORKEYHW"; + case DDERR_NOCOOPERATIVELEVELSET: + return "DDERR_NOCOOPERATIVELEVELSET"; + case DDERR_NODC: + return "DDERR_NODC"; + case DDERR_NODDROPSHW: + return "DDERR_NODDROPSHW"; + case DDERR_NODIRECTDRAWHW: + return "DDERR_NODIRECTDRAWHW"; + case DDERR_NOEMULATION: + return "DDERR_NOEMULATION"; + case DDERR_NOEXCLUSIVEMODE: + return "DDERR_NOEXCLUSIVEMODE"; + case DDERR_NOFLIPHW: + return "DDERR_NOFLIPHW"; + case DDERR_NOGDI: + return "DDERR_NOGDI"; + case DDERR_NOHWND: + return "DDERR_NOHWND"; + case DDERR_NOMIRRORHW: + return "DDERR_NOMIRRORHW"; + case DDERR_NOOVERLAYDEST: + return "DDERR_NOOVERLAYDEST"; + case DDERR_NOOVERLAYHW: + return "DDERR_NOOVERLAYHW"; + case DDERR_NOPALETTEATTACHED: + return "DDERR_NOPALETTEATTACHED"; + case DDERR_NOPALETTEHW: + return "DDERR_NOPALETTEHW"; + case DDERR_NORASTEROPHW: + return "DDERR_NORASTEROPHW"; + case DDERR_NOROTATIONHW: + return "DDERR_NOROTATIONHW"; + case DDERR_NOSTRETCHHW: + return "DDERR_NOSTRETCHHW"; + case DDERR_NOT4BITCOLOR: + return "DDERR_NOT4BITCOLOR"; + case DDERR_NOT4BITCOLORINDEX: + return "DDERR_NOT4BITCOLORINDEX"; + case DDERR_NOT8BITCOLOR: + return "DDERR_NOT8BITCOLOR"; + case DDERR_NOTAOVERLAYSURFACE: + return "DDERR_NOTAOVERLAYSURFACE"; + case DDERR_NOTEXTUREHW: + return "DDERR_NOTEXTUREHW"; + case DDERR_NOTFLIPPABLE: + return "DDERR_NOTFLIPPABLE"; + case DDERR_NOTFOUND: + return "DDERR_NOTFOUND"; + case DDERR_NOTLOCKED: + return "DDERR_NOTLOCKED"; + case DDERR_NOTPALETTIZED: + return "DDERR_NOTPALETTIZED"; + case DDERR_NOVSYNCHW: + return "DDERR_NOVSYNCHW"; + case DDERR_NOZBUFFERHW: + return "DDERR_NOZBUFFERHW"; + case DDERR_NOZOVERLAYHW: + return "DDERR_NOZOVERLAYHW"; + case DDERR_OUTOFCAPS: + return "DDERR_OUTOFCAPS"; + case DDERR_OUTOFMEMORY: + return "DDERR_OUTOFMEMORY or DSERR_OUTOFMEMORY"; + case DDERR_OUTOFVIDEOMEMORY: + return "DDERR_OUTOFVIDEOMEMORY"; + case DDERR_OVERLAYCANTCLIP: + return "DDERR_OVERLAYCANTCLIP"; + case DDERR_OVERLAYCOLORKEYONLYONEACTIVE: + return "DDERR_OVERLAYCOLORKEYONLYONEACTIVE"; + case DDERR_OVERLAYNOTVISIBLE: + return "DDERR_OVERLAYNOTVISIBLE"; + case DDERR_PALETTEBUSY: + return "DDERR_PALETTEBUSY"; + case DDERR_PRIMARYSURFACEALREADYEXISTS: + return "DDERR_PRIMARYSURFACEALREADYEXISTS"; + case DDERR_REGIONTOOSMALL: + return "DDERR_REGIONTOOSMALL"; + case DDERR_SURFACEALREADYATTACHED: + return "DDERR_SURFACEALREADYATTACHED"; + case DDERR_SURFACEALREADYDEPENDENT: + return "DDERR_SURFACEALREADYDEPENDENT"; + case DDERR_SURFACEBUSY: + return "DDERR_SURFACEBUSY"; + case DDERR_SURFACEISOBSCURED: + return "DDERR_SURFACEISOBSCURED"; + case DDERR_SURFACELOST: + return "DDERR_SURFACELOST"; + case DDERR_SURFACENOTATTACHED: + return "DDERR_SURFACENOTATTACHED"; + case DDERR_TOOBIGHEIGHT: + return "DDERR_TOOBIGHEIGHT"; + case DDERR_TOOBIGSIZE: + return "DDERR_TOOBIGSIZE"; + case DDERR_TOOBIGWIDTH: + return "DDERR_TOOBIGWIDTH"; + case DDERR_UNSUPPORTED: + return "DDERR_UNSUPPORTED or DSERR_UNSUPPORTED"; + case DDERR_UNSUPPORTEDFORMAT: + return "DDERR_UNSUPPORTEDFORMAT"; + case DDERR_UNSUPPORTEDMASK: + return "DDERR_UNSUPPORTEDMASK"; + case DDERR_VERTICALBLANKINPROGRESS: + return "DDERR_VERTICALBLANKINPROGRESS"; + case DDERR_WASSTILLDRAWING: + return "DDERR_WASSTILLDRAWING"; + case DDERR_WRONGMODE: + return "DDERR_WRONGMODE"; + case DDERR_XALIGN: + return "DDERR_XALIGN"; + + case DSERR_ALLOCATED: + return "DSERR_ALLOCATED"; + case DSERR_ALREADYINITIALIZED: + return "DSERR_ALREADYINITIALIZED"; + case DSERR_BADFORMAT: + return "DSERR_BADFORMAT"; + case DSERR_BUFFERLOST: + return "DSERR_BUFFERLOST"; + case DSERR_CONTROLUNAVAIL: + return "DSERR_CONTROLUNAVAIL"; + case DSERR_INVALIDCALL: + return "DSERR_INVALIDCALL"; + case DSERR_NOAGGREGATION: + return "DSERR_NOAGGREGATION"; + case DSERR_NODRIVER: + return "DSERR_NODRIVER"; + case DSERR_OTHERAPPHASPRIO: + return "DSERR_OTHERAPPHASPRIO"; + case DSERR_PRIOLEVELNEEDED: + return "DSERR_PRIOLEVELNEEDED"; + case DSERR_UNINITIALIZED: + return "DSERR_UNINITIALIZED"; + + #if defined(DIRECT3D) || defined(DIRECT3D_IM) + + case D3DERR_BADMAJORVERSION: + return "D3DERR_BADMAJORVERSION"; + case D3DERR_BADMINORVERSION: + return "D3DERR_BADMINORVERSION"; + case D3DERR_EXECUTE_LOCKED: + return "D3DERR_EXECUTE_LOCKED"; + case D3DERR_EXECUTE_NOT_LOCKED: + return "D3DERR_EXECUTE_NOT_LOCKED"; + case D3DERR_EXECUTE_CREATE_FAILED: + return "D3DERR_EXECUTE_CREATE_FAILED"; + case D3DERR_EXECUTE_DESTROY_FAILED: + return "D3DERR_EXECUTE_DESTROY_FAILED"; + case D3DERR_EXECUTE_LOCK_FAILED: + return "D3DERR_EXECUTE_LOCK_FAILED"; + case D3DERR_EXECUTE_UNLOCK_FAILED: + return "D3DERR_EXECUTE_UNLOCK_FAILED"; + case D3DERR_EXECUTE_FAILED: + return "D3DERR_EXECUTE_FAILED"; + case D3DERR_EXECUTE_CLIPPED_FAILED: + return "D3DERR_EXECUTE_CLIPPED_FAILED"; + case D3DERR_TEXTURE_NO_SUPPORT: + return "D3DERR_TEXTURE_NO_SUPPORT"; + case D3DERR_TEXTURE_NOT_LOCKED: + return "D3DERR_TEXTURE_NOT_LOCKED"; + case D3DERR_TEXTURE_LOCKED: + return "D3DERR_TEXTURE_LOCKED"; + case D3DERR_TEXTURE_CREATE_FAILED: + return "D3DERR_TEXTURE_CREATE_FAILED"; + case D3DERR_TEXTURE_DESTROY_FAILED: + return "D3DERR_TEXTURE_DESTROY_FAILED"; + case D3DERR_TEXTURE_LOCK_FAILED: + return "D3DERR_TEXTURE_LOCK_FAILED"; + case D3DERR_TEXTURE_UNLOCK_FAILED: + return "D3DERR_TEXTURE_UNLOCK_FAILED"; + case D3DERR_TEXTURE_LOAD_FAILED: + return "D3DERR_TEXTURE_LOAD_FAILED"; + case D3DERR_MATRIX_CREATE_FAILED: + return "D3DERR_MATRIX_CREATE_FAILED"; + case D3DERR_MATRIX_DESTROY_FAILED: + return "D3DERR_MATRIX_DESTROY_FAILED"; + case D3DERR_MATRIX_SETDATA_FAILED: + return "D3DERR_MATRIX_SETDATA_FAILED"; + case D3DERR_SETVIEWPORTDATA_FAILED: + return "D3DERR_SETVIEWPORTDATA_FAILED"; + case D3DERR_MATERIAL_CREATE_FAILED: + return "D3DERR_MATERIAL_CREATE_FAILED"; + case D3DERR_MATERIAL_DESTROY_FAILED: + return "D3DERR_MATERIAL_DESTROY_FAILED"; + case D3DERR_MATERIAL_SETDATA_FAILED: + return "D3DERR_MATERIAL_SETDATA_FAILED"; + case D3DERR_LIGHT_SET_FAILED: + return "D3DERR_LIGHT_SET_FAILED"; + + #endif + + #ifdef DIRECT3D_IM + + case D3DERR_INVALIDCURRENTVIEWPORT: + return "D3DERR_INVALIDCURRENTVIEWPORT"; + case D3DERR_INVALIDPRIMITIVETYPE: + return "D3DERR_INVALIDPRIMITIVETYPE"; + case D3DERR_INVALIDVERTEXTYPE: + return "D3DERR_INVALIDVERTEXTYPE"; + case D3DERR_TEXTURE_BADSIZE: + return "D3DERR_TEXTURE_BADSIZE"; + case D3DERR_INVALIDRAMPTEXTURE: + return "D3DERR_INVALIDRAMPTEXTURE"; + case D3DERR_INVALIDPALETTE: + return "D3DERR_INVALIDPALETTE"; + case D3DERR_ZBUFF_NEEDS_SYSTEMMEMORY: + return "D3DERR_ZBUFF_NEEDS_SYSTEMMEMORY"; + case D3DERR_ZBUFF_NEEDS_VIDEOMEMORY: + return "D3DERR_ZBUFF_NEEDS_VIDEOMEMORY"; + case D3DERR_SURFACENOTINVIDMEM: + return "D3DERR_SURFACENOTINVIDMEM"; + case D3DERR_LIGHTHASVIEWPORT: + return "D3DERR_LIGHTHASVIEWPORT"; + case D3DERR_LIGHTNOTINTHISVIEWPORT: + return "D3DERR_LIGHTNOTINTHISVIEWPORT"; + case D3DERR_SCENE_IN_SCENE: + return "D3DERR_SCENE_IN_SCENE"; + case D3DERR_SCENE_NOT_IN_SCENE: + return "D3DERR_SCENE_NOT_IN_SCENE"; + case D3DERR_SCENE_BEGIN_FAILED: + return "D3DERR_SCENE_BEGIN_FAILED"; + case D3DERR_SCENE_END_FAILED: + return "D3DERR_SCENE_END_FAILED"; + case D3DERR_INBEGIN: + return "D3DERR_INBEGIN"; + case D3DERR_NOTINBEGIN: + return "D3DERR_NOTINBEGIN"; + case D3DERR_NOVIEWPORTS: + return "D3DERR_NOVIEWPORTS"; + case D3DERR_VIEWPORTDATANOTSET: + return "D3DERR_VIEWPORTDATANOTSET"; + case D3DERR_VIEWPORTHASNODEVICE: + return "D3DERR_VIEWPORTHASNODEVICE"; + case D3DERR_NOCURRENTVIEWPORT: + return "D3DERR_NOCURRENTVIEWPORT"; + case D3DERR_INVALIDVERTEXFORMAT: + return "D3DERR_INVALIDVERTEXFORMAT"; + case D3DERR_COLORKEYATTACHED: + return "D3DERR_COLORKEYATTACHED"; + case D3DERR_VERTEXBUFFEROPTIMIZED: + return "D3DERR_VERTEXBUFFEROPTIMIZED"; + case D3DERR_VBUF_CREATE_FAILED: + return "D3DERR_VBUF_CREATE_FAILED"; + case D3DERR_VERTEXBUFFERLOCKED: + return "D3DERR_VERTEXBUFFERLOCKED"; + case D3DERR_VERTEXBUFFERUNLOCKFAILED: + return "D3DERR_VERTEXBUFFERUNLOCKFAILED"; + case D3DERR_ZBUFFER_NOTPRESENT: + return "D3DERR_ZBUFFER_NOTPRESENT"; + case D3DERR_STENCILBUFFER_NOTPRESENT: + return "D3DERR_STENCILBUFFER_NOTPRESENT"; + case D3DERR_WRONGTEXTUREFORMAT: + return "D3DERR_WRONGTEXTUREFORMAT"; + case D3DERR_UNSUPPORTEDCOLOROPERATION: + return "D3DERR_UNSUPPORTEDCOLOROPERATION"; + case D3DERR_UNSUPPORTEDCOLORARG: + return "D3DERR_UNSUPPORTEDCOLORARG"; + case D3DERR_UNSUPPORTEDALPHAOPERATION: + return "D3DERR_UNSUPPORTEDALPHAOPERATION"; + case D3DERR_UNSUPPORTEDALPHAARG: + return "D3DERR_UNSUPPORTEDALPHAARG"; + case D3DERR_TOOMANYOPERATIONS: + return "D3DERR_TOOMANYOPERATIONS"; + case D3DERR_CONFLICTINGTEXTUREFILTER: + return "D3DERR_CONFLICTINGTEXTUREFILTER"; + case D3DERR_UNSUPPORTEDFACTORVALUE: + return "D3DERR_UNSUPPORTEDFACTORVALUE"; + case D3DERR_CONFLICTINGRENDERSTATE: + return "D3DERR_CONFLICTINGRENDERSTATE"; + case D3DERR_UNSUPPORTEDTEXTUREFILTER: + return "D3DERR_UNSUPPORTEDTEXTUREFILTER"; + case D3DERR_TOOMANYPRIMITIVES: + return "D3DERR_TOOMANYPRIMITIVES"; + case D3DERR_INVALIDMATRIX: + return "D3DERR_INVALIDMATRIX"; + case D3DERR_TOOMANYVERTICES: + return "D3DERR_TOOMANYVERTICES"; + case D3DERR_CONFLICTINGTEXTUREPALETTE: + return "D3DERR_CONFLICTINGTEXTUREPALETTE"; + case D3DERR_INVALIDSTATEBLOCK: + return "D3DERR_INVALIDSTATEBLOCK"; + case D3DERR_INBEGINSTATEBLOCK: + return "D3DERR_INBEGINSTATEBLOCK"; + case D3DERR_NOTINBEGINSTATEBLOCK: + return "D3DERR_NOTINBEGINSTATEBLOCK"; + + #endif + + #ifdef DIRECT3D + + case D3DRMERR_BADOBJECT: + return "D3DRMERR_BADOBJECT"; + case D3DRMERR_BADTYPE: + return "D3DRMERR_BADTYPE"; + case D3DRMERR_BADALLOC: + return "D3DRMERR_BADALLOC"; + case D3DRMERR_FACEUSED: + return "D3DRMERR_FACEUSED"; + case D3DRMERR_NOTFOUND: + return "D3DRMERR_NOTFOUND"; + case D3DRMERR_NOTDONEYET: + return "D3DRMERR_NOTDONEYET"; + case D3DRMERR_FILENOTFOUND: + return "D3DRMERR_FILENOTFOUND"; + case D3DRMERR_BADFILE: + return "D3DRMERR_BADFILE"; + case D3DRMERR_BADDEVICE: + return "D3DRMERR_BADDEVICE"; + case D3DRMERR_BADVALUE: + return "D3DRMERR_BADVALUE"; + case D3DRMERR_BADMAJORVERSION: + return "D3DRMERR_BADMAJORVERSION"; + case D3DRMERR_BADMINORVERSION: + return "D3DRMERR_BADMINORVERSION"; + case D3DRMERR_UNABLETOEXECUTE: + return "D3DRMERR_UNABLETOEXECUTE"; + + #endif + + #ifdef DIRECTMUSIC + + case DMUS_S_PARTIALLOAD: + return "DMUS_S_PARTIALLOAD"; + case DMUS_S_PARTIALDOWNLOAD: + return "DMUS_S_PARTIALDOWNLOAD"; + case DMUS_S_REQUEUE: + return "DMUS_S_REQUEUE"; + case DMUS_S_FREE: + return "DMUS_S_FREE"; + case DMUS_S_END: + return "DMUS_S_END"; + case DMUS_S_STRING_TRUNCATED: + return "DMUS_S_STRING_TRUNCATED"; + case DMUS_S_LAST_TOOL: + return "DMUS_S_LAST_TOOL"; + case DMUS_S_OVER_CHORD: + return "DMUS_S_OVER_CHORD"; + case DMUS_S_UP_OCTAVE: + return "DMUS_S_UP_OCTAVE"; + case DMUS_S_DOWN_OCTAVE: + return "DMUS_S_DOWN_OCTAVE"; + case DMUS_S_NOBUFFERCONTROL: + return "DMUS_S_NOBUFFERCONTROL"; + case DMUS_E_DRIVER_FAILED: + return "DMUS_E_DRIVER_FAILED"; + case DMUS_E_PORTS_OPEN: + return "DMUS_E_PORTS_OPEN"; + case DMUS_E_DEVICE_IN_USE: + return "DMUS_E_DEVICE_IN_USE"; + case DMUS_E_INSUFFICIENTBUFFER: + return "DMUS_E_INSUFFICIENTBUFFER"; + case DMUS_E_BUFFERNOTSET: + return "DMUS_E_BUFFERNOTSET"; + case DMUS_E_BUFFERNOTAVAILABLE: + return "DMUS_E_BUFFERNOTAVAILABLE"; + case DMUS_E_NOTADLSCOL: + return "DMUS_E_NOTADLSCOL"; + case DMUS_E_INVALIDOFFSET: + return "DMUS_E_INVALIDOFFSET"; + case DMUS_E_ALREADY_LOADED: + return "DMUS_E_ALREADY_LOADED"; + case DMUS_E_INVALIDPOS: + return "DMUS_E_INVALIDPOS"; + case DMUS_E_INVALIDPATCH: + return "DMUS_E_INVALIDPATCH"; + case DMUS_E_CANNOTSEEK: + return "DMUS_E_CANNOTSEEK"; + case DMUS_E_CANNOTWRITE: + return "DMUS_E_CANNOTWRITE"; + case DMUS_E_CHUNKNOTFOUND: + return "DMUS_E_CHUNKNOTFOUND"; + case DMUS_E_INVALID_DOWNLOADID: + return "DMUS_E_INVALID_DOWNLOADID"; + case DMUS_E_NOT_DOWNLOADED_TO_PORT: + return "DMUS_E_NOT_DOWNLOADED_TO_PORT"; + case DMUS_E_ALREADY_DOWNLOADED: + return "DMUS_E_ALREADY_DOWNLOADED"; + case DMUS_E_UNKNOWN_PROPERTY: + return "DMUS_E_UNKNOWN_PROPERTY"; + case DMUS_E_SET_UNSUPPORTED: + return "DMUS_E_SET_UNSUPPORTED"; + case DMUS_E_GET_UNSUPPORTED: + return "DMUS_E_GET_UNSUPPORTED"; + case DMUS_E_NOTMONO: + return "DMUS_E_NOTMONO"; + case DMUS_E_BADARTICULATION: + return "DMUS_E_BADARTICULATION"; + case DMUS_E_BADINSTRUMENT: + return "DMUS_E_BADINSTRUMENT"; + case DMUS_E_BADWAVELINK: + return "DMUS_E_BADWAVELINK"; + case DMUS_E_NOARTICULATION: + return "DMUS_E_NOARTICULATION"; + case DMUS_E_NOTPCM: + return "DMUS_E_NOTPCM"; + case DMUS_E_BADWAVE: + return "DMUS_E_BADWAVE"; + case DMUS_E_BADOFFSETTABLE: + return "DMUS_E_BADOFFSETTABLE"; + case DMUS_E_UNKNOWNDOWNLOAD: + return "DMUS_E_UNKNOWNDOWNLOAD"; + case DMUS_E_NOSYNTHSINK: + return "DMUS_E_NOSYNTHSINK"; + case DMUS_E_ALREADYOPEN: + return "DMUS_E_ALREADYOPEN"; + case DMUS_E_ALREADYCLOSED: + return "DMUS_E_ALREADYCLOSED"; + case DMUS_E_SYNTHNOTCONFIGURED: + return "DMUS_E_SYNTHNOTCONFIGURED"; + case DMUS_E_SYNTHACTIVE: + return "DMUS_E_SYNTHACTIVE"; + case DMUS_E_CANNOTREAD: + return "DMUS_E_CANNOTREAD"; + case DMUS_E_DMUSIC_RELEASED: + return "DMUS_E_DMUSIC_RELEASED"; + case DMUS_E_BUFFER_EMPTY: + return "DMUS_E_BUFFER_EMPTY"; + case DMUS_E_BUFFER_FULL: + return "DMUS_E_BUFFER_FULL"; + case DMUS_E_PORT_NOT_CAPTURE: + return "DMUS_E_PORT_NOT_CAPTURE"; + case DMUS_E_PORT_NOT_RENDER: + return "DMUS_E_PORT_NOT_RENDER"; + case DMUS_E_DSOUND_NOT_SET: + return "DMUS_E_DSOUND_NOT_SET"; + case DMUS_E_ALREADY_ACTIVATED: + return "DMUS_E_ALREADY_ACTIVATED"; + case DMUS_E_INVALIDBUFFER: + return "DMUS_E_INVALIDBUFFER"; + case DMUS_E_WAVEFORMATNOTSUPPORTED: + return "DMUS_E_WAVEFORMATNOTSUPPORTED"; + case DMUS_E_SYNTHINACTIVE: + return "DMUS_E_SYNTHINACTIVE"; + case DMUS_E_DSOUND_ALREADY_SET: + return "DMUS_E_DSOUND_ALREADY_SET"; + case DMUS_E_INVALID_EVENT: + return "DMUS_E_INVALID_EVENT"; + case DMUS_E_UNSUPPORTED_STREAM: + return "DMUS_E_UNSUPPORTED_STREAM"; + case DMUS_E_ALREADY_INITED: + return "DMUS_E_ALREADY_INITED"; + case DMUS_E_INVALID_BAND: + return "DMUS_E_INVALID_BAND"; + case DMUS_E_TRACK_HDR_NOT_FIRST_CK: + return "DMUS_E_TRACK_HDR_NOT_FIRST_CK"; + case DMUS_E_TOOL_HDR_NOT_FIRST_CK: + return "DMUS_E_TOOL_HDR_NOT_FIRST_CK"; + case DMUS_E_INVALID_TRACK_HDR: + return "DMUS_E_INVALID_TRACK_HDR"; + case DMUS_E_INVALID_TOOL_HDR: + return "DMUS_E_INVALID_TOOL_HDR"; + case DMUS_E_ALL_TOOLS_FAILED: + return "DMUS_E_ALL_TOOLS_FAILED"; + case DMUS_E_ALL_TRACKS_FAILED: + return "DMUS_E_ALL_TRACKS_FAILED"; + case DMUS_E_NOT_FOUND: + return "DMUS_E_NOT_FOUND"; + case DMUS_E_NOT_INIT: + return "DMUS_E_NOT_INIT"; + case DMUS_E_TYPE_DISABLED: + return "DMUS_E_TYPE_DISABLED"; + case DMUS_E_TYPE_UNSUPPORTED: + return "DMUS_E_TYPE_UNSUPPORTED"; + case DMUS_E_TIME_PAST: + return "DMUS_E_TIME_PAST"; + case DMUS_E_TRACK_NOT_FOUND: + return "DMUS_E_TRACK_NOT_FOUND"; + case DMUS_E_NO_MASTER_CLOCK: + return "DMUS_E_NO_MASTER_CLOCK"; + case DMUS_E_LOADER_NOCLASSID: + return "DMUS_E_LOADER_NOCLASSID"; + case DMUS_E_LOADER_BADPATH: + return "DMUS_E_LOADER_BADPATH"; + case DMUS_E_LOADER_FAILEDOPEN: + return "DMUS_E_LOADER_FAILEDOPEN"; + case DMUS_E_LOADER_FORMATNOTSUPPORTED: + return "DMUS_E_LOADER_FORMATNOTSUPPORTED"; + case DMUS_E_LOADER_FAILEDCREATE: + return "DMUS_E_LOADER_FAILEDCREATE"; + case DMUS_E_LOADER_OBJECTNOTFOUND: + return "DMUS_E_LOADER_OBJECTNOTFOUND"; + case DMUS_E_LOADER_NOFILENAME: + return "DMUS_E_LOADER_NOFILENAME"; + case DMUS_E_INVALIDFILE: + return "DMUS_E_INVALIDFILE"; + case DMUS_E_ALREADY_EXISTS: + return "DMUS_E_ALREADY_EXISTS"; + case DMUS_E_OUT_OF_RANGE: + return "DMUS_E_OUT_OF_RANGE"; + case DMUS_E_SEGMENT_INIT_FAILED: + return "DMUS_E_SEGMENT_INIT_FAILED"; + case DMUS_E_ALREADY_SENT: + return "DMUS_E_ALREADY_SENT"; + case DMUS_E_CANNOT_FREE: + return "DMUS_E_CANNOT_FREE"; + case DMUS_E_CANNOT_OPEN_PORT: + return "DMUS_E_CANNOT_OPEN_PORT"; + case DMUS_E_CONNOT_CONVERT: + return "DMUS_E_CONNOT_CONVERT"; + case DMUS_E_DESCEND_CHUNK_FAIL: + return "DMUS_E_DESCEND_CHUNK_FAIL"; + + #endif + + default: + return "不明"; + } +} + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= ドロークラス宣言 ( elDraw ) =*/ +/*= =*/ +/*==============================================================================*/ + +// 最大値定義 +static const int SPRITE_MAX=1024; // スプライト数 ( 最初の2個は内部で使用 ) + +// DirectDraw制御 +#ifdef NEWCODE + +static LPDIRECTDRAW7 DDObject=NULL; +static LPDIRECTDRAWSURFACE7 DDFront=NULL; +static LPDIRECTDRAWSURFACE7 DDBack=NULL; + +#else + +static LPDIRECTDRAW DDObject=NULL; +static LPDIRECTDRAWSURFACE DDFront=NULL; +static LPDIRECTDRAWSURFACE DDBack=NULL; + +#endif + +static LPDIRECTDRAWCLIPPER DDClip=NULL; + +#ifdef DIRECT3D + +static LPDIRECTDRAWSURFACE DD3D=NULL; +static LPDIRECTDRAWSURFACE DDZBuffer=NULL; + +#endif + +// 内部使用スプライト定義 +static const int BUFFER_SPRITE=0; // バッファ用 +static const int SCREEN_SPRITE=1; // スクリーン切り換え用 +static const int FONT_SPRITE=2; // フォント用 +static const int FONTBUFFER_SPRITE=3; // フォントバッファ用 + +// クラス定義 +class elDraw +{ + public: + + static BOOL Screen(int,int,int); + static void VirtualScreen(int,int,int,int); + static void SetFullColor(int,int,int); + static BOOL Exit(void); + static BOOL Error(char*,char*,HRESULT=NULL); + static BOOL Error(void); + static BOOL ErrorExit(void); + static DDOBJ LoadObject(char*,int); + static DDOBJ CreateObject(int,int,int); + static void FreeObject(DDOBJ); + static BOOL SwapObject(char*,DDOBJ,int); + static void ReloadObject(void); + static void DestroyObject(void); + static void SetPack(char*); + static DDOBJ LoadPack(char*,int); + static DDOBJ SwapPack(char*,DDOBJ,int); + static BOOL Convert(char*,char*,BOOL); + static void ConvertFile(char*,char*); + static void SetSpriteColor(COLORREF); + static void SetSpriteLeftTop(void); + static void CopySpriteColor(DDOBJ,DDOBJ); + static void ChangeSpriteColor(DDOBJ,COLORREF); + static void ChangeSpriteLeftTop(DDOBJ); + static void Clear(void); + static void SpriteClear(DDOBJ); + + #ifdef DIRECT3D + + static void Clear3D(void); + + #endif + + static void ClearArea(int,int,int,int); + static void ClearFrame(int,int,int,int); + static void Flash(void); + static void FlashArea(int,int,int,int); + static void ColorFill(int,int,int,int,WORD); + static BOOL ColorBlend(int,int,int,int,WORD); + static void Layer(int,int,DDOBJ,int,int,int,int); + static void SpriteLayer(DDOBJ,int,int,DDOBJ,int,int,int,int); + static void DirectLayer(int,int,DDOBJ,int,int,int,int); + static void DirectSpriteLayer(DDOBJ,int,int,DDOBJ,int,int,int,int); + static void WaveLayer(int,int,int,int,float,DDOBJ,int,int,int,int,BOOL); + static void TileLayer(float,float,DDOBJ,int,int,int,int); + static void RollWaveLayer(int,int,int,int,float,float,DDOBJ, + int,int,int,int); + static void TileRollWaveLayer(int,int,int,int,float,float,DDOBJ, + int,int,int,int); + static void MosaicLayer(int,int,int,DDOBJ,int,int,int,int); + static void StretchLayer(int,int,DDOBJ,int,int,int,int,int,int); + static void DirectStretchLayer(int,int,DDOBJ,int,int,int,int,int,int); + static BOOL MirrorLayer(int,int,int,DDOBJ,int,int,int,int); + static void LineLayer(int,int,int,DDOBJ,int,int,int,int); + static void RandomLayer(int,int,int,DDOBJ,int,int,int,int); + static void WaterfallLayer(int,int,int,float,DDOBJ,int,int,int,int); + + #ifdef DIRECT3D + + static void Layer3D(int,int,int,int,int,int); + static void DirectLayer3D(int,int,int,int,int,int); + + #endif + + static BOOL BlendLayer(int,int,DDOBJ,int,int,int,int); + static BOOL BlendLayer(int,int,float,DDOBJ,int,int,int,int); + static BOOL BlendLayer(int,int,float,float,float,DDOBJ,int,int,int,int); + static BOOL BlendLayer(int,int,int,DDOBJ,int,int,int,int); + static BOOL BlendLayer(int,int,int,int,int,DDOBJ,int,int,int,int); + static BOOL BlendLayer(int,int,float,float,float,int,int,int, + DDOBJ,int,int,int,int); + static BOOL BlendLayer(int,int,int,int,int,int,int,int, + DDOBJ,int,int,int,int); + static BOOL AddBlendLayer(int,int,DDOBJ,int,int,int,int); + static BOOL AddBlendLayer(int,int,float,DDOBJ,int,int,int,int); + static BOOL DelBlendLayer(int,int,DDOBJ,int,int,int,int); + static BOOL EdgeBlendLayer(int,int,DDOBJ,int,int,int,int); + static BOOL PlainLayer(int,int,BOOL,BOOL,BOOL,DDOBJ,int,int,int,int); + static BOOL BrightLayer(int,int,float,DDOBJ,int,int,int,int); + static BOOL BrightLayer(int,int,float,float,float,DDOBJ,int,int,int,int); + static BOOL BrightLayer(int,int,int,DDOBJ,int,int,int,int); + static BOOL BrightLayer(int,int,int,int,int,DDOBJ,int,int,int,int); + static BOOL ShadeLayer(int,int,int,DDOBJ,int,int,int,int); + static BOOL GrayLayer(int,int,DDOBJ,int,int,int,int); + static BOOL MeshLayer(int,int,int,int,int,float,float,DDOBJ,int,int,int,int); + static BOOL RotateLayer(int,int,int,int,int,DDOBJ,int,int,int,int); + static BOOL TileRotateLayer(int,int,int,int,int,DDOBJ,int,int,int,int); + static BOOL ZoomRotateLayer(int,int,int,int,int,float,DDOBJ,int,int,int,int); + static BOOL TileZoomRotateLayer(int,int,int,int,int,float,DDOBJ, + int,int,int,int); + static BOOL MysteryLayer(int,int,int,int,int,float,float,float,float, + float,float,float,DDOBJ,int,int,int,int); + static BOOL PickLayer(int,int,int,int,DDOBJ,int,int,int,int); + static BOOL ShiftLayer(int,int,float,DDOBJ,int,int,int,int); + static void CreateTunnel(int,int,int,int,int,int,int,int,int,int); + static BOOL TunnelLayer(int,int,int,int,DDOBJ); + static BOOL LightLayer(int,int,int,int,int,WORD,BOOL,DDOBJ,int,int,int,int); + static BOOL SetWipe(int,int,float,int); + static void SetWipeOut(void); + static BOOL Wipe(void); + static void Reverse(int,int,int,int); + static void Refresh(void); + static void SetRefreshMode(BOOL); + static void ShowFPS(void); + static void ShowString(int,int,char*); + static void ShowFormat(int,int,char*,...); + static void FillPattern(POINT*,int,COLORREF,COLORREF,int,int); + static void LoadMask(char*); + static void LoadHelp(char*,char*,int); + static void Help(void); + static void FadeIn(void); + static void FadeOut(void); + static BOOL SaveBitmap(char*,int,int); + + #ifdef NEWCODE + + static CLBKB SearchDriver(GUID FAR*,LPSTR,LPSTR,void*,HMONITOR); + + #else + + static CLBKB SearchDriver(GUID FAR*,LPSTR,LPSTR,LPVOID); + + #endif + + static void GetDC(void); + static void ReleaseDC(void); + static void GetColor(int,int,int*,int*,int*); + static void SpriteScreen(DDOBJ,int,int,int,int); + static void Pixel(int,int,COLORREF); + static void Line(int,int,int,int,COLORREF,int); + static void Box(int,int,int,int,COLORREF,COLORREF,int); + static void Bezier(POINT*,int,COLORREF,int); + + #ifdef MENU + + static void Menu(void); + + #endif + + static BOOL ErrorCheck; + + static ULONG FpsTime; + static int FpsCnt; + static float FpsData; + static float FpsDataMin; + static float FpsDataMax; + + static int Width; + static int Height; + + static DDOBJ MaskBMP; + + static BOOL HelpOn; + static DDOBJ HelpBMP[]; + static int HelpSize; + static float HelpY; + static float HelpBackX; + static float HelpBackY; + + static int FadeType; + static int FadeNo; + static int FadeAdd; + static int FadeMax; + + static int ColorBit; + static int RetryColorBit1; + static int RetryColorBit2; + + static int Vx1,Vy1,Vx2,Vy2; + + static BOOL WipeIn; + static BOOL WipeOut; + + static int EffectOn; + static int EffectInOut; + static int EffectType; + static float EffectSpeed; + static int EffectSize; + + static int Wx1,Wy1,Wx2,Wy2; + + static COLORREF SpriteColor; + static BOOL SpriteLeftTop; + + static int RotateData[]; + + static BOOL SearchVideoCard; + + static DWORD MaskR,MaskG,MaskB,MaskRGB; + static DWORD WhiteRGB,MaskRGB2; + static DWORD BitR,BitG,BitB; + static WORD ShiftR,ShiftG,ShiftB; + static WORD ShiftR2,ShiftG2,ShiftB2; + + static BOOL UseStretch; + + static RECT RefreshSize; + static RECT RefreshPos; + static BOOL RefreshMode; + + static unsigned short BlendList[]; + static unsigned short AddBlendList[]; + static unsigned short DelBlendList[]; + static unsigned short GrayList[]; + + static char PackFileName[]; + + #ifdef NEWCODE + + static char VideoCardName[]; + + #endif + + static int TunnelSpriteX; + static int TunnelSpriteY; + static int TunnelDisplayX; + static int TunnelDisplayY; + + struct _tunnellist + { + short x; + short y; + }; + + struct _getrgb + { + BYTE r; + BYTE g; + BYTE b; + }; + + struct _sprite + { + LPDIRECTDRAWSURFACE Object; // スプライトデータ + char FileName[31]; // ファイル名またはリソース名 + BOOL PackData; // パックファイルデータ + int Memory; // メモリ格納タイプ + COLORREF Color; // 透明色 + WORD SizeX,SizeY; // サイズ + }; +}; + +// エラーチェックフラグ +BOOL elDraw::ErrorCheck; + +// FPS計算 +ULONG elDraw::FpsTime=timeGetTime(); +int elDraw::FpsCnt=0; +float elDraw::FpsData=F(0); +float elDraw::FpsDataMin=F(999.9); +float elDraw::FpsDataMax=F(0); + +// 実画面サイズ +int elDraw::Width=0; +int elDraw::Height=0; + +// マスク +DDOBJ elDraw::MaskBMP; + +// ヘルプ +BOOL elDraw::HelpOn=FALSE; +DDOBJ elDraw::HelpBMP[2]; +int elDraw::HelpSize=0; +float elDraw::HelpY=F(0); +float elDraw::HelpBackX=F(0); +float elDraw::HelpBackY=F(0); + +// フェイド +int elDraw::FadeType=FADE_MASK; +int elDraw::FadeNo=0; +int elDraw::FadeAdd=0; +int elDraw::FadeMax=0; + +// カラービット数 +int elDraw::ColorBit=16; +int elDraw::RetryColorBit1=0; +int elDraw::RetryColorBit2=0; + +// 仮想画面サイズ +int elDraw::Vx1; +int elDraw::Vy1; +int elDraw::Vx2; +int elDraw::Vy2; + +// ワイプ +BOOL elDraw::WipeIn=FALSE; +BOOL elDraw::WipeOut=FALSE; +int elDraw::EffectOn=0; +int elDraw::EffectInOut; +int elDraw::EffectType; +float elDraw::EffectSpeed; +int elDraw::EffectSize; +int elDraw::Wx1; +int elDraw::Wy1; +int elDraw::Wx2; +int elDraw::Wy2; + +// スプライト透明色 +COLORREF elDraw::SpriteColor=RGB(0,0,0); +BOOL elDraw::SpriteLeftTop=FALSE; + +// 回転情報 +int elDraw::RotateData[450]; + +// ビデオカードの検索結果 +BOOL elDraw::SearchVideoCard; + +// ピクセル情報 +DWORD elDraw::MaskR; +DWORD elDraw::MaskG; +DWORD elDraw::MaskB; +DWORD elDraw::MaskRGB; +DWORD elDraw::MaskRGB2; +DWORD elDraw::WhiteRGB; +DWORD elDraw::BitR; +DWORD elDraw::BitG; +DWORD elDraw::BitB; +WORD elDraw::ShiftR; +WORD elDraw::ShiftG; +WORD elDraw::ShiftB; +WORD elDraw::ShiftR2; +WORD elDraw::ShiftG2; +WORD elDraw::ShiftB2; + +// DirectDrawの機能使用フラグ +BOOL elDraw::UseStretch; // 拡大縮小 + +// ウィンドウ表示でのリフレッシュ位置とサイズ +RECT elDraw::RefreshSize; +RECT elDraw::RefreshPos; + +// 垂直帰線期間待ちフラグ +BOOL elDraw::RefreshMode=TRUE; + +// リスト情報 +unsigned short elDraw::BlendList[3*32*32*32]; +unsigned short elDraw::AddBlendList[3*32*32*32]; +unsigned short elDraw::DelBlendList[3*32*32]; +unsigned short elDraw::GrayList[32+32+32]; +struct elDraw::_tunnellist TunnelList[640*480]; +struct elDraw::_getrgb GetRGB[65536]; + +// パックファイル名 +char elDraw::PackFileName[256]=""; + +// ビデオカードの名称 +#ifdef NEWCODE + +char elDraw::VideoCardName[128]="不明"; + +#endif + +// トンネル情報 +int elDraw::TunnelSpriteX; +int elDraw::TunnelSpriteY; +int elDraw::TunnelDisplayX; +int elDraw::TunnelDisplayY; + +// スプライト情報 +struct elDraw::_sprite Sprite[SPRITE_MAX]; + +/*==============================================================================*/ +/*= =*/ +/*= エフェクトクラス宣言 ( elEffect ) =*/ +/*= =*/ +/*==============================================================================*/ + +// クラス定義 +class elEffect +{ + public: + + static BOOL Fire(int,int,UINT,UINT); + static BOOL Fire(BOOL,BOOL,BOOL,int,int,UINT,UINT); + static BOOL Shade(int,int,UINT,UINT); + static BOOL Shade(BOOL,BOOL,BOOL,int,int,UINT,UINT); + static BOOL Zoom2(int,int,UINT,UINT,BOOL); + static BOOL Zoom4(int,int,UINT,UINT,BOOL); + static BOOL Mosaic(int,int,int,int); + static BOOL Noise(int,int,int,UINT,UINT); + static BOOL Noise(BOOL,BOOL,BOOL,int,int,int,UINT,UINT); + + static char FireRandomList[]; +}; + +// Fire関数用ランダムリスト +char elEffect::FireRandomList[10000]; + +/*==============================================================================*/ +/*= =*/ +/*= サウンドクラス宣言 ( elSound ) =*/ +/*= =*/ +/*==============================================================================*/ + +// 最大値定義 +static const int SOUND_MAX=70; // サウンド数 +static const int MIX_MAX=10; // 同音ミックス数 +static const DWORD SOUND_STREAM_TIME=4; // ストリーム時間 + +// DirectSound制御 +static LPDIRECTSOUND DSObject=NULL; +static LPDIRECTSOUNDBUFFER DSBuff1=NULL; +static LPDIRECTSOUNDBUFFER DSBuff2[SOUND_MAX][MIX_MAX]; + +// 次に再生されるミックスNoの指定 +static const int NEXT_MIX=-2; + +// エフェクトの使用 +static const int USE_EFFECT=-2; + +// クラス定義 +class elSound +{ + public: + + static BOOL Init(void); + static void DestroyObject(void); + static DSOBJ LoadObject(char*,int); + static void ReloadObject(void); + static void FreeObject(DSOBJ); + static void SetPack(char*); + static DSOBJ LoadPack(char*,int); + static DSOBJ LoadStream(char*,DWORD); + static BOOL Streaming(void); + static BOOL ResetStream(DSOBJ); + static BOOL Convert(char*,char*,BOOL); + static void ConvertFile(char*,char*); + static void Play(DSOBJ,int); + static void Loop(DSOBJ,int); + static void Stop(DSOBJ,int); + static void Pause(DSOBJ,int); + static void Pitch(DSOBJ,int,int); + static void InitPitch(DSOBJ,int); + static void SetPitch(DSOBJ,int,int); + static void Pan(DSOBJ,int,int); + static void InitPan(DSOBJ,int); + static void SetPan(DSOBJ,int,int); + static void LeftPan(DSOBJ,int); + static void RightPan(DSOBJ,int); + static void Volume(DSOBJ,int,int); + static void InitVolume(DSOBJ,int); + static void SetVolume(DSOBJ,int,int); + static void Delay(DSOBJ,int,int,int); + static void Chorus(DSOBJ,int,int,int,int); + static void Beep(void); + static void PlayFile(char*); + static BOOL SearchFile(char*,WAVEFORMATEX**,UINT*,BYTE**,UINT*); + static BOOL SelectFormat(int,int,int); + static DWORD GetPos(DSOBJ); + + static int ListNo; + static BOOL ListUse[]; + static int ListMix[]; + static int ListUseMix[]; + static long ListVolume[][MIX_MAX]; + static ULONG ListPitch[][MIX_MAX]; + static ULONG ListPitchDef[]; + static long ListPan[][MIX_MAX]; + static char ListName[][31]; + static int ListEffectCount[]; + static float ListEffectTime[]; + static float ListEffectPos[]; + static int ListEffectDir[]; + static BOOL ListEffectLoop[]; + static DWORD ListPosition[][MIX_MAX]; + static BOOL ListLoop[]; + static BOOL ListPack[]; + + static char PackFileName[]; + + static BOOL Reload; + static BOOL Ok; + + struct _soundstream + { + DWORD StartPos; // ファイルの先頭シーク位置 + DWORD LoopPos; // ファイルのループシーク位置 + DWORD SeekPos; // ファイルのシーク位置 + DWORD DataSize; // 全体のデータサイズ + DWORD ReadData; // 読み込んだデータサイズ + DWORD WriteCheck; // 次のデータ書き込み用のチェック位置 + DWORD NextWrite; // 次のデータ書き込み位置 + DWORD WriteSize; // 書き込むデータサイズ + DWORD WriteMax; // 書き込み先の最大データサイズ + DWORD PlayPos; // 前回の処理での再生位置 + DWORD LastPos; // 直前フレームでの再生位置 + BYTE NextStop; // 次の判定での停止フラグ + char PackName[256]; // パックファイル名 + }; +}; + +// オブジェクト定義 +int elSound::ListNo; +BOOL elSound::ListUse[SOUND_MAX]; +int elSound::ListMix[SOUND_MAX]; +int elSound::ListUseMix[SOUND_MAX]; +long elSound::ListVolume[SOUND_MAX][MIX_MAX]; +ULONG elSound::ListPitch[SOUND_MAX][MIX_MAX]; +ULONG elSound::ListPitchDef[SOUND_MAX]; +long elSound::ListPan[SOUND_MAX][MIX_MAX]; +char elSound::ListName[SOUND_MAX][31]; +int elSound::ListEffectCount[SOUND_MAX]; +float elSound::ListEffectTime[SOUND_MAX]; +float elSound::ListEffectPos[SOUND_MAX]; +int elSound::ListEffectDir[SOUND_MAX]; +BOOL elSound::ListEffectLoop[SOUND_MAX]; +DWORD elSound::ListPosition[SOUND_MAX][MIX_MAX]; +BOOL elSound::ListLoop[SOUND_MAX]; +BOOL elSound::ListPack[SOUND_MAX]; + +// パックファイル名 +char elSound::PackFileName[256]=""; + +// リソースからの再読み込みフラグ +BOOL elSound::Reload; + +// DirectSound使用可能フラグ +BOOL elSound::Ok; + +// サウンドストリーミング情報 +struct elSound::_soundstream SoundStream[SOUND_MAX]; + +/*==============================================================================*/ +/*= =*/ +/*= ミュージッククラス宣言 ( elMusic ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef DIRECTMUSIC + +// 最大値定義 +static const int PORT_MAX=16; // MIDI出力ポート数 +static const int MUSIC_MAX=128; // ミュージック数 + +// elSoundクラス用 +static const DSOBJ DIRECT_MUSIC=0; + +// DirectMusic出力ポート +static const int DIRECTMUSIC_PORT=-1; + +// DirectMusic制御 +static IDirectMusic* DMMusic=NULL; +static IDirectMusicPerformance* DMPerformance=NULL; +static IDirectMusicLoader* DMLoader=NULL; +static IDirectMusicSegmentState* DMState=NULL; +static IDirectMusicSegment* DMSegment=NULL; +static IDirectMusicPort* DMPort=NULL; + +#endif + +// クラス定義 +class elMusic +{ + public: + + static BOOL Init(void); + static void DestroyObject(void); + static void Play(char*,BOOL); + static void Replay(void); + static void Stop(void); + static void NoLoop(void); + + #ifdef DIRECTMUSIC + + static void Pitch(int); + static void InitPitch(void); + static void SetPitch(int); + static void Pan(int); + static void InitPan(void); + static void SetPan(int); + static void LeftPan(void); + static void RightPan(void); + static void Volume(int); + static void InitVolume(void); + static void SetVolume(int); + static BOOL SelectPort(int,int,int,int,BOOL); + static void Reverb(BOOL); + static DMOBJ LoadObject(char*); + static void FreeObject(DMOBJ); + static void Play(DMOBJ,BOOL); + static void Stop(DMOBJ); + + #endif + + static BOOL PlayMusic; + static BOOL LoopMusic; + static BOOL LoopMode; + + #ifdef DIRECTMUSIC + + static BOOL UseDirectMusic; + static BOOL InitDirectMusic; + static int MaxPort; + static int DirectMusicPort; + static DMUS_PORTCAPS* Port[]; + static char PortName[][32]; + static int PortNo; + static int Channel; + static int Rate; + static int Bit; + static DWORD ChannelGroup; + + struct _music + { + IDirectMusicPerformance* Performance; // パフォーマンス + IDirectMusicSegment* Segment; // セグメント + }; + + #endif +}; + +// 再生状態 +BOOL elMusic::PlayMusic; +BOOL elMusic::LoopMusic; + +// ループ再生フラグ +BOOL elMusic::LoopMode; + +#ifdef DIRECTMUSIC + +// DirectMusic使用フラグ +BOOL elMusic::UseDirectMusic; + +// DirectMusic初期化完了フラグ +BOOL elMusic::InitDirectMusic; + +// MIDI出力ポートデータ +int elMusic::MaxPort; +int elMusic::DirectMusicPort; +DMUS_PORTCAPS* elMusic::Port[PORT_MAX]; +char elMusic::PortName[PORT_MAX][32]; + +// MIDI出力ポートパラメーター +int elMusic::PortNo; +int elMusic::Channel; +int elMusic::Rate; +int elMusic::Bit; + +// チャンネルグループ数 +DWORD elMusic::ChannelGroup; + +// ミュージック情報 +struct elMusic::_music Music[MUSIC_MAX]; + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= CDクラス宣言 ( elCD ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef CDDA + +// 最大値定義 +static const int CD_MAX=99+1; // 曲数 + +// クラス定義 +class elCD +{ + public: + + static void Init(void); + static void GetInfo(void); + static void Play(void); + static void Play(int); + static void Play(int,int); + static void Play(int,int,int,int,int,int); + static void Replay(void); + static void Stop(void); + static void Pause(BOOL); + static void Skip(int); + static void Forward(int); + static void Backward(int); + static BOOL Ready(void); + static void Open(void); + static void Close(void); + static void NoLoop(void); + static int MaxSong(void); + static int NowSong(void); + + static BOOL PlayCD; + static BOOL LoopCD; + static BOOL LoopMode; + + static int PauseM; + static int PauseS; + static int PauseF; + + static int StartSongNo; + static int EndSongNo; + + static int SongMax; + + // CD情報 + struct _cdinfo + { + // 曲の開始時間 + struct start + { + int m,s,f; // 分・秒・フレーム + } + Start; + + // 曲の時間 + struct time + { + int m,s,f; // 分・秒・フレーム + } + Time; + }; +}; + +// 再生状態 +BOOL elCD::PlayCD; +BOOL elCD::LoopCD; + +// ループ再生フラグ +BOOL elCD::LoopMode; + +// 一時停止状態での時間 +int elCD::PauseM; +int elCD::PauseS; +int elCD::PauseF; + +// 開始曲番号と終了曲番号 +int elCD::StartSongNo; +int elCD::EndSongNo; + +// 曲の数 +int elCD::SongMax; + +// CD情報 ( 0:CD全体 / 1〜:曲 ) +elCD::_cdinfo CDInfo[CD_MAX]; + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= 3Dクラス宣言 ( el3D ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef DIRECT3D + +// 最大値定義 +static const int MODEL_MAX=256; // モデル数 +static const int CAMERA_MAX=4; // カメラ数 +static const int LIGHT_MAX=3+1; // ライト数 + +// Direct3D制御 +static LPDIRECT3D D3=NULL; +static LPDIRECT3DDEVICE D3Device=NULL; +static LPDIRECT3DRM D3RM=NULL; +static LPDIRECT3DRMDEVICE D3RMDevice=NULL; +static LPDIRECT3DRMVIEWPORT D3RMViewport[CAMERA_MAX]; +static LPDIRECT3DRMMESHBUILDER D3RMBuilder=NULL; +static LPDIRECT3DRMMATERIAL D3RMMaterial=NULL; +static LPDIRECT3DRMMESH D3RMMesh=NULL; +static LPDIRECT3DRMWRAP D3RMWrap=NULL; +static LPDIRECT3DRMFRAME D3RMScene=NULL; +static LPDIRECT3DRMFRAME D3RMCamera[CAMERA_MAX]; +static LPDIRECT3DRMFRAME D3RMLight[LIGHT_MAX]; +static LPDIRECT3DRMLIGHT D3RMLightType[LIGHT_MAX]; +static LPDIRECT3DRMVISUAL D3RMShadow=NULL; + +// クラス定義 +class el3D +{ + public: + + static BOOL GetConfig(void); + static BOOL Init(void); + static CLBKH SearchDriver(LPGUID,LPSTR,LPSTR,LPD3DDEVICEDESC, + LPD3DDEVICEDESC,LPVOID); + static D3OBJ LoadObject(char*,int,D3OBJ*); + static D3OBJ CreateObject(void); + static void FreeObject(D3OBJ*); + static void DestroyObject(void); + static D3TXR LoadTexture(char*); + static void FreeTexture(D3TXR*); + static void SwapTexture(char*,D3TXR*); + static void SetWireShade(void); + static void SetFlatShade(void); + static void SetNoLightShade(void); + static void SetColor(float,float,float); + static void SetScale(float); + static void SetTexture(D3TXR,BOOL,BOOL,int,int); + static void SetTransparentTexture(D3TXR,D3DCOLOR); + static void SetTransparentTexture(D3TXR); + static void SetShadow(int); + static void SetLink(D3OBJ); + static void SetChange(void); + static void ChangeColor(D3OBJ,float,float,float); + static void ChangeTexture(D3OBJ,D3TXR); + static void ChangeTextureBright(D3OBJ,float); + static void ClearTexture(D3OBJ); + static void Rendering(void); + static void ShowPPF(void); + static long CountPolygon(void); + static void CreateScene(float,float,float); + static void CreateAmbient(float); + static BOOL CreateLight(int,float,int); + static BOOL CreateCamera(int,int,int,int,int); + static void ClipCamera(int,float,float); + static void ResizeCamera(int,int,int,int,int,BOOL); + static void SwapDrawCamera(int,int); + + static void InitCamera(float,float); + static BOOL UpdateCamera(void); + static BOOL ThroughCamera(void); + static void StopCamera(void); + static void StopMoveCamera(void); + static void StopRotateCamera(void); + static void MoveCameraX(int); + static void MoveCameraY(int); + static void MoveCameraZ(int); + static void RotateCameraX(int); + static void RotateCameraY(int); + static void RotateCameraZ(int); + static void BrakeMoveCameraX(void); + static void BrakeMoveCameraY(void); + static void BrakeMoveCameraZ(void); + static void BrakeRotateCameraX(void); + static void BrakeRotateCameraY(void); + static void BrakeRotateCameraZ(void); + static void DirectMoveCamera(int,float,float,float); + static void DirectMoveCameraX(int,float); + static void DirectMoveCameraY(int,float); + static void DirectMoveCameraZ(int,float); + static void DirectRotateCamera(int,float,float,float); + static void DirectRotate360Camera(int,float,float,float,float); + static void DirectRotate360CameraX(int,float); + static void DirectRotate360CameraY(int,float); + static void DirectRotate360CameraZ(int,float); + static void LookAtCamera(D3OBJ); + static void DirectLookAtCamera(int,D3OBJ); + static void ShowCamera(int); + static void HideCamera(int,BOOL); + static void SearchCamera(D3OBJ,float,float,float); + static void DirectSearchCamera(int,D3OBJ,float,float,float); + static void Search360Camera(D3OBJ,float,float,float); + static void DirectSearch360Camera(int,D3OBJ,float,float,float); + + static void InitModel(float,float,float,float); + static BOOL UpdateModel(D3OBJ); + static BOOL ThroughModel(void); + static void StopModel(void); + static void StopAllModel(void); + static void StopMoveModel(void); + static void StopRotateModel(void); + static void MoveModelX(int); + static void MoveModelY(int); + static void MoveModelZ(int); + static void RotateModelX(int); + static void RotateModelY(int); + static void RotateModelZ(int); + static void BrakeMoveModelX(void); + static void BrakeMoveModelY(void); + static void BrakeMoveModelZ(void); + static void BrakeRotateModelX(void); + static void BrakeRotateModelY(void); + static void BrakeRotateModelZ(void); + static void CopyMoveModel(void); + static void PasteMoveModel(void); + static void RandomMoveModel(int); + static void ReverseMoveModel(void); + static void DirectMoveModel(D3OBJ,float,float,float); + static void DirectMoveModelX(D3OBJ,float); + static void DirectMoveModelY(D3OBJ,float); + static void DirectMoveModelZ(D3OBJ,float); + static void DirectRotateModel(D3OBJ,float,float,float); + static void DirectRotate360Model(D3OBJ,float,float,float,float); + static void DirectRotate360ModelX(D3OBJ,float); + static void DirectRotate360ModelY(D3OBJ,float); + static void DirectRotate360ModelZ(D3OBJ,float); + static void LookAtModel(D3OBJ,D3OBJ); + static void ShowModel(D3OBJ); + static void ShowLinkModel(D3OBJ,D3OBJ); + static void HideModel(D3OBJ); + static void HideLinkModel(D3OBJ,D3OBJ); + static float DistanceZeroModel(D3OBJ); + static float DistanceModel(D3OBJ,D3OBJ); + static void FollowModel(D3OBJ,D3OBJ); + static void GetMoveModelX(float*,int*); + static void GetMoveModelY(float*,int*); + static void GetMoveModelZ(float*,int*); + static void GetScreenPositionModel(D3OBJ,int,int*,int*,float*); + static D3OBJ GetLinkModel(D3OBJ); + static int SearchLinkModel(int,int,int,D3OBJ,D3OBJ); + + static void DirectMoveLight(int,float,float,float); + static void ShowLight(int); + static void HideLight(int); + static void SetAutoLight(int,float,float,float); + static void AutoLight(int); + static void FollowLight(D3OBJ,int); + + static int ModelNo; + static int CameraNo; + + static BOOL UseCamera[]; + static int CameraX1[],CameraY1[]; + static int CameraX2[],CameraY2[]; + + static ULONG DrawPolygon; + static ULONG LastDrawPolygon; + + static BOOL Search3DVideoCard; + static LPGUID UseDriver; + static D3DCOLORMODEL DriverType; + static int ZBufferSize; + static DWORD ZBufferMemory; + static BOOL HEL; + static UINT Mode; + + static float CameraMx[],CameraMy[],CameraMz[]; + static float CameraMxs[],CameraMys[],CameraMzs[]; + static int CameraMxf[],CameraMyf[],CameraMzf[]; + static float CameraMoveSpeed[]; + static float CameraRx[],CameraRy[],CameraRz[]; + static float CameraRxs[],CameraRys[],CameraRzs[]; + static int CameraRxf[],CameraRyf[],CameraRzf[]; + static float CameraRotateSpeed[]; + + static float ModelMx[],ModelMy[],ModelMz[]; + static float ModelMxs[],ModelMys[],ModelMzs[]; + static int ModelMxf[],ModelMyf[],ModelMzf[]; + static float ModelMoveSpeed[],ModelMoveMaxSpeed[]; + static float ModelRx[],ModelRy[],ModelRz[]; + static float ModelRxs[],ModelRys[],ModelRzs[]; + static int ModelRxf[],ModelRyf[],ModelRzf[]; + static float ModelRotateSpeed[],ModelRotateMaxSpeed[]; + + static float LightMx[],LightMy[],LightMz[]; + static float LightMxp[],LightMyp[],LightMzp[]; + + static float CopyModelMx,CopyModelMy,CopyModelMz; + static float CopyModelMxs,CopyModelMys,CopyModelMzs; + static int CopyModelMxf,CopyModelMyf,CopyModelMzf; + + static BOOL DefaultWireShade; + static BOOL DefaultFlatShade; + static BOOL DefaultNoLightShade; + static BOOL DefaultColor; + static float DefaultColorRed; + static float DefaultColorGreen; + static float DefaultColorBlue; + static float DefaultScale; + static D3TXR DefaultTexture; + static BOOL DefaultTextureQuality; + static BOOL DefaultTextureBall; + static int DefaultTextureCountX; + static int DefaultTextureCountY; + static int DefaultShadow; + static D3OBJ DefaultLink; + static BOOL DefaultChange; + + struct _lightdata + { + int x,y,z; + }; +}; + +// オブジェクト定義 +int el3D::ModelNo=0; +int el3D::CameraNo=0; + +// カメラ情報 +BOOL el3D::UseCamera[CAMERA_MAX]; +int el3D::CameraX1[CAMERA_MAX]; +int el3D::CameraY1[CAMERA_MAX]; +int el3D::CameraX2[CAMERA_MAX]; +int el3D::CameraY2[CAMERA_MAX]; + +// PPF計算 +ULONG el3D::DrawPolygon; +ULONG el3D::LastDrawPolygon=0; + +// 3Dドライバー +BOOL el3D::Search3DVideoCard=FALSE; +LPGUID el3D::UseDriver; +D3DCOLORMODEL el3D::DriverType=D3DCOLOR_MONO; +int el3D::ZBufferSize; +DWORD el3D::ZBufferMemory; +BOOL el3D::HEL=FALSE; + +// 3D設定 +UINT el3D::Mode=0x0000; + +// カメラ情報 +float el3D::CameraMx[CAMERA_MAX]; +float el3D::CameraMy[CAMERA_MAX]; +float el3D::CameraMz[CAMERA_MAX]; +float el3D::CameraMxs[CAMERA_MAX]; +float el3D::CameraMys[CAMERA_MAX]; +float el3D::CameraMzs[CAMERA_MAX]; +int el3D::CameraMxf[CAMERA_MAX]; +int el3D::CameraMyf[CAMERA_MAX]; +int el3D::CameraMzf[CAMERA_MAX]; +float el3D::CameraMoveSpeed[CAMERA_MAX]; +float el3D::CameraRx[CAMERA_MAX]; +float el3D::CameraRy[CAMERA_MAX]; +float el3D::CameraRz[CAMERA_MAX]; +float el3D::CameraRxs[CAMERA_MAX]; +float el3D::CameraRys[CAMERA_MAX]; +float el3D::CameraRzs[CAMERA_MAX]; +int el3D::CameraRxf[CAMERA_MAX]; +int el3D::CameraRyf[CAMERA_MAX]; +int el3D::CameraRzf[CAMERA_MAX]; +float el3D::CameraRotateSpeed[CAMERA_MAX]; + +// モデル情報 +float el3D::ModelMx[MODEL_MAX]; +float el3D::ModelMy[MODEL_MAX]; +float el3D::ModelMz[MODEL_MAX]; +float el3D::ModelMxs[MODEL_MAX]; +float el3D::ModelMys[MODEL_MAX]; +float el3D::ModelMzs[MODEL_MAX]; +int el3D::ModelMxf[MODEL_MAX]; +int el3D::ModelMyf[MODEL_MAX]; +int el3D::ModelMzf[MODEL_MAX]; +float el3D::ModelMoveSpeed[MODEL_MAX]; +float el3D::ModelMoveMaxSpeed[MODEL_MAX]; +float el3D::ModelRx[MODEL_MAX]; +float el3D::ModelRy[MODEL_MAX]; +float el3D::ModelRz[MODEL_MAX]; +float el3D::ModelRxs[MODEL_MAX]; +float el3D::ModelRys[MODEL_MAX]; +float el3D::ModelRzs[MODEL_MAX]; +int el3D::ModelRxf[MODEL_MAX]; +int el3D::ModelRyf[MODEL_MAX]; +int el3D::ModelRzf[MODEL_MAX]; +float el3D::ModelRotateSpeed[MODEL_MAX]; +float el3D::ModelRotateMaxSpeed[MODEL_MAX]; + +// ライト情報 +float el3D::LightMx[LIGHT_MAX]; +float el3D::LightMy[LIGHT_MAX]; +float el3D::LightMz[LIGHT_MAX]; +float el3D::LightMxp[LIGHT_MAX]; +float el3D::LightMyp[LIGHT_MAX]; +float el3D::LightMzp[LIGHT_MAX]; + +// モデル複写情報 +float el3D::CopyModelMx; +float el3D::CopyModelMy; +float el3D::CopyModelMz; +float el3D::CopyModelMxs; +float el3D::CopyModelMys; +float el3D::CopyModelMzs; +int el3D::CopyModelMxf; +int el3D::CopyModelMyf; +int el3D::CopyModelMzf; + +// オブジェクト情報 +BOOL el3D::DefaultWireShade=FALSE; +BOOL el3D::DefaultFlatShade=FALSE; +BOOL el3D::DefaultNoLightShade=FALSE; +BOOL el3D::DefaultColor=FALSE; +float el3D::DefaultColorRed; +float el3D::DefaultColorGreen; +float el3D::DefaultColorBlue; +float el3D::DefaultScale=F(-999); +D3TXR el3D::DefaultTexture=NULL; +BOOL el3D::DefaultTextureQuality; +BOOL el3D::DefaultTextureBall; +int el3D::DefaultTextureCountX; +int el3D::DefaultTextureCountY; +int el3D::DefaultShadow; +D3OBJ el3D::DefaultLink=NULL; +BOOL el3D::DefaultChange=FALSE; + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= 4Dクラス宣言 ( el4D ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef DIRECT3D_IM + +// Direct3D IM制御 +LPDIRECT3D7 D3=NULL; +LPDIRECT3DDEVICE7 D3Device=NULL; +LPDIRECTDRAWSURFACE7 D3ZBuffer=NULL; + +// 最大値定義 +const int POLYOBJ_MAX =1024; // ポリゴンオブジェクト数 +const int LIGHTOBJ_MAX=1024; // ライトオブジェクト数 +const int TEXTURE_MAX = 16; // テクスチャーフォーマット数 +const int XFILE_MAX =1024; // Xファイルオブジェクト数 +const int MULTI_MAX= 4; // マルチマテリアル数 + +#ifdef NO_SUBPOLYGON + const int SUBPOLY_MAX=1; // サブポリゴンオブジェクトは未使用 +#else + const int SUBPOLY_MAX=128; // サブポリゴンオブジェクト数 +#endif + +// カメラオブジェクト +const int CAMERA_OBJECT=0; + +// ポリゴンオブジェクトタイプ +const int POLYOBJ_CAMERA=0xFFFF+1; // カメラ +const int POLYOBJ_FRAME =0xFFFF+2; // フレーム + +// Config::Driver変数用 +const WORD DC4D_OK =0x0001; // ドライバー有効 +const WORD DC4D_HAL=0x0002; // HAL有効 +const WORD DC4D_TNL=0x0004; // TnL有効 + +// Config::Texture変数用 +const WORD DC4D_2POWERS =0x0001; // 幅と高さに2の累乗を要求 +const WORD DC4D_SQUAREONLY=0x0002; // 正方形を要求 + +// Config::User変数用 ( Config関数用 ) +const WORD DC4D_USEHEL =0x0001; // HELを要求 +const WORD DC4D_USERR =0x0002; // リファレンスラスタライザーを要求 +const WORD DC4D_BITEQUAL=0x0004; // カラーとZに同じビット数を要求 +const WORD DC4D_NOTNL =0x0008; // TnLを使わないHALを要求 + +// 頂点バッファタイプ ( Object::SelectMemory関数用 ) +const WORD MEM_AUTO =0x0001; // 自動 +const WORD MEM_RAM =0x0002; // RAM +const WORD MEM_RENDER=0x0004; // レンダリング速度優先 + +// ライトタイプ ( Light::Create関数用 ) +const int LIGHT_DIR =1; // 方位光源 +const int LIGHT_SPOT =2; // スポットライト +const int LIGHT_POINT=3; // 点光源 + +// フィルタータイプ ( Texture::Filter関数用 ) +const int FILTER_NONE =1; // フィルターなし +const int FILTER_LINEAR=2; // リニア + +// Zバッファ比較タイプ ( State::CheckZ関数用 ) +const int Z_NOCHECK =0; // 比較なし +const int Z_DEFAULT =D3DCMP_LESSEQUAL; // デフォルト +const int Z_EQUAL =D3DCMP_EQUAL; // 等しい +const int Z_NOTEQUAL =D3DCMP_NOTEQUAL; // 等しくない +const int Z_LESS =D3DCMP_LESS; // 小さい +const int Z_LESSEQUAL =D3DCMP_LESSEQUAL; // 以下 +const int Z_GREATER =D3DCMP_GREATER; // 大きい +const int Z_GREATEREQUAL=D3DCMP_GREATEREQUAL; // 以上 + +// アルファブレンドタイプ ( State::Alpha関数用 ) +const int ALPHA_NONE =1; // アルファブレンドなし +const int ALPHA_NORMAL =2; // 通常 +const int ALPHA_ADD =3; // 加算 +const int ALPHA_DELETE =4; // 減算 +const int ALPHA_REVERSE=5; // 反転 ( アルファ値無効 ) +const int ALPHA_BRIGHT =6; // 明度 + +// アルファビット比較タイプ ( State::CheckAlpha関数用 ) +const int ALPHA_DEFAULT =D3DCMP_GREATEREQUAL; // デフォルト +const int ALPHA_EQUAL =D3DCMP_EQUAL; // 等しい +const int ALPHA_NOTEQUAL =D3DCMP_NOTEQUAL; // 等しくない +const int ALPHA_LESS =D3DCMP_LESS; // 小さい +const int ALPHA_LESSEQUAL =D3DCMP_LESSEQUAL; // 以下 +const int ALPHA_GREATER =D3DCMP_GREATER; // 大きい +const int ALPHA_GREATEREQUAL=D3DCMP_GREATEREQUAL; // 以上 + +// 有効になるアルファタイプ ( State::UseAlpha関数用 ) +const int USE_TEXTURE =1; // テクスチャー側 +const int USE_MATERIAL=2; // マテリアル側 + +// シェードタイプ ( State::Shade関数用 ) +const int SHADE_GOURAUD =1; // グーロー +const int SHADE_FLAT =2; // フラット +const int SHADE_WIREFRAME=3; // ワイヤーフレーム +const int SHADE_POINT =4; // ポイント + +// テクスチャー反転タイプ ( Flat::ReverseUv関数用 ) +const int UV_NORMAL=1; // 反転なし +const int UV_X =2; // X方向に反転 +const int UV_Y =3; // Y方向に反転 +const int UV_XY =4; // XY方向に反転 + +// テクスチャー反転タイプ ( Texture::Load関数用 ) +const int LOAD_ALPHA=1; // アルファ付きテクスチャー + +// ポリゴンオブジェクトから頂点データを読み込み ( Lock/Unlock内で使用 ) +#define GET_POLYOBJ(ObjD4,No,Member)\ + \ + (PolyObj[ObjD4].Vertex+No)->Member + +#define GET_POLYOBJ_L(ObjD4,No,Member)\ + \ + (PolyObj[ObjD4].VertexL+No)->Member + +#define GET_POLYOBJ_TL(ObjD4,No,Member)\ + \ + (PolyObj[ObjD4].VertexTL+No)->Member + +// ポリゴンオブジェクトに頂点データを書き込み ( Lock/Unlock内で使用 ) +#define SET_POLYOBJ(ObjD4,No,Member,Data)\ + \ + (PolyObj[ObjD4].Vertex+No)->Member=Data; + +#define SET_POLYOBJ_L(ObjD4,No,Member,Data)\ + \ + (PolyObj[ObjD4].VertexL+No)->Member=Data; + +#define SET_POLYOBJ_TL(ObjD4,No,Member,Data)\ + \ + (PolyObj[ObjD4].VertexTL+No)->Member=Data; + +// クラス定義 +class el4D +{ + public: + + static BOOL Init(void); + static void Config(WORD); + static void DestroyObject(void); + static CLBKH SearchDriver(LPSTR,LPSTR,D3DDEVICEDESC7*,void*); + static CLBKH SearchZBuffer(DDPIXELFORMAT*,void*); + static CLBKH SearchTexture(DDPIXELFORMAT*,void*); + static BOOL Start(void); + static void End(void); + static BOOL Lock(D4OBJ,DWORD); + static void Unlock(D4OBJ); + static void InitMatrix(D4OBJ); + static void InitMatrix(D4MTX&); + static void ShowPPF(void); + static DWORD GetZ(int,int); + static void Clear(void); + static void Render(D4OBJ); + static void RenderX(D4OBJ); + static void RenderXList(D4OBJ); + static void RenderXList(void); + static void Target(D4TXR,float); + static void Target(void); + + // Renderクラス + class Render + { + public: + + static void Polygon(D4OBJ); + static void Polygon(D4OBJ,int); + static void SetTexture(D4TXR); + static void NoTexture(void); + static void SetMaterial(D4OBJ); + static void SetMaterial(D4OBJ,int); + static void Shadow(D4OBJ,D4OBJ,D4LGT,BYTE,float); + static void Reflect(D4OBJ,BYTE,float); + + // Xファイルリスト情報 + struct _xfile + { + D4OBJ Object; // ポリゴンオブジェクト + D4MTX Matrix; // マトリクス + }; + + static int XFileNo; + }; + + // Clearクラス + class Clear + { + public: + + static void Color(float,float,float); + static void Area(int,int,int,int); + static void Area(void); + static void View(BOOL); + static void Z(BOOL); + + static DWORD ClearType; + static D3DRECT ClearArea; + static LPD3DRECT ClearAreaPtr; + static DWORD ClearAreaCount; + static D3DCOLOR ClearColor; + }; + + // Objectクラス + class Object + { + public: + + static void Free(D4OBJ); + static D4OBJ Load(char*); + static BOOL CreateVertexBuffer(D4OBJ); + static void SelectMemory(WORD); + static void Move(D4OBJ,float,float,float); + static void MoveX(D4OBJ,float); + static void MoveY(D4OBJ,float); + static void MoveZ(D4OBJ,float); + static void Rotate(D4OBJ,float,float,float); + static void RotateX(D4OBJ,float); + static void RotateY(D4OBJ,float); + static void RotateZ(D4OBJ,float); + static void Scale(D4OBJ,float,float,float); + static void Scale(D4OBJ,float); + static void ScaleX(D4OBJ,float); + static void ScaleY(D4OBJ,float); + static void ScaleZ(D4OBJ,float); + static void StaticTransform(D4OBJ); + static void DynamicTransform(D4OBJ); + static void LoadMatrix(D4OBJ); + static void SetMatrix(D4OBJ,D4MTX&); + static D4MTX& GetMatrix(D4OBJ); + static void ForceVertex(D4OBJ); + static void AddUV(D4OBJ,float,float); + static void AddU(D4OBJ,float); + static void AddV(D4OBJ,float); + static BOOL GetScreenPosition(D4OBJ,int*,int*,float*,float*); + static BOOL GetScreenPosition(D4OBJ,float*,float*,float*,float*); + static void GetPosition(D4OBJ); + static void GetSize(D4OBJ); + static BOOL LookAt(D4OBJ,float,float,float,float,float,float); + static BOOL LookAtObject(D4OBJ,D4OBJ,float,float,float); + static void LookAtCamera(D4OBJ); + static void LookAtCameraX(D4OBJ); + static void LookAtCameraY(D4OBJ); + static void LookAtCameraZ(D4OBJ); + + // ポリゴンオブジェクト情報 + struct _polyobj + { + // レンダリング情報 + DWORD VertexType; // 頂点タイプ + LPDIRECT3DVERTEXBUFFER7 VertexBuffer; // 頂点バッファ + D3DVERTEX* Vertex; // 頂点データ + D3DLVERTEX* VertexL; //   〃 + D3DTLVERTEX* VertexTL; //   〃 + WORD* Index; //   〃 + int VertexCount; //   〃 + int IndexCount; //   〃 + D4MTX Matrix; // 変換用マトリクス + D4MTX ObjectMatrix; // 現在のマトリクス + float Px,Py,Pz; // 位置 ( ローカル ) + float Ax,Ay,Az; // 角度 ( ローカル ) + float Sx,Sy,Sz; // サイズ ( ローカル ) + D4TXR Texture; // テクスチャー + D3DMATERIAL7 Material; // マテリアル + int Lock; // 頂点バッファロック状態 + + // サブポリゴン関係 + int SubCount; // サブポリゴンオブジェクト数 + WORD* SubIndex[SUBPOLY_MAX]; // 頂点データ + int SubIndexCount[SUBPOLY_MAX]; //   〃 + D4TXR SubTexture[SUBPOLY_MAX]; // テクスチャー + D3DMATERIAL7 SubMaterial[SUBPOLY_MAX]; // マテリアル + + // マルチマテリアル関係 + float *Mu[MULTI_MAX],*Mv[MULTI_MAX]; // UV座標 + D4TXR Mt[MULTI_MAX][SUBPOLY_MAX+1]; // テクスチャー + D3DMATERIAL7 Mm[MULTI_MAX][SUBPOLY_MAX+1]; // マテリアル + + // Xファイル関係 + D4MTX XFileMatrix; // Xファイルのマトリクス + int Parent; // 親のオブジェクトNo + int Next; // 次のオブジェクトNo + int Prev; // 前のオブジェクトNo + BOOL Alpha; // アルファフラグ + + // el4D::Object::GetPosition関数により取得可能 + float PosX,PosY,PosZ; // 位置 ( ワールド ) + + // el4D::Object::GetSize関数により取得可能 + float MinX,MaxX; // 頂点の最小値と最大値 + float MinY,MaxY; //     〃 + float MinZ,MaxZ; //     〃 + + // el4D::Flatクラスで使用 + float PiPx,PiPy; // 位置 ( ピクセル ) + float PiSx,PiSy; // サイズ ( ピクセル ) + float R[4],G[4],B[4]; // RGB値 + float A[4]; // アルファ値 + float U[4],V[4]; // UV座標 + }; + }; + + // Primitiveクラス + class Primitive + { + public: + + static D4OBJ Triangle(float); + static D4OBJ Square(int,int,float,float,float,float); + static D4OBJ Cube(int,float,float,float,BYTE); + static D4OBJ ReverseCube(int,float,float,float,BYTE); + static D4OBJ Sphere(int,float,float,float,BOOL); + }; + + // Vertexクラス + class Vertex + { + public: + + static void Move(D4OBJ,int,float,float,float); + static void MoveX(D4OBJ,int,float); + static void MoveY(D4OBJ,int,float); + static void MoveZ(D4OBJ,int,float); + static int GetCount(D4OBJ); + static void Set(D4OBJ,int,float,float,float); + static void SetX(D4OBJ,int,float); + static void SetY(D4OBJ,int,float); + static void SetZ(D4OBJ,int,float); + static void Get(D4OBJ,int,float*,float*,float*); + static float GetX(D4OBJ,int); + static float GetY(D4OBJ,int); + static float GetZ(D4OBJ,int); + static void SetUV(D4OBJ,int,float,float); + static void SetU(D4OBJ,int,float); + static void SetV(D4OBJ,int,float); + static void GetUV(D4OBJ,int,float*,float*); + static float GetU(D4OBJ,int); + static float GetV(D4OBJ,int); + static void AddUV(D4OBJ,int,float,float); + static void AddU(D4OBJ,int,float); + static void AddV(D4OBJ,int,float); + static BOOL GetScreenPosition(D4OBJ,int,int*,int*,float*); + static void MMSave(D4OBJ,int); + static void MMSaveX(D4OBJ,int); + static void MMLoad(D4OBJ,int); + static void MMLoadX(D4OBJ,int); + }; + + // Transformクラス + class Transform + { + public: + + static void P(D4OBJ); + static void X(D4OBJ); + static void Y(D4OBJ); + static void Z(D4OBJ); + static void S(D4OBJ); + + static void Angle(D4OBJ); + + static void PX(D4OBJ); + static void PY(D4OBJ); + static void PZ(D4OBJ); + static void PS(D4OBJ); + static void XP(D4OBJ); + static void XY(D4OBJ); + static void XZ(D4OBJ); + static void XS(D4OBJ); + static void YP(D4OBJ); + static void YX(D4OBJ); + static void YZ(D4OBJ); + static void YS(D4OBJ); + static void ZP(D4OBJ); + static void ZX(D4OBJ); + static void ZY(D4OBJ); + static void ZS(D4OBJ); + static void SP(D4OBJ); + static void SX(D4OBJ); + static void SY(D4OBJ); + static void SZ(D4OBJ); + static void PXY(D4OBJ); + static void PXZ(D4OBJ); + static void PXS(D4OBJ); + static void PYX(D4OBJ); + static void PYZ(D4OBJ); + static void PYS(D4OBJ); + static void PZX(D4OBJ); + static void PZY(D4OBJ); + static void PZS(D4OBJ); + static void PSX(D4OBJ); + static void PSY(D4OBJ); + static void PSZ(D4OBJ); + static void XPY(D4OBJ); + static void XPZ(D4OBJ); + static void XPS(D4OBJ); + static void XYP(D4OBJ); + static void XYZ(D4OBJ); + static void XYS(D4OBJ); + static void XZP(D4OBJ); + static void XZY(D4OBJ); + static void XZS(D4OBJ); + static void XSP(D4OBJ); + static void XSY(D4OBJ); + static void XSZ(D4OBJ); + static void YPX(D4OBJ); + static void YPZ(D4OBJ); + static void YPS(D4OBJ); + static void YXP(D4OBJ); + static void YXZ(D4OBJ); + static void YXS(D4OBJ); + static void YZP(D4OBJ); + static void YZX(D4OBJ); + static void YZS(D4OBJ); + static void YSP(D4OBJ); + static void YSX(D4OBJ); + static void YSZ(D4OBJ); + static void ZPX(D4OBJ); + static void ZPY(D4OBJ); + static void ZPS(D4OBJ); + static void ZXP(D4OBJ); + static void ZXY(D4OBJ); + static void ZXS(D4OBJ); + static void ZYP(D4OBJ); + static void ZYX(D4OBJ); + static void ZYS(D4OBJ); + static void ZSP(D4OBJ); + static void ZSX(D4OBJ); + static void ZSY(D4OBJ); + static void SPX(D4OBJ); + static void SPY(D4OBJ); + static void SPZ(D4OBJ); + static void SXP(D4OBJ); + static void SXY(D4OBJ); + static void SXZ(D4OBJ); + static void SYP(D4OBJ); + static void SYX(D4OBJ); + static void SYZ(D4OBJ); + static void SZP(D4OBJ); + static void SZX(D4OBJ); + static void SZY(D4OBJ); + static void PXYZ(D4OBJ); + static void PXYS(D4OBJ); + static void PXZY(D4OBJ); + static void PXZS(D4OBJ); + static void PXSY(D4OBJ); + static void PXSZ(D4OBJ); + static void PYXZ(D4OBJ); + static void PYXS(D4OBJ); + static void PYZX(D4OBJ); + static void PYZS(D4OBJ); + static void PYSX(D4OBJ); + static void PYSZ(D4OBJ); + static void PZXY(D4OBJ); + static void PZXS(D4OBJ); + static void PZYX(D4OBJ); + static void PZYS(D4OBJ); + static void PZSX(D4OBJ); + static void PZSY(D4OBJ); + static void PSXY(D4OBJ); + static void PSXZ(D4OBJ); + static void PSYX(D4OBJ); + static void PSYZ(D4OBJ); + static void PSZX(D4OBJ); + static void PSZY(D4OBJ); + static void XPYZ(D4OBJ); + static void XPYS(D4OBJ); + static void XPZY(D4OBJ); + static void XPZS(D4OBJ); + static void XPSY(D4OBJ); + static void XPSZ(D4OBJ); + static void XYPZ(D4OBJ); + static void XYPS(D4OBJ); + static void XYZP(D4OBJ); + static void XYZS(D4OBJ); + static void XYSP(D4OBJ); + static void XYSZ(D4OBJ); + static void XZPY(D4OBJ); + static void XZPS(D4OBJ); + static void XZYP(D4OBJ); + static void XZYS(D4OBJ); + static void XZSP(D4OBJ); + static void XZSY(D4OBJ); + static void XSPY(D4OBJ); + static void XSPZ(D4OBJ); + static void XSYP(D4OBJ); + static void XSYZ(D4OBJ); + static void XSZP(D4OBJ); + static void XSZY(D4OBJ); + static void YPXZ(D4OBJ); + static void YPXS(D4OBJ); + static void YPZX(D4OBJ); + static void YPZS(D4OBJ); + static void YPSX(D4OBJ); + static void YPSZ(D4OBJ); + static void YXPZ(D4OBJ); + static void YXPS(D4OBJ); + static void YXZP(D4OBJ); + static void YXZS(D4OBJ); + static void YXSP(D4OBJ); + static void YXSZ(D4OBJ); + static void YZPX(D4OBJ); + static void YZPS(D4OBJ); + static void YZXP(D4OBJ); + static void YZXS(D4OBJ); + static void YZSP(D4OBJ); + static void YZSX(D4OBJ); + static void YSPX(D4OBJ); + static void YSPZ(D4OBJ); + static void YSXP(D4OBJ); + static void YSXZ(D4OBJ); + static void YSZP(D4OBJ); + static void YSZX(D4OBJ); + static void ZPXY(D4OBJ); + static void ZPXS(D4OBJ); + static void ZPYX(D4OBJ); + static void ZPYS(D4OBJ); + static void ZPSX(D4OBJ); + static void ZPSY(D4OBJ); + static void ZXPY(D4OBJ); + static void ZXPS(D4OBJ); + static void ZXYP(D4OBJ); + static void ZXYS(D4OBJ); + static void ZXSP(D4OBJ); + static void ZXSY(D4OBJ); + static void ZYPX(D4OBJ); + static void ZYPS(D4OBJ); + static void ZYXP(D4OBJ); + static void ZYXS(D4OBJ); + static void ZYSP(D4OBJ); + static void ZYSX(D4OBJ); + static void ZSPX(D4OBJ); + static void ZSPY(D4OBJ); + static void ZSXP(D4OBJ); + static void ZSXY(D4OBJ); + static void ZSYP(D4OBJ); + static void ZSYX(D4OBJ); + static void SPXY(D4OBJ); + static void SPXZ(D4OBJ); + static void SPYX(D4OBJ); + static void SPYZ(D4OBJ); + static void SPZX(D4OBJ); + static void SPZY(D4OBJ); + static void SXPY(D4OBJ); + static void SXPZ(D4OBJ); + static void SXYP(D4OBJ); + static void SXYZ(D4OBJ); + static void SXZP(D4OBJ); + static void SXZY(D4OBJ); + static void SYPX(D4OBJ); + static void SYPZ(D4OBJ); + static void SYXP(D4OBJ); + static void SYXZ(D4OBJ); + static void SYZP(D4OBJ); + static void SYZX(D4OBJ); + static void SZPX(D4OBJ); + static void SZPY(D4OBJ); + static void SZXP(D4OBJ); + static void SZXY(D4OBJ); + static void SZYP(D4OBJ); + static void SZYX(D4OBJ); + static void PXYZS(D4OBJ); + static void PXYSZ(D4OBJ); + static void PXZYS(D4OBJ); + static void PXZSY(D4OBJ); + static void PXSYZ(D4OBJ); + static void PXSZY(D4OBJ); + static void PYXZS(D4OBJ); + static void PYXSZ(D4OBJ); + static void PYZXS(D4OBJ); + static void PYZSX(D4OBJ); + static void PYSXZ(D4OBJ); + static void PYSZX(D4OBJ); + static void PZXYS(D4OBJ); + static void PZXSY(D4OBJ); + static void PZYXS(D4OBJ); + static void PZYSX(D4OBJ); + static void PZSXY(D4OBJ); + static void PZSYX(D4OBJ); + static void PSXYZ(D4OBJ); + static void PSXZY(D4OBJ); + static void PSYXZ(D4OBJ); + static void PSYZX(D4OBJ); + static void PSZXY(D4OBJ); + static void PSZYX(D4OBJ); + static void XPYZS(D4OBJ); + static void XPYSZ(D4OBJ); + static void XPZYS(D4OBJ); + static void XPZSY(D4OBJ); + static void XPSYZ(D4OBJ); + static void XPSZY(D4OBJ); + static void XYPZS(D4OBJ); + static void XYPSZ(D4OBJ); + static void XYZPS(D4OBJ); + static void XYZSP(D4OBJ); + static void XYSPZ(D4OBJ); + static void XYSZP(D4OBJ); + static void XZPYS(D4OBJ); + static void XZPSY(D4OBJ); + static void XZYPS(D4OBJ); + static void XZYSP(D4OBJ); + static void XZSPY(D4OBJ); + static void XZSYP(D4OBJ); + static void XSPYZ(D4OBJ); + static void XSPZY(D4OBJ); + static void XSYPZ(D4OBJ); + static void XSYZP(D4OBJ); + static void XSZPY(D4OBJ); + static void XSZYP(D4OBJ); + static void YPXZS(D4OBJ); + static void YPXSZ(D4OBJ); + static void YPZXS(D4OBJ); + static void YPZSX(D4OBJ); + static void YPSXZ(D4OBJ); + static void YPSZX(D4OBJ); + static void YXPZS(D4OBJ); + static void YXPSZ(D4OBJ); + static void YXZPS(D4OBJ); + static void YXZSP(D4OBJ); + static void YXSPZ(D4OBJ); + static void YXSZP(D4OBJ); + static void YZPXS(D4OBJ); + static void YZPSX(D4OBJ); + static void YZXPS(D4OBJ); + static void YZXSP(D4OBJ); + static void YZSPX(D4OBJ); + static void YZSXP(D4OBJ); + static void YSPXZ(D4OBJ); + static void YSPZX(D4OBJ); + static void YSXPZ(D4OBJ); + static void YSXZP(D4OBJ); + static void YSZPX(D4OBJ); + static void YSZXP(D4OBJ); + static void ZPXYS(D4OBJ); + static void ZPXSY(D4OBJ); + static void ZPYXS(D4OBJ); + static void ZPYSX(D4OBJ); + static void ZPSXY(D4OBJ); + static void ZPSYX(D4OBJ); + static void ZXPYS(D4OBJ); + static void ZXPSY(D4OBJ); + static void ZXYPS(D4OBJ); + static void ZXYSP(D4OBJ); + static void ZXSPY(D4OBJ); + static void ZXSYP(D4OBJ); + static void ZYPXS(D4OBJ); + static void ZYPSX(D4OBJ); + static void ZYXPS(D4OBJ); + static void ZYXSP(D4OBJ); + static void ZYSPX(D4OBJ); + static void ZYSXP(D4OBJ); + static void ZSPXY(D4OBJ); + static void ZSPYX(D4OBJ); + static void ZSXPY(D4OBJ); + static void ZSXYP(D4OBJ); + static void ZSYPX(D4OBJ); + static void ZSYXP(D4OBJ); + static void SPXYZ(D4OBJ); + static void SPXZY(D4OBJ); + static void SPYXZ(D4OBJ); + static void SPYZX(D4OBJ); + static void SPZXY(D4OBJ); + static void SPZYX(D4OBJ); + static void SXPYZ(D4OBJ); + static void SXPZY(D4OBJ); + static void SXYPZ(D4OBJ); + static void SXYZP(D4OBJ); + static void SXZPY(D4OBJ); + static void SXZYP(D4OBJ); + static void SYPXZ(D4OBJ); + static void SYPZX(D4OBJ); + static void SYXPZ(D4OBJ); + static void SYXZP(D4OBJ); + static void SYZPX(D4OBJ); + static void SYZXP(D4OBJ); + static void SZPXY(D4OBJ); + static void SZPYX(D4OBJ); + static void SZXPY(D4OBJ); + static void SZXYP(D4OBJ); + static void SZYPX(D4OBJ); + static void SZYXP(D4OBJ); + }; + + // Cameraクラス + class Camera + { + public: + + static void Viewport(int,int,int,int); + static void Projection(float,float,float,float); + static void Move(float,float,float); + static void MoveX(float); + static void MoveY(float); + static void MoveZ(float); + static void Rotate(float,float,float); + static void RotateX(float); + static void RotateY(float); + static void RotateZ(float); + static void StaticTransform(void); + static void DynamicTransform(void); + static void LoadMatrix(void); + static void SetMatrix(D4MTX&); + static D4MTX& GetMatrix(void); + static void GetPosition(void); + static BOOL LookAt(float,float,float,float,float,float); + static void LookAtObject(D4OBJ,float,float,float); + static void ObjectMirror(D4OBJ); + static void ObjectMirror(void); + static void Zoom(float); + + static int Vx1,Vy1,Vx2,Vy2; + + static float Near,Far,Aspect,Fov; + + static D4MTX ViewMatrix; + static D4MTX ProjectionMatrix; + }; + + // Lightクラス + class Light + { + public: + + static D4LGT Create(int); + static void Free(D4LGT); + static void Show(D4LGT); + static void Hide(D4LGT); + static void Update(D4LGT); + static void Color(D4LGT,float,float,float); + static void Specular(D4LGT,float,float,float); + static void Ambient(float,float,float); + static void SpotSize(D4LGT,float,float); + static void SpotPower(D4LGT,float); + static void PointPower(D4LGT,float); + static void Move(D4LGT,float,float,float); + static void Direction(D4LGT,float,float,float); + + // ライトオブジェクト情報 + struct _lightobj + { + BOOL Use; // 使用フラグ + D3DLIGHT7 Data; // ライトデータ + }; + }; + + // Textureクラス + class Texture + { + public: + + static D4TXR Create(int,int); + static D4TXR CreateTarget(int,int); + static D4TXR Load(char*,int); + static void Swap(char*,D4TXR); + static void SetPack(char*); + static D4TXR LoadPack(char*); + static void SwapPack(char*,D4TXR); + static void Free(D4TXR); + static void Set(D4OBJ,D4TXR); + static void SetX(D4OBJ,D4TXR); + static D4TXR Get(D4OBJ); + static void Transparent(BOOL); + static void Filter(int,int); + static void Perspective(BOOL); + static void Atm(BOOL); + static BOOL SetAlpha(D4TXR); + static void EnvMap(D4OBJ); + static void EnvMapX(D4OBJ); + static void MMSave(D4OBJ,int); + static void MMSaveX(D4OBJ,int); + static void MMLoad(D4OBJ,int); + static void MMLoadX(D4OBJ,int); + + static int LastTexture; + static DWORD MinWidth,MinHeight; + static DWORD MaxWidth,MaxHeight; + + static BOOL AtmMode; + + static int AlphaTexture; + static BOOL AlphaFormat; + static int MaxTextureFormat; + static DDPIXELFORMAT Format[]; + }; + + // Fogクラス + class Fog + { + public: + + static void Show(void); + static void Hide(void); + static void Color(float,float,float); + static void Range(float,float,BOOL); + }; + + // Materialクラス + class Material + { + public: + + static void Color(D4OBJ,float,float,float); + static void ColorX(D4OBJ,float,float,float); + static void Ambient(D4OBJ,float,float,float); + static void AmbientX(D4OBJ,float,float,float); + static void Specular(D4OBJ,float,float,float); + static void SpecularX(D4OBJ,float,float,float); + static void Power(D4OBJ,float); + static void PowerX(D4OBJ,float); + static void Emissive(D4OBJ,float,float,float); + static void EmissiveX(D4OBJ,float,float,float); + static void Alpha(D4OBJ,float); + static void AlphaX(D4OBJ,float); + static void GetColor(D4OBJ,float*,float*,float*); + static void GetAmbient(D4OBJ,float*,float*,float*); + static void GetSpecular(D4OBJ,float*,float*,float*); + static void GetPower(D4OBJ,float*); + static void GetEmissive(D4OBJ,float*,float*,float*); + static void GetAlpha(D4OBJ,float*); + static void Copy(D4OBJ,D4OBJ); + static void MMSave(D4OBJ,int); + static void MMSaveX(D4OBJ,int); + static void MMLoad(D4OBJ,int); + static void MMLoadX(D4OBJ,int); + }; + + // Stateクラス + class State + { + public: + + static void Z(BOOL); + static void W(BOOL); + static void CheckZ(int); + static void WriteZ(BOOL); + static void Dither(BOOL); + static void Specular(BOOL); + static void Shade(int); + static void Antialias(BOOL); + static void Alpha(int); + static void Reverse(BOOL); + static void UseAlpha(int); + static void CheckAlpha(int,BYTE); + static void UnCheckAlpha(void); + }; + + // Flatクラス + class Flat + { + public: + + static D4OBJ Create(void); + static void Free(D4OBJ); + static D4OBJ Load(char*,int); + static void Render(D4OBJ); + static void AlphaRender(D4OBJ,int); + static void Move(D4OBJ,float,float); + static void Size(D4OBJ,float,float); + static void Area(D4OBJ,float,float,float,float); + static void Vertex(D4OBJ,float,float,float,float,float,float,float, + float); + static void Rotate(D4OBJ,float); + static void TexturePosition(D4OBJ,float,float,float,float); + static void Alpha(D4OBJ,float); + static void Alpha(D4OBJ,float,float,float,float); + static void Color(D4OBJ,float,float,float); + static void Color(D4OBJ,float,float,float,float,float,float,float,float, + float,float,float,float); + static void Uv(D4OBJ,float,float,float,float,float,float,float,float); + static void ReverseUv(D4OBJ,int); + static void Layer(float,float,D4OBJ,float,float,float,float); + static void Layer(float,float,D4OBJ); + static void RotateLayer(float,float,float,D4OBJ,float,float,float,float); + static void RotateLayer(float,float,float,D4OBJ); + static void StretchLayer(float,float,D4OBJ,float,float,float,float,float, + float); + static void StretchLayer(float,float,D4OBJ,float,float); + static void ZoomLayer(float,float,float,D4OBJ,float,float,float,float, + float,float); + static void ZoomLayer(float,float,float,D4OBJ,float,float); + }; + + // Configクラス + class Config + { + public: + + static WORD Driver; + static WORD Texture; + static WORD User; + + static WORD VertexBuffer; + + static WORD Antialias; + + static BOOL AlphaBlendNormal; + static BOOL AlphaBlendAdd; + static BOOL AlphaBlendDelete; + static BOOL AlphaBlendReverse; + static BOOL AlphaBlendBright; + + static WORD WBuffer; + + static DDPIXELFORMAT ZBuffer; + + static int ZBit; + + static GUID DriverGUID; + }; + + static float Width,Height; + + static D4MTX mat1,mat2; + + static DWORD Ppf; +}; + +// Xファイルリスト情報 +struct el4D::Render::_xfile XFile[XFILE_MAX]; +int el4D::Render::XFileNo; + +// 画面クリアー情報 +DWORD el4D::Clear::ClearType; // タイプ +D3DRECT el4D::Clear::ClearArea; // エリア +LPD3DRECT el4D::Clear::ClearAreaPtr; // エリアポインター +DWORD el4D::Clear::ClearAreaCount; // エリア数 +D3DCOLOR el4D::Clear::ClearColor; // 色 + +// ビューポートのサイズ +int el4D::Camera::Vx1; +int el4D::Camera::Vy1; +int el4D::Camera::Vx2; +int el4D::Camera::Vy2; + +// カメラビュー情報 +float el4D::Camera::Near; // 手前のクリップ位置 +float el4D::Camera::Far; // 奥のクリップ位置 +float el4D::Camera::Aspect; // アスペクト比 +float el4D::Camera::Fov; // FOV + +// ビューマトリクス +D4MTX el4D::Camera::ViewMatrix; + +// 投影マトリクス +D4MTX el4D::Camera::ProjectionMatrix; + +// ポリゴンオブジェクト情報 +struct el4D::Object::_polyobj PolyObj[POLYOBJ_MAX]; + +// ライトオブジェクト情報 +struct el4D::Light::_lightobj LightObj[LIGHTOBJ_MAX]; + +// 最後に処理したテクスチャー +int el4D::Texture::LastTexture; + +// テクスチャーの最小サイズと最大サイズ +DWORD el4D::Texture::MinWidth; +DWORD el4D::Texture::MinHeight; +DWORD el4D::Texture::MaxWidth; +DWORD el4D::Texture::MaxHeight; + +// オートマチックテクスチャーマネージャー +BOOL el4D::Texture::AtmMode; + +// テクスチャーフォーマット +int el4D::Texture::AlphaTexture; +BOOL el4D::Texture::AlphaFormat; +int el4D::Texture::MaxTextureFormat; +DDPIXELFORMAT el4D::Texture::Format[TEXTURE_MAX]; + +// 環境データ +WORD el4D::Config::Driver=0x0000; // ドライバー関係 +WORD el4D::Config::Texture=0x0000; // テクスチャー関係 +WORD el4D::Config::User=0x0000; // ユーザー要求 + +// 頂点バッファタイプ +WORD el4D::Config::VertexBuffer; + +// アンチエイリアスモード +WORD el4D::Config::Antialias; + +// アルファブレンドモード +BOOL el4D::Config::AlphaBlendNormal; // 通常 +BOOL el4D::Config::AlphaBlendAdd; // 加算 +BOOL el4D::Config::AlphaBlendDelete; // 減算 +BOOL el4D::Config::AlphaBlendReverse; // 反転 +BOOL el4D::Config::AlphaBlendBright; // 明度 + +// Wバッファモード +WORD el4D::Config::WBuffer; + +// Zバッファフォーマット +DDPIXELFORMAT el4D::Config::ZBuffer; + +// Zバッファビット数 +int el4D::Config::ZBit; + +// Direct3Dドライバー +GUID el4D::Config::DriverGUID; + +// 画面サイズ ( elDrawクラスと同等 ) +float el4D::Width; +float el4D::Height; + +// 汎用マトリクス +D4MTX el4D::mat1; +D4MTX el4D::mat2; + +// 1フレームあたりのポリゴン数 +DWORD el4D::Ppf; + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= ストリームクラス宣言 ( elStream ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef MEDIASTREAM + +// DirectShow/ActiveMovie制御 +IMediaStream* STMediaStream=NULL; +IMultiMediaStream* STMultiMediaStream=NULL; +IDirectDrawMediaStream* STMediaStreamDD=NULL; +IDirectDrawStreamSample* STStreamSample=NULL; +IDirectDrawSurface* STStreamSurface=NULL; + +// クラス定義 +class elStream +{ + public: + + static void Init(void); + static void DestroyObject(void); + static BOOL LoadObject(char*,BOOL); + static void FreeObject(void); + static void Rendering(int,int,DDOBJ); + static void ShowImage(void); + static void Play(void); + static void Stop(void); + static void Pause(void); + static void Forward(int); + static void Backward(int); + static void Top(void); + static int GetStatus(void); + + + static BOOL LoadCheck; + static BOOL PlayCheck; + static BOOL PauseCheck; + static BOOL OneShot; + static STREAM_TIME MovieTime; + static int Sx,Sy; +}; + +// 制御フラグ +BOOL elStream::LoadCheck; +BOOL elStream::PlayCheck; +BOOL elStream::PauseCheck; + +// 1フレーム描画 +BOOL elStream::OneShot; + +// ストリームの時間 +STREAM_TIME elStream::MovieTime; + +// 再生サイズ +int elStream::Sx; +int elStream::Sy; + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= 内部使用ムービークラス宣言 ( elMovieObject、elMovieRender ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef DIRECTSHOW + +static const int MV_READY=0; +static const int MV_END=1; +static const int MV_DRAWBEGIN=2; +static const int MV_DRAWBEFORE=3; + +static const int CLOSE_MOVIE=0; +static const int OPEN_MOVIE=1; +static const int PLAY_MOVIE=2; +static const int STOP_MOVIE=3; +static const int PAUSE_MOVIE=4; + +static int ViewLeft; +static int ViewTop; +static int ViewWidth; +static int ViewHeight; + +static BOOL ViewStretch; +static BOOL ViewLayer; +static BOOL ViewDrawEvent; + +extern const GUID _RenderClass; + +class elMovieRender:public CBaseVideoRenderer +{ + public: + + elMovieRender(LPUNKNOWN,HRESULT*,LPDIRECTDRAW,LPDIRECTDRAWSURFACE,BOOL); + virtual ~elMovieRender(); + BOOL (*UserCallback)(); + HRESULT CheckMediaType(const CMediaType*); + HRESULT SetMediaType(const CMediaType*); + HRESULT DoRenderSample(IMediaSample*); + HRESULT CreateVideoSprite(void); + HRESULT BreakConnect(void); + HRESULT Draw(ULONG,ULONG); + void Check(void); + + CMediaType MediaType; + CCritSec AccessLock; + BYTE BitWidth; + DDCAPS HalCaps; + DDSURFACEDESC SurfaceDesc; + static LPDIRECTDRAWSURFACE DDVideo; +}; + +LPDIRECTDRAWSURFACE elMovieRender::DDVideo; + +class elMovieObject +{ + public: + + elMovieObject(HRESULT*,LPDIRECTDRAW,LPDIRECTDRAWSURFACE); + ~elMovieObject(); + int Start(LPCSTR,LPDIRECTDRAW,LPDIRECTDRAWSURFACE,BOOL, + BOOL(*PlayCallback)()); + void Close(void); + BOOL OnGraphNotify(void); + elMovieRender* CreateVideoRenderer(LPDIRECTDRAW,LPDIRECTDRAWSURFACE,BOOL, + IGraphBuilder*,WCHAR*); + BOOL Open(LPCSTR,LPDIRECTDRAW,LPDIRECTDRAWSURFACE,BOOL); + void Play(void); + void Pause(void); + void Stop(void); + void Forward(int); + void Backward(int); + void Top(void); + BOOL End(void); + + int MovieMode; + HANDLE GraphEvent; + REFTIME MovieTime; + IGraphBuilder* FilterGraph; + IMediaControl* MediaControl; + IMediaPosition* MediaPosition; + elMovieRender* MovieRender; +}; + +const GUID _RenderClass= +{ + 0x7af77a70, + 0xa8f8, + 0x11d0, + + { + 0x89, + 0xb7, + 0x0, + 0x20, + 0xaf, + 0xef, + 0x46, + 0x1e + } +}; + +elMovieRender::elMovieRender(LPUNKNOWN OwnObj,HRESULT* Ret,LPDIRECTDRAW ObjectDD, + LPDIRECTDRAWSURFACE FrontDD,BOOL FlipFlag) +:CBaseVideoRenderer(_RenderClass,NAME("Renderer"),OwnObj,Ret) +{ + UserCallback=NULL; + + if (ObjectDD && FrontDD) + { + HRESULT ret; + + DDObject=ObjectDD; + DDFront=FrontDD; + DDVideo=NULL; + + if (FlipFlag) + { + DDSCAPS ddscaps; + ddscaps.dwCaps=DDSCAPS_BACKBUFFER; + ret=DDFront->GetAttachedSurface(&ddscaps,&DDBack); + } + else + { + ret=DD_OK; + } + + if (SUCCEEDED(ret)) + { + SurfaceDesc.dwSize=sizeof(SurfaceDesc); + SurfaceDesc.dwFlags=DDSD_ALL; + ret=DDFront->GetSurfaceDesc(&SurfaceDesc); + + if (SUCCEEDED(ret)) + { + Check(); + *Ret=NOERROR; + + return; + } + } + } + + *Ret=E_FAIL; +} + +elMovieRender::~elMovieRender() +{ + if (DDVideo!=NULL) + { + DDVideo->Release(); + DDVideo=NULL; + } +} + +HRESULT elMovieRender::BreakConnect(void) +{ + m_pQSink=NULL; + + return CBaseVideoRenderer::BreakConnect(); +} + +HRESULT elMovieRender::CheckMediaType(const CMediaType* Type) +{ + HRESULT ret; + VIDEOINFO *Info; + + if (*Type->FormatType()!=FORMAT_VideoInfo) + { + return E_INVALIDARG; + } + + ret=E_FAIL; + Info=(VIDEOINFO*)Type->Format(); + + switch (SurfaceDesc.ddpfPixelFormat.dwRGBBitCount) + { + case 16: + { + if (Info->bmiHeader.biBitCount==16) + { + if (((BitWidth==6) && + IsEqualGUID(*Type->Type(),MEDIATYPE_Video) && + IsEqualGUID(*Type->Subtype(),MEDIASUBTYPE_RGB565)) || + ((BitWidth==5) && + IsEqualGUID(*Type->Type(),MEDIATYPE_Video) && + IsEqualGUID(*Type->Subtype(),MEDIASUBTYPE_RGB555))) + { + ret=NOERROR; + } + } + + break; + } + + case 24: + { + if (Info->bmiHeader.biBitCount==24) + { + if (IsEqualGUID(*Type->Type(),MEDIATYPE_Video) && + IsEqualGUID(*Type->Subtype(),MEDIASUBTYPE_RGB24)) + { + ret=NOERROR; + } + } + + break; + } + + case 32: + { + if (Info->bmiHeader.biBitCount==32) + { + if (IsEqualGUID(*Type->Type(),MEDIATYPE_Video) && + IsEqualGUID(*Type->Subtype(),MEDIASUBTYPE_RGB32)) + { + ret=NOERROR; + } + } + + break; + } + } + + return ret; +} + +HRESULT elMovieRender::SetMediaType(const CMediaType* Type) +{ + MediaType=*Type; + + return CreateVideoSprite(); +} + +HRESULT elMovieRender::DoRenderSample(IMediaSample* RenderData) +{ + static HRESULT ret; + static BYTE* BmpBuffer; + static BYTE* TxtBuffer; + static VIDEOINFO* Info; + static LONG BmpWidth,BmpHeight; + static LONG TxtWidth,TxtHeight; + static LONG CopyWidth,CopyHeight; + static LONG y; + static DDSURFACEDESC ddsd; + + _controlfp(_MCW_RC,_RC_CHOP); + + CAutoLock lock(&AccessLock); + + UserCallback(); + + if (!DDVideo) return S_FALSE; + + int pixelsize=ddsd.ddpfPixelFormat.dwRGBBitCount/8; + LONG lBmpPitch=(BmpWidth*pixelsize+3)&~3; + LONG lTxtPitch=ddsd.lPitch; + + RenderData->GetPointer(&BmpBuffer); + Info=(VIDEOINFO*)MediaType.Format(); + BmpWidth=Info->bmiHeader.biWidth; + BmpHeight=abs(Info->bmiHeader.biHeight); + + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + + ret=DDVideo->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); + if (FAILED(ret)) return ret; + + TxtBuffer=(BYTE*)ddsd.lpSurface; + + if (TxtBuffer) + { + TxtWidth=(LONG)ddsd.dwWidth; + TxtHeight=(LONG)ddsd.dwHeight; + + if (BmpWidth<=TxtWidth) + { + CopyWidth=BmpWidth; + TxtBuffer+=(TxtWidth-BmpWidth)/2*pixelsize; + } + else if (BmpWidth>TxtWidth) + { + CopyWidth=TxtWidth; + BmpBuffer+=(BmpWidth-TxtWidth)/2; + } + + if (BmpHeight<=TxtHeight) + { + CopyHeight=BmpHeight; + TxtBuffer+=(TxtHeight-BmpHeight)/2*lTxtPitch; + } + else if (BmpHeight>TxtHeight) + { + CopyHeight=TxtHeight; + BmpBuffer+=(BmpHeight-TxtHeight)/2*lBmpPitch; + } + + TxtBuffer=TxtBuffer+(CopyHeight-1)*lTxtPitch; + CopyWidth*=pixelsize; + + for (y=0;yUnlock(ddsd.lpSurface); + + ret=Draw(TxtWidth,TxtHeight); + } + + return NOERROR; +} + +HRESULT elMovieRender::CreateVideoSprite(void) +{ + HRESULT ret; + + CAutoLock lock(&AccessLock); + + VIDEOINFO* Info=(VIDEOINFO*)MediaType.Format(); + + DDSURFACEDESC ddsd; + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + + ddsd.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_CKSRCBLT; + ddsd.ddsCaps.dwCaps=DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN|DDSCAPS_MODEX; + ddsd.dwWidth=Info->bmiHeader.biWidth; + ddsd.dwHeight=Info->bmiHeader.biHeight; + ddsd.ddpfPixelFormat.dwSize=sizeof(ddsd.ddpfPixelFormat); + ddsd.ddpfPixelFormat.dwRGBBitCount=SurfaceDesc.ddpfPixelFormat.dwRGBBitCount; + ddsd.ddpfPixelFormat.dwFlags=SurfaceDesc.ddpfPixelFormat.dwFlags; + ddsd.ddpfPixelFormat.dwRBitMask=SurfaceDesc.ddpfPixelFormat.dwRBitMask; + ddsd.ddpfPixelFormat.dwGBitMask=SurfaceDesc.ddpfPixelFormat.dwGBitMask; + ddsd.ddpfPixelFormat.dwBBitMask=SurfaceDesc.ddpfPixelFormat.dwBBitMask; + ddsd.ddckCKSrcBlt.dwColorSpaceLowValue=0; + ddsd.ddckCKSrcBlt.dwColorSpaceHighValue=0; + + ret=DDObject->CreateSurface(&ddsd,&DDVideo,NULL); + + DDSetColorKey(DDVideo,RGB(0,0,0)); + + return ret; +} + +void elMovieRender::Check(void) +{ + if (DDObject) + { + DDCAPS ddcaps; + DDObject->GetCaps(&HalCaps,&ddcaps); + } + + DWORD RedMask=SurfaceDesc.ddpfPixelFormat.dwRBitMask; + DWORD GreenMask=SurfaceDesc.ddpfPixelFormat.dwGBitMask; + BYTE Red=0,Green=0; + + while (!(RedMask&1)) + { + RedMask>>=1; + ++Red; + } + + while (!(GreenMask&1)) + { + GreenMask>>=1; + ++Green; + } + + BitWidth=(BYTE)(Red-Green); +} + +HRESULT elMovieRender::Draw(ULONG Width,ULONG Height) +{ + static HRESULT ret; + static RECT sr,dr; + static RECT rect; + + sr.left=0; + sr.top=0; + sr.right=Width; + sr.bottom=Height; + dr.left=ViewLeft; + dr.top=ViewTop; + dr.right=ViewWidth; + dr.bottom=ViewHeight; + + if (ViewDrawEvent) + { + elMovieProc(MV_DRAWBEGIN); + } + + if (ViewStretch) + { + if ((ULONG)ViewWidth!=Width || + (ULONG)ViewHeight!=Height) + { + HDC shdc,dhdc; + + ret=DDVideo->GetDC(&shdc); + if (ret!=DD_OK) return 0; + + if (!ViewLayer) + { + ret=DDBack->GetDC(&dhdc); + } + else + { + ret=Sprite[BUFFER_SPRITE].Object->GetDC(&dhdc); + } + + if (ret==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + + if (!ViewLayer) + { + ret=DDBack->GetDC(&dhdc); + } + else + { + ret=Sprite[BUFFER_SPRITE].Object->GetDC(&dhdc); + } + } + + if (ret!=DD_OK) return 0; + + if (!StretchBlt(dhdc,dr.left,dr.top,dr.right,dr.bottom,shdc, + sr.left,sr.top,sr.right,sr.bottom,SRCCOPY)) + { + return 0; + } + + DDVideo->ReleaseDC(shdc); + + if (!ViewLayer) + { + DDBack->ReleaseDC(dhdc); + } + else + { + Sprite[BUFFER_SPRITE].Object->ReleaseDC(dhdc); + } + } + else + { + if (!ViewLayer) + { + ret=DDBack->Blt(&dr,DDVideo,&sr,DDBLT_WAIT,NULL); + + if (ret==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } + else + { + ret=Sprite[BUFFER_SPRITE].Object->Blt(&dr,DDVideo,&sr, + DDBLT_WAIT,NULL); + + if (ret==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } + + if (ret!=DD_OK) return 0; + } + } + + if (ViewLayer) + { + if (!ViewStretch) + { + rect.left=0; + rect.top=0; + rect.right=Width; + rect.bottom=Height; + + ret=DDBack->BltFast(ViewLeft,ViewTop,DDVideo,&rect, + DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT); + + if (ret==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + + if (ret!=DD_OK) return 0; + } + else + { + rect.left=ViewLeft; + rect.top=ViewTop; + rect.right=ViewLeft+ViewWidth; + rect.bottom=ViewTop+ViewHeight; + + ret=DDBack->BltFast(ViewLeft,ViewTop,Sprite[BUFFER_SPRITE].Object, + &rect,DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT); + + if (ret==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + + if (ret!=DD_OK) return 0; + } + } + + if (!ViewStretch && !ViewLayer) + { + rect.left=0; + rect.top=0; + rect.right=Width; + rect.bottom=Height; + + ret=DDBack->BltFast(ViewLeft,ViewTop,DDVideo,&rect,DDBLTFAST_WAIT); + + if (ret==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + + if (ret!=DD_OK) return 0; + } + + if (ViewDrawEvent) + { + elMovieProc(MV_DRAWBEFORE); + } + else + { + elDraw::Refresh(); + } + + return ret; +} + +elMovieObject::elMovieObject(HRESULT* Ret,LPDIRECTDRAW ObjectDD, + LPDIRECTDRAWSURFACE FrontDD) +{ + FilterGraph=NULL; + MediaControl=NULL; + MediaPosition=NULL; + GraphEvent=NULL; + MovieMode=CLOSE_MOVIE; + MovieRender=NULL; + *Ret=NOERROR; +} + +elMovieObject::~elMovieObject() +{ +} + +BOOL elMovieObject::OnGraphNotify() +{ + BOOL Error=TRUE; + + if (GraphEvent==NULL) return TRUE; + + IMediaEvent* Event; + long EventCode,lParam1,lParam2; + + if (SUCCEEDED(FilterGraph->QueryInterface(IID_IMediaEvent,(void**)&Event))) + { + if (SUCCEEDED(Event->GetEvent(&EventCode,&lParam1,&lParam2,0))) + { + if (EventCode==EC_COMPLETE || EventCode==EC_USERABORT || + EventCode==EC_ERRORABORT) + { + Close(); + Error=TRUE; + } + else + { + Error=FALSE; + } + } + + Event->Release(); + } + + return Error; +} + +elMovieRender* elMovieObject::CreateVideoRenderer(LPDIRECTDRAW ObjectDD, + LPDIRECTDRAWSURFACE FrontDD, + BOOL FlipFlag, + IGraphBuilder* Graph, + WCHAR* FileName) +{ + HRESULT ret; + elMovieRender* Renderer; + + #ifdef __AMEXTRA__ + + IBaseFilter* Filter; + + #else + + IFilter* Filter; + + #endif + + Renderer=new elMovieRender(NULL,&ret,ObjectDD,FrontDD,FlipFlag); + + if (SUCCEEDED(ret)) + { + #ifdef __AMEXTRA__ + + Renderer->NonDelegatingQueryInterface(IID_IBaseFilter,(void**)&Filter); + + #else + + Renderer->NonDelegatingQueryInterface(IID_IFilter,(void**)&Filter); + + #endif + + ret=Graph->AddFilter(Filter,NULL); + Filter->Release(); + + if (SUCCEEDED(ret)) + { + if (SUCCEEDED(Graph->RenderFile((LPCWSTR)FileName,NULL))) + { + return Renderer; + } + } + } + + return NULL; +} + +int elMovieObject::Start(LPCSTR Path,LPDIRECTDRAW ObjectDD, + LPDIRECTDRAWSURFACE FrontDD, + BOOL FlipFlag,BOOL (*PlayCallback)()) +{ + if (Open(Path,ObjectDD,FrontDD,FlipFlag)) + { + if (MovieRender) + { + MovieRender->UserCallback=PlayCallback; + + return 0; + } + + return -1; + } + + return -2; +} + +BOOL elMovieObject::Open(LPCSTR Path,LPDIRECTDRAW ObjectDD, + LPDIRECTDRAWSURFACE FrontDD,BOOL FlipFlag) +{ + HRESULT ret; + WCHAR FileName[MAX_PATH]; + IGraphBuilder* graphbuilder; + IMediaEvent* mediaevent; + IMediaControl* mediacontrol; + IMediaPosition* mediaposition; + elMovieRender* Renderer; + HANDLE GraphNotifyEvent; + + MultiByteToWideChar(CP_ACP,0,Path,-1,FileName,MAX_PATH); + + QzInitialize(NULL); + + graphbuilder=0; + mediacontrol=0; + mediaposition=0; + + while (TRUE) + { + ret=QzCreateFilterObject(CLSID_FilterGraph,NULL,CLSCTX_INPROC, + IID_IGraphBuilder,(LPVOID*)&graphbuilder); + if (FAILED(ret)) break; + + Renderer=CreateVideoRenderer(ObjectDD,FrontDD,FlipFlag, + graphbuilder,FileName); + if (!Renderer) break; + + ret=graphbuilder->QueryInterface(IID_IMediaEvent,(void**)&mediaevent); + if (FAILED(ret)) break; + + ret=mediaevent->GetEventHandle((OAEVENT*)&GraphNotifyEvent); + mediaevent->Release(); + if (FAILED(ret)) break; + + ret=graphbuilder->QueryInterface(IID_IMediaControl, + (LPVOID*)&mediacontrol); + if (FAILED(ret)) break; + + ret=graphbuilder->QueryInterface(IID_IMediaPosition, + (LPVOID*)&mediaposition); + if (FAILED(ret)) break; + + ret=mediaposition->get_Duration(&MovieTime); + if (FAILED(ret)) break; + + FilterGraph=graphbuilder; + MediaControl=mediacontrol; + MediaPosition=mediaposition; + GraphEvent=GraphNotifyEvent; + MovieMode=OPEN_MOVIE; + MovieRender=Renderer; + + return TRUE; + } + + if (mediaposition!=NULL) + { + mediaposition->Release(); + mediaposition=NULL; + } + + if (mediacontrol!=NULL) + { + mediacontrol->Release(); + mediacontrol=NULL; + } + + if (graphbuilder!=NULL) + { + graphbuilder->Release(); + graphbuilder=NULL; + } + + return FALSE; +} + +void elMovieObject::Close(void) +{ + if (MovieMode!=STOP_MOVIE) + { + Stop(); + } + + if (MediaControl!=NULL) + { + MediaControl->Release(); + MediaControl=NULL; + } + + if (MediaPosition!=NULL) + { + MediaPosition->Release(); + MediaPosition=NULL; + } + + if (FilterGraph!=NULL) + { + FilterGraph->Release(); + FilterGraph=NULL; + } + + MovieRender=NULL; + + QzUninitialize(); +} + +void elMovieObject::Play(void) +{ + if (MediaControl) + { + MediaControl->Run(); + MovieMode=PLAY_MOVIE; + } +} + +void elMovieObject::Pause(void) +{ + if (MediaControl) + { + MediaControl->Pause(); + MovieMode=PAUSE_MOVIE; + } +} + +void elMovieObject::Stop(void) +{ + if (MediaControl) + { + MediaControl->Stop(); + MovieMode=STOP_MOVIE; + } +} + +void elMovieObject::Forward(int Speed) +{ + static double NowPos; + + if (MediaControl) + { + MediaPosition->get_CurrentPosition(&NowPos); + NowPos+=MovieTime/F(Speed); + + if (NowPos>MovieTime) NowPos=MovieTime; + + MediaPosition->put_CurrentPosition(NowPos); + } +} + +void elMovieObject::Backward(int Speed) +{ + static double NowPos; + + if (MediaControl) + { + MediaPosition->get_CurrentPosition(&NowPos); + NowPos-=MovieTime/F(Speed); + + if (NowPosput_CurrentPosition(NowPos); + } +} + +void elMovieObject::Top(void) +{ + if (MediaControl) + { + MediaPosition->put_CurrentPosition(0); + } +} + +BOOL elMovieObject::End(void) +{ + static double NowPos; + + if (MediaControl) + { + if (SUCCEEDED(MediaPosition->get_CurrentPosition(&NowPos))) + { + if (MovieTime-NowPosCreateDeviceEx(GUID_SysKeyboard, + IID_IDirectInputDevice7, + (LPVOID*)&DIKeyboard,NULL))) break; + + #else + + if (FAILED(DIObject->CreateDevice(GUID_SysKeyboard,&DIKeyboard,NULL))) + { + break; + } + + #endif + + if (FAILED(DIKeyboard->SetDataFormat(&c_dfDIKeyboard))) break; + + if (FAILED(DIKeyboard->SetCooperativeLevel(hwnd,DISCL_NONEXCLUSIVE| + DISCL_FOREGROUND))) + { + break; + } + + dip.diph.dwSize=sizeof(DIPROPDWORD); + dip.diph.dwHeaderSize=sizeof(DIPROPHEADER); + dip.diph.dwObj=0; + dip.diph.dwHow=DIPH_DEVICE; + dip.dwData=INPUTCHECK_MAX; + + if (FAILED(DIKeyboard->SetProperty(DIPROP_BUFFERSIZE,&dip.diph))) break; + + #ifdef REPORT + + ddc.dwSize=sizeof(DIDEVCAPS); + DIKeyboard->GetCapabilities(&ddc); + + REP_IN + "キーボード = %d キー\n",ddc.dwButtons + REP_OUT + + #endif + + // マウスデバイスの生成 + + #ifdef NEWCODE + + if (FAILED(DIObject->CreateDeviceEx(GUID_SysMouse, + IID_IDirectInputDevice7, + (LPVOID*)&DIMouse,NULL))) break; + + #else + + if (FAILED(DIObject->CreateDevice(GUID_SysMouse,&DIMouse,NULL))) break; + + #endif + + if (FAILED(DIMouse->SetDataFormat(&c_dfDIMouse))) break; + + if (FAILED(DIMouse->SetCooperativeLevel(hwnd,DISCL_NONEXCLUSIVE| + DISCL_FOREGROUND))) + { + break; + } + + dip.diph.dwSize=sizeof(DIPROPDWORD); + dip.diph.dwHeaderSize=sizeof(DIPROPHEADER); + dip.diph.dwObj=0; + dip.diph.dwHow=DIPH_DEVICE; + dip.dwData=INPUTCHECK_MAX; + + if (FAILED(DIMouse->SetProperty(DIPROP_BUFFERSIZE,&dip.diph))) break; + + #ifdef REPORT + + ddc.dwSize=sizeof(DIDEVCAPS); + DIMouse->GetCapabilities(&ddc); + + REP_IN + "マウス = %d 軸 / %d ボタン\n",ddc.dwAxes,ddc.dwButtons + REP_OUT + + #endif + + // ジョイスティックは標準デバイスではないので、エラー無視 + error=FALSE; + + // ジョイスティック数の初期化 + JoystickCount=0; + + // ジョイスティックデバイスの初期化 + for (i=0;iEnumDevices(DIDEVTYPE_JOYSTICK,SearchDevice,NULL, + DIEDFL_ATTACHEDONLY); + + break; + } + + #ifdef REPORT + + REP_IN + "\n" + REP_OUT + + #endif + + if (error) + { + return elDraw::Error("elSystem::Init", + "DirectInputが使用できません"); + } + + // ジョイスティックが使える場合 + if (JoystickCount>0) + { + // キーボード・マウス絶対位置・ジョイスティックを使用 + elSystem::UseInputDevice(USE_KEYBOARD|USE_MOUSE_ABS|USE_JOYSTICK); + } + else + { + // キーボード・マウス絶対位置を使用 + elSystem::UseInputDevice(USE_KEYBOARD|USE_MOUSE_ABS); + } + + InputCount=0; + + #endif + + #ifdef USE_PRINTSCREEN + + // ホットキーの登録 + RegisterHotKey(hwnd,0xBF01,0,VK_SNAPSHOT); + RegisterHotKey(hwnd,0xBF02,MOD_ALT,VK_SNAPSHOT); + + #endif + + for (i=0;iUnacquire(); + DIKeyboard->Release(); + DIKeyboard=NULL; + } + + if (DIMouse!=NULL) + { + DIMouse->Unacquire(); + DIMouse->Release(); + DIMouse=NULL; + } + + for (i=0;iUnacquire(); + DIJoystick[i]->Release(); + DIJoystick[i]=NULL; + } + + #ifndef NEWCODE + + if (DIJoystick2[i]!=NULL) + { + DIJoystick2[i]->Release(); + DIJoystick2[i]=NULL; + } + + #endif + } + + if (DIObject!=NULL) + { + DIObject->Release(); + DIObject=NULL; + } + + #endif + + #ifdef USE_PRINTSCREEN + + // ホットキーの解除 + UnregisterHotKey(hwnd,0xBF01); + UnregisterHotKey(hwnd,0xBF02); + + #endif + + elSystem::ClearMouseArea(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ウェイトの設定 -*/ +/*- -*/ +/*- int No : ウェイトNo -*/ +/*- int Time : 待ち時間 ( ミリ秒 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elSystem::SetWait(int No,int Time) +{ + if (No<1 || No>WAIT_MAX-1) + { + return elDraw::Error("elSystem::SetWait", + "ウェイトNoが範囲外です"); + } + + WaitTime[No-1]=timeGetTime()+(ULONG)Time; + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ウェイトの初期化 -*/ +/*- -*/ +/*- int No : ウェイトNo -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elSystem::InitWait(int No) +{ + if (No<1 || No>WAIT_MAX-1) + { + return elDraw::Error("elSystem::InitWait", + "ウェイトNoが範囲外です"); + } + + WaitTime[No-1]=999999999UL; + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ウェイト状態の取得 -*/ +/*- -*/ +/*- int No : ウェイトNo -*/ +/*- -*/ +/*- 戻り値 : TRUE = 待ち時間経過 -*/ +/*- FALSE = 待ち時間未経過 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elSystem::Wait(int No) +{ + if (timeGetTime()FlipToGDISurface(); + } + + if (!_ShowMouse) + { + ShowCursor(TRUE); + + _ShowMouse=TRUE; + } + + _ShowDialog=TRUE; + + MessageBox(hwnd,Buffer,"メッセージ",MB_OK|MB_SYSTEMMODAL|MB_ICONEXCLAMATION); + + _ShowDialog=FALSE; + + InitFrame(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- YES/NOメッセージの表示 -*/ +/*- -*/ +/*- char* Format ... : printf関数の書式と同様 -*/ +/*- -*/ +/*- 戻り値 : TRUE = YESが選択された -*/ +/*- FALSE = NOが選択された -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elSystem::YesNo(char* Format,...) +{ + char Buffer[256]; + + vsprintf(Buffer,Format,(char*)(&Format+1)); + strcat(Buffer,"\r\n"); + + if (DDObject) + { + DDObject->FlipToGDISurface(); + } + + if (!_ShowMouse) + { + ShowCursor(TRUE); + + _ShowMouse=TRUE; + } + + _ShowDialog=TRUE; + + if (MessageBox(hwnd,Buffer,"メッセージ", + MB_YESNO/*|MB_SYSTEMMODAL*/|MB_ICONQUESTION)==IDYES) + { + _ShowDialog=FALSE; + + InitFrame(); + + return TRUE; + } + else + { + _ShowDialog=FALSE; + + InitFrame(); + + return FALSE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- キー状態の取得 -*/ +/*- -*/ +/*- UINT Code : アスキーコード or 仮想キーコード ( VK_…… ) -*/ +/*- int* Flag : キー状態 ( 戻り値 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// キー状態 +static const int FREE_KEY=0; // キーが押されていない状態 +static const int PUSH_KEY=1; // キーを押された瞬間 +static const int PULL_KEY=2; // キーが放された瞬間 +static const int HOLD_KEY=3; // キーが押されている状態 + +void elSystem::GetKey(UINT Code,int* Flag) +{ + if ((GetKeyState(Code)&0x80)==0x80) + { + if (*Flag==FREE_KEY) + { + *Flag=PUSH_KEY; + } + else + { + *Flag=HOLD_KEY; + } + } + else + { + if (*Flag==PUSH_KEY || *Flag==HOLD_KEY) + { + *Flag=PULL_KEY; + } + else + { + *Flag=FREE_KEY; + } + } + + if (elDraw::FadeNo || elDraw::HelpOn || elSystem::KeyboardLock) + { + *Flag=FREE_KEY; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- キーPUSH/PULLのチェック -*/ +/*- -*/ +/*- UINT Code ... : アスキーコード or 仮想キーコード ( 最後にNULLを指定 ) -*/ +/*- -*/ +/*- 戻り値 : 押されたキー ( UINT型 ) -*/ +/*- Codeに指定した値 = そのキーが押された -*/ +/*- NULL = 何も押されていない -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +UINT elSystem::CheckKey(UINT Code,...) +{ + static int i; // 汎用カウンター + static int Mode=0; // 処理モード + static UINT Key; // 押されたキーコード + + // 最初に何も押されていないことを検出 + if (Mode==0 && !PushKey && !MousePush) Mode=1; + + // 指定されたキーが押されているかチェック + if (Mode==1) + { + for (i=0;*(&Code+i)!=NULL;i++) + { + Key=*(&Code+i); + + if (LastKey==Key || MouseLast==Key) + { + Mode=2; + + break; + } + } + } + + // キーが押された後のチェック + if (Mode==2) + { + // 異なるキーが押された場合 + if (Key!=VK_LBUTTON && Key!=VK_RBUTTON && LastKey!=Key || + (Key==VK_LBUTTON || Key==VK_RBUTTON) && MouseLast!=Key) + { + // 初期化 + Mode=0; + } + + // キーが放された場合 + if (Key!=VK_LBUTTON && Key!=VK_RBUTTON && !PushKey || + (Key==VK_LBUTTON || Key==VK_RBUTTON) && !MousePush) + { + // 初期化 + Mode=0; + LastKey=NULL; + MouseLast=NULL; + + // キーコードを返す + return Key; + } + } + + return FALSE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マウス情報の初期化 ※ 内部で使用 -*/ +/*- -*/ +/*- BOOL Flag : 省略/TRUE = Get構造体に位置データを作成 -*/ +/*- FALSE = 初期化のみ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::InitMouse(BOOL Flag=TRUE) +{ + #ifdef DIRECTINPUT + + POINT pt; + + GetCursorPos(&pt); + + // マウスカーソルが絶対座標の場合 + if (InputDevice&USE_MOUSE_ABS) + { + // 初期位置をGet構造体に作成 + MakeMousePosition=Flag; + } + + // DirectInputの初期カーソル位置に、Windowsのカーソル位置を代入 + VC_INITMX=pt.x-_WindowX; + VC_INITMY=pt.y-_WindowY; + + #endif +} + +#ifdef DIRECTINPUT + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- デバイスの検索 ※ 内部で使用 -*/ +/*- -*/ +/*- パラメーター省略 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +CLBKB elSystem::SearchDevice(LPCDIDEVICEINSTANCE Instance,LPVOID Context) +{ + DIPROPRANGE dir; + DIPROPDWORD dip; + + #ifdef NEWCODE + + LPDIRECTINPUTDEVICE7 device; + + if (FAILED(DIObject->CreateDeviceEx(Instance->guidInstance, + IID_IDirectInputDevice7, + (LPVOID*)&device,NULL))) + { + return DIENUM_CONTINUE; + } + + #else + + LPDIRECTINPUTDEVICE device; + + if (FAILED(DIObject->CreateDevice(Instance->guidInstance,&device,NULL))) + { + return DIENUM_CONTINUE; + } + + #endif + + DIJoystick[JoystickCount]=device; + + #ifndef NEWCODE + + device->QueryInterface(IID_IDirectInputDevice2, + (LPVOID*)&DIJoystick2[JoystickCount]); +// device->Release(); + + #endif + + if (FAILED(DIJoystick[JoystickCount]->SetDataFormat(&c_dfDIJoystick))) + { + return DIENUM_CONTINUE; + } + + if (FAILED(DIJoystick[JoystickCount]-> + SetCooperativeLevel(hwnd,DISCL_NONEXCLUSIVE|DISCL_FOREGROUND))) + { + return DIENUM_CONTINUE; + } + + dip.diph.dwSize=sizeof(DIPROPDWORD); + dip.diph.dwHeaderSize=sizeof(DIPROPHEADER); + dip.diph.dwObj=0; + dip.diph.dwHow=DIPH_DEVICE; + dip.dwData=INPUTCHECK_MAX; + + if (FAILED(DIJoystick[JoystickCount]->SetProperty(DIPROP_BUFFERSIZE, + &dip.diph))) + { + return DIENUM_CONTINUE; + } + + dip.diph.dwHow=DIPH_BYOFFSET; + dip.dwData=5000; + + dip.diph.dwObj=DIJOFS_X; + + if (FAILED(DIJoystick[JoystickCount]->SetProperty(DIPROP_DEADZONE,&dip.diph))) + { + return DIENUM_CONTINUE; + } + + dip.diph.dwObj=DIJOFS_Y; + + if (FAILED(DIJoystick[JoystickCount]->SetProperty(DIPROP_DEADZONE,&dip.diph))) + { + return DIENUM_CONTINUE; + } + + dip.diph.dwObj=DIJOFS_Z; + DIJoystick[JoystickCount]->SetProperty(DIPROP_DEADZONE,&dip.diph); + + dir.diph.dwSize=sizeof(DIPROPRANGE); + dir.diph.dwHeaderSize=sizeof(DIPROPHEADER); + dir.diph.dwHow=DIPH_BYOFFSET; + dir.lMin=-1000; + dir.lMax=1000; + + dir.diph.dwObj=DIJOFS_X; + + if (FAILED(DIJoystick[JoystickCount]->SetProperty(DIPROP_RANGE,&dir.diph))) + { + return DIENUM_CONTINUE; + } + + dir.diph.dwObj=DIJOFS_Y; + + if (FAILED(DIJoystick[JoystickCount]->SetProperty(DIPROP_RANGE,&dir.diph))) + { + return DIENUM_CONTINUE; + } + + dir.diph.dwObj=DIJOFS_Z; + DIJoystick[JoystickCount]->SetProperty(DIPROP_RANGE,&dir.diph); + + dir.diph.dwObj=DIJOFS_RX; + DIJoystick[JoystickCount]->SetProperty(DIPROP_RANGE,&dir.diph); + + dir.diph.dwObj=DIJOFS_RY; + DIJoystick[JoystickCount]->SetProperty(DIPROP_RANGE,&dir.diph); + + dir.diph.dwObj=DIJOFS_RZ; + DIJoystick[JoystickCount]->SetProperty(DIPROP_RANGE,&dir.diph); + + #ifdef REPORT + + DIDEVCAPS ddc; + DIDEVICEINSTANCE ddi; + + ddi.dwSize=sizeof(DIDEVICEINSTANCE); + DIJoystick[JoystickCount]->GetDeviceInfo(&ddi); + + REP_IN + "ジョイスティック = No.%d / %s / ",JoystickCount+1,ddi.tszProductName + REP_OUT + + ddc.dwSize=sizeof(DIDEVCAPS); + DIJoystick[JoystickCount]->GetCapabilities(&ddc); + + REP_IN + "%d 軸 / %d ボタン",ddc.dwAxes,ddc.dwButtons + REP_OUT + + if (ddc.dwPOVs) + { + REP_IN + " / %d POV",ddc.dwPOVs + REP_OUT + } + + if (ddc.dwFlags&DIDC_FORCEFEEDBACK) + { + REP_IN + " / フォースフィードバック" + REP_OUT + } + + if (ddc.dwFlags&(DIDC_POLLEDDATAFORMAT|DIDC_POLLEDDEVICE)) + { + REP_IN + " / バッファリング性能低下" + REP_OUT + } + + REP_IN + "\n" + REP_OUT + + #endif + + // ジョイスティックの数に加算 + JoystickCount++; + + return DIENUM_CONTINUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 入力デバイスの状態をリストに保存 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::GetInputDevice(void) +{ + static int j; + static HRESULT ret; + static DWORD count,i; + static POINT pt; + + // アクティブ状態の場合 + if (_WindowActive) + { + // キーボードデバイスが正常な場合 + if (InputDevice&USE_KEYBOARD && DIKeyboard) + { + ret=DIERR_INPUTLOST; + + // キーボードバッファから読み込み + while (ret!=DI_OK) + { + InputCount=INPUTCHECK_MAX; + + ret=DIKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), + InputData,&InputCount,0); + + if (ret!=DI_OK) DIKeyboard->Acquire(); + } + } + else + { + InputCount=0; + } + + // マウスデバイスが正常で、バッファに余裕がある場合 + if (InputDevice&(USE_MOUSE_ABS|USE_MOUSE_REL) && + InputCountGetDeviceData(sizeof(DIDEVICEOBJECTDATA), + &InputData[InputCount],&count,0); + + if (ret!=DI_OK) DIMouse->Acquire(); + } + + // ウィンドウ表示で絶対座標を要求された場合 + if (!_FullScreen && InputDevice&USE_MOUSE_ABS) + { + // 現在のマウスカーソル位置を取得 + GetCursorPos(&pt); + } + + // 仮想コードに変換 + for (i=InputCount;i=DIMOFS_BUTTON0 && + InputData[i].dwOfs<=DIMOFS_BUTTON3) + { + InputData[i].dwOfs+=0x100; + } + else + { + // 移動量が5ドット以上の場合 + if (abs(InputData[i].dwData)>=5) + { + // 2倍の移動量 + InputData[i].dwData<<=1; + } + + // 絶対座標を要求された場合 + if (InputDevice&USE_MOUSE_ABS) + { + // フルスクリーンの場合 + if (_FullScreen) + { + // DirectInputの相対座標を加算 + if (InputData[i].dwOfs==DIMOFS_X) + { + VC_INITMX+=InputData[i].dwData; + + if (MouseAreaReady) + { + if (VC_INITMXMouseMoveLockArea.right-1) + { + VC_INITMX=MouseMoveLockArea.right-1; + } + } + + InputData[i].dwData=VC_INITMX; + } + else + { + VC_INITMY+=InputData[i].dwData; + + if (MouseAreaReady) + { + if (VC_INITMYMouseMoveLockArea.bottom-1) + { + VC_INITMY=MouseMoveLockArea.bottom-1; + } + } + + InputData[i].dwData=VC_INITMY; + } + } + else + { + // Windowsのマウスカーソル位置を代入 + if (InputData[i].dwOfs==DIMOFS_X) + { + InputData[i].dwData=pt.x-_WindowX; + } + else + { + InputData[i].dwData=pt.y-_WindowY; + } + } + } + + InputData[i].dwOfs+=0x1000; + } + } + + InputCount+=count; + } + + for (j=0;jPoll(); + + #else + + DIJoystick2[j]->Poll(); + + #endif + + // ジョイスティックバッファから読み込み + while (ret!=DI_OK) + { + count=INPUTCHECK_MAX-InputCount; + + ret=DIJoystick[j]->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), + &InputData[InputCount],&count,0); + + if (ret!=DI_OK) DIJoystick[j]->Acquire(); + } + + // 仮想コードに変換 + for (i=InputCount;i=DIJOFS_BUTTON0 && + InputData[i].dwOfs<=DIJOFS_BUTTON31) + { + InputData[i].dwOfs+=0x200; + } + else + { + InputData[i].dwOfs+=0x2000; + } + + // 入力されたジョイスティックNoの保存 + InputDeviceNo[i]=j+1; + } + + InputCount+=count; + } + } + + // マウス座標のデータを作成する場合 + if (MakeMousePosition) + { + GetCursorPos(&pt); + + InputData[InputCount].dwOfs=VC_MX; + InputData[InputCount].dwData=pt.x-_WindowX; + InputData[InputCount].dwTimeStamp=NowTime; + + InputCount++; + + InputData[InputCount].dwOfs=VC_MY; + InputData[InputCount].dwData=pt.y-_WindowY; + InputData[InputCount].dwTimeStamp=NowTime; + + InputCount++; + + MakeMousePosition=FALSE; + } + } + else + { + InputCount=0; + } + + InputNow=-1; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 入力デバイス読み取りループ ※ 戻り値を使用してwhileループ -*/ +/*- -*/ +/*- BOOL OneLoop : ループ処理 -*/ +/*- 省略/TRUE = データがなくても1回だけループ -*/ +/*- FALSE = データがある時だけループ -*/ +/*- -*/ +/*- 戻り値 : TRUE = 入力信号あり -*/ +/*- FALSE = 入力信号なし -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elSystem::InputLoop(BOOL OneLoop=TRUE) +{ + static BOOL Loop=FALSE; + + if (!Loop) + { + // 入力データが終わりの場合 + if (!InputCount || ++InputNow>=(int)InputCount) + { + // 1回だけループする場合 + if (OneLoop && InputCount==0) + { + // 1回だけ空データでループ + Loop=TRUE; + Get.Device=0; + Get.Code=0xFFFF; + Get.Status=0; + Get.Time=F(0); + + return TRUE; + } + else + { + // 入力データがないので終了 + return FALSE; + } + } + } + else + { + // 空ループの終了 + Loop=FALSE; + + return FALSE; + } + + // 仮想コード・処理時間・デバイスNoの取得 + Get.Code=(WORD)InputData[InputNow].dwOfs; + Get.Time=F(NowTime-InputData[InputNow].dwTimeStamp)/F(1000); + Get.DeviceNo=InputDeviceNo[InputNow]; + + // デバイスの種類の設定 + if (Get.Code<0x100) + { + Get.Device=VC_KEYBOARD; + } + else + { + if (Get.Code<0x200 || Get.Code>=0x1000 && Get.Code<0x2000) + { + Get.Device=VC_MOUSE; + } + else + { + Get.Device=VC_JOYSTICK; + } + } + + // キーかボタンの場合 + if (Get.Code<0x1000) + { + // TRUE/FALSEに変換 + Get.Status=((InputData[InputNow].dwData&0x80)==0x80); + } + else + { + // そのままの値を使用 + Get.Status=InputData[InputNow].dwData; + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 使用する入力デバイスの指定 -*/ +/*- -*/ +/*- WORD Device : デバイスの種類 -*/ +/*- USE_KEYBOARD = キーボード -*/ +/*- USE_MOUSE_ABS = マウス ( 座標は絶対値 ) -*/ +/*- USE_MOUSE_REL = マウス ( 座標は直前からの相対値 ) -*/ +/*- USE_JOYSTICK = ジョイスティック -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::UseInputDevice(WORD Device) +{ + InputDevice=Device; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 入力状態の取得 ※ InputLoop関数を使ったループ内で使用 -*/ +/*- -*/ +/*- WORD Code : 仮想コード ( VC_…… ) -*/ +/*- int* Status : キー・ボタン・位置の状態 ( 戻り値 ) -*/ +/*- 仮想コードがキーやボタンの場合 -*/ +/*- VC_FREE = 押されていない状態 -*/ +/*- VC_PUSH = 押された瞬間 -*/ +/*- VC_PULL = 放された瞬間 -*/ +/*- VC_HOLD = 押されている状態 -*/ +/*- float* Time : 処理された時間 ( 戻り値 ) -*/ +/*- 省略 = 未使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +static float _TempTime; + +void elSystem::GetInput(WORD Code,int* Status,float *Time=&_TempTime) +{ + // 直前の状態が1フレームだけ有効な場合、次に関連する状態を代入 + if (*Status==VC_PUSH) *Status=VC_HOLD; + if (*Status==VC_PULL) *Status=VC_FREE; + + // マウスが相対座標の場合は初期化 + if (InputDevice&USE_MOUSE_REL) + { + if (Code>=VC_MX && Code<=VC_MZ) *Status=0; + } + + // 指定された仮想コードと同じ場合 + if (Get.Code==Code) + { + // キーボードの場合 + if (Get.Device==VC_KEYBOARD) + { + // 押されている場合 + if (Get.Status) + { + *Status=VC_PUSH; + } + else + { + *Status=VC_PULL; + } + } + // マウスの場合 + else if (Get.Device==VC_MOUSE) + { + // 位置の場合 + if (Get.Code>=VC_MX) + { + // 相対移動量が5ドット以上の場合 + if (InputDevice&USE_MOUSE_REL && abs(Get.Status)>=5) + { + // 2倍の移動量 + *Status=Get.Status<<1; + } + else + { + // 通常の移動量または絶対位置 + *Status=Get.Status; + } + } + // ボタンの場合 + else + { + // 押されている場合 + if (Get.Status) + { + *Status=VC_PUSH; + } + else + { + *Status=VC_PULL; + } + } + } + // ジョイスティックの場合 + else if (Get.Device==VC_JOYSTICK) + { + // 位置の場合 + if (Get.Code>=VC_JX) + { + *Status=Get.Status; + } + // ボタンの場合 + else + { + // 押されている場合 + if (Get.Status) + { + *Status=VC_PUSH; + } + else + { + *Status=VC_PULL; + } + } + } + } + + // 処理された時間 + *Time=Get.Time; +} + +#endif + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ディスク空き容量の取得 -*/ +/*- -*/ +/*- char Drive : ドライブ名 ( 'C'など ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +DWORD elSystem::FreeDisk(char Drive) +{ + char Buffer[8]; + + DWORD Sec,Byte,Free,All; + DWORD Space; + + strcpy(Buffer,"?:\\"); + + Buffer[0]=Drive; + + GetDiskFreeSpace(Buffer,&Sec,&Byte,&Free,&All); + + Space=Sec*Byte*Free; + + return Space; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- メモリ空き容量の取得 -*/ +/*- -*/ +/*- 戻り値 : 空きバイト数 ( DWORD型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +DWORD elSystem::FreeMemory(void) +{ + static MEMORYSTATUS Mem; + + Mem.dwLength=sizeof(MEMORYSTATUS); + GlobalMemoryStatus(&Mem); + + return Mem.dwAvailPhys; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マウスカーソルの移動 -*/ +/*- -*/ +/*- int x : X座標 -*/ +/*- int y : Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::MouseMove(int x,int y) +{ + SetCursorPos(x+_WindowX,y+_WindowY); + + #ifdef DIRECTINPUT + + // マウスカーソルが絶対座標の場合 + if (InputDevice&USE_MOUSE_ABS) + { + // 初期位置をGet構造体に作成 + MakeMousePosition=TRUE; + + VC_INITMX=x; + VC_INITMY=y; + } + + #endif +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ディレクトリィの取得 -*/ +/*- -*/ +/*- BOOL Install : ディレクトリィの種類 -*/ +/*- 省略/FALSE = カレントディレクトリィ -*/ +/*- TRUE = インストール先ディレクトリィ -*/ +/*- -*/ +/*- 戻り値 : ディレクトリィ名 ( char*型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +char* elSystem::Directory(BOOL Install=FALSE) +{ + static int i,j; + static char Buffer[256]; + static char InstName[128]; + + // カレントディレクトリィの取得 + GetModuleFileName(_Instance,Buffer,256); + + for (i=strlen(Buffer);Buffer[i]!='\\';i--) Buffer[i]=NULL; + + // インストール先を要求している場合 + if (Install && InstallDirectory[0]!=NULL) + { + // 右端から2個目の「\」を検索 + for (i=strlen(Buffer)-2;Buffer[i]!='\\' && i>=0;i--); + + // ディレクトリィ名が有効な場合 + if (i>=0) + { + // ディレクトリィ名の取得 + for (i++,j=0;i<=(int)strlen(Buffer);i++,j++) InstName[j]=Buffer[i]; + } + + strcpy(Buffer,InstallDirectory); + strcat(Buffer,"\\"); + strcat(Buffer,InstName); + } + + return Buffer; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- コマンドラインからパラメーターの取得 -*/ +/*- -*/ +/*- 戻り値 : パラメーター ( char*型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +char* elSystem::Parameter(void) +{ + return _CommandLine; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定時間だけシステム停止 -*/ +/*- -*/ +/*- int Time : 待ち時間 ( ミリ秒 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::Stop(int Time) +{ + WaitTime[WAIT_MAX-1]=timeGetTime()+(ULONG)Time; + + while (timeGetTime()<=WaitTime[WAIT_MAX-1]); + + elSystem::InitFrame(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- キーボードのロック -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::LockKey(void) +{ + KeyboardLock=TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- キーボードのロック解除 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::UnlockKey(void) +{ + KeyboardLock=FALSE; + + PushKey=NULL; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 画面のカラービットの取得 -*/ +/*- -*/ +/*- 戻り値 : カラービット数 ( int型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elSystem::ColorBit(void) +{ + HDC hdc; + int Bit; + + hdc=GetDC(hwnd); + + Bit=GetDeviceCaps(hdc,BITSPIXEL); + + ReleaseDC(hwnd,hdc); + + return Bit; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 画面がウィンドウ表示状態かチェック -*/ +/*- -*/ +/*- 戻り値 : TRUE = ウィンドウ状態 -*/ +/*- FALSE = フルスクリーン状態 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elSystem::WindowMode(void) +{ + if (_FullScreen) + { + return FALSE; + } + else + { + return TRUE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マウスカーソルの移動範囲の設定 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::MouseArea(int X1,int Y1,int X2,int Y2) +{ + RECT rect; + + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + ClipCursor(&rect); + + MouseAreaReady=TRUE; + + #ifdef DIRECTINPUT + + MouseMoveLockArea=rect; + + #endif +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マウスカーソルの移動範囲をウィンドウ内に設定 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::WindowMouseArea(void) +{ + if (_FullScreen) + { + elSystem::MouseArea(0,0,elDraw::Width,elDraw::Height); + } + else + { + elSystem::MouseArea(_WindowX,_WindowY, + _WindowX+elDraw::Width,_WindowY+elDraw::Height); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マウスカーソルの移動範囲の解除 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::ClearMouseArea(void) +{ + ClipCursor(NULL); + + MouseAreaReady=FALSE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マウスカーソルの移動範囲の設定状態の取得 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 設定あり -*/ +/*- FALSE = 設定なし -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elSystem::GetMouseArea(void) +{ + return MouseAreaReady; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 画面モードをファイルに書き込み -*/ +/*- -*/ +/*- char* FileName : ファイル名 -*/ +/*- int Mode : 画面モード -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// 画面モード +static const int FULLSCREEN_MODE=1; // フルスクリーン +static const int WINDOW_MODE=2; // ウィンドウ + +void elSystem::SaveScreenMode(char* FileName,int Mode) +{ + char Buffer[256]; + + strcpy(Buffer,elSystem::Directory(TRUE)); + strcat(Buffer,FileName); + + if ((_Fpt=fopen(Buffer,"wt"))!=NULL) + { + fprintf(_Fpt,"%d",Mode); + fclose(_Fpt); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 画面モードをファイルから読み込み -*/ +/*- -*/ +/*- char* FileName : ファイル名 -*/ +/*- -*/ +/*- 戻り値 : 画面モード ( int型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elSystem::LoadScreenMode(char* FileName) +{ + char Buffer[256]; + int Mode; + + strcpy(Buffer,elSystem::Directory(TRUE)); + strcat(Buffer,FileName); + + if ((_Fpt=fopen(Buffer,"rt"))!=NULL) + { + fscanf(_Fpt,"%d",&Mode); + fclose(_Fpt); + } + + return Mode; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- MIDIモードをファイルに書き込み -*/ +/*- -*/ +/*- char* FileName : ファイル名 -*/ +/*- int Mode : MIDIモード -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// MIDIモード +static const int FM_MODE=0; // FM音源 +static const int MIDI_MODE=1; // MIDI音源 + +void elSystem::SaveMidiMode(char* FileName,int Mode) +{ + char Buffer[256]; + + strcpy(Buffer,elSystem::Directory(TRUE)); + strcat(Buffer,FileName); + + if ((_Fpt=fopen(Buffer,"wt"))!=NULL) + { + fprintf(_Fpt,"%d",Mode); + fclose(_Fpt); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- MIDIモードをファイルから読み込み -*/ +/*- -*/ +/*- char* FileName : ファイル名 -*/ +/*- -*/ +/*- 戻り値 : MIDIモード ( int型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elSystem::LoadMidiMode(char* FileName) +{ + char Buffer[256]; + int Mode; + + strcpy(Buffer,elSystem::Directory(TRUE)); + strcat(Buffer,FileName); + + if ((_Fpt=fopen(Buffer,"rt"))!=NULL) + { + fscanf(_Fpt,"%d",&Mode); + fclose(_Fpt); + } + + return Mode; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 日付の取得 -*/ +/*- -*/ +/*- int* Year : 年 -*/ +/*- int* Month : 月 -*/ +/*- int* Day : 日 -*/ +/*- char* Week : 曜日 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::GetDate(int* Year,int* Month,int* Day,char* Week) +{ + SYSTEMTIME SysTime; + const char WeekData[7][3]={ "日","月","火","水","木","金","土" }; + + GetLocalTime(&SysTime); + + *Year=SysTime.wYear; + *Month=SysTime.wMonth; + *Day=SysTime.wDay; + strcpy(Week,WeekData[SysTime.wDayOfWeek]); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 時刻の取得 -*/ +/*- -*/ +/*- int* Hour : 時 -*/ +/*- int* Minute : 分 -*/ +/*- int* Second : 秒 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::GetTime(int* Hour,int* Minute,int* Second) +{ + SYSTEMTIME SysTime; + + GetLocalTime(&SysTime); + + *Hour=SysTime.wHour; + *Minute=SysTime.wMinute; + *Second=SysTime.wSecond; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- キーカウントの設定と初期化 -*/ +/*- -*/ +/*- UINT Code : アスキーコード or 仮想キーコード -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::SetPullCount(UINT Code) +{ + _PullKey=Code; + _PullCount=0; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- キーカウントの取得 -*/ +/*- -*/ +/*- 戻り値 : キーが放された回数 ( int型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elSystem::GetPullCount(void) +{ + return _PullCount; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- IME表示の切り換え -*/ +/*- -*/ +/*- BOOL Flag : TRUE = 表示あり ( 使用可 ) -*/ +/*- FALSE = 表示なし ( 使用不可 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSystem::IME(BOOL Flag) +{ + WINNLSEnableIME(NULL,Flag); + + StatusIME=Flag; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カラービットによる警告メッセージの表示 ( ウィンドウ状態 ) -*/ +/*- -*/ +/*- char* FileName : 画面モード保存用ファイル名 -*/ +/*- 省略 = 警告メッセージのみ表示 -*/ +/*- 指定あり = フルスクリーンへの切り換え確認あり -*/ +/*- NO_UPDATE = ファイル更新なしで切り換え確認 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 画面の色数がカラービットを満たしている -*/ +/*- FALSE = 満たしていない ( 要プログラム終了 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +#define NO_UPDATE "*" + +BOOL elSystem::WarningColorBit(char* FileName="") +{ + char Buffer[256],Format[256]; + char ColorList[4][7]={"16","256","65536","1670万"}; + int ColorListNo; + + // カラービットの確認 + switch (elDraw::ColorBit) + { + case 8: + { + ColorListNo=1; + + break; + } + + case 16: + { + ColorListNo=2; + + break; + } + + case 24: + case 32: + { + ColorListNo=3; + + break; + } + + default: + { + ColorListNo=0; + + break; + } + } + + // 16色以下を要求した場合、メッセージの表示なし + if (ColorListNo==0) return TRUE; + + // ウィンドウ状態でカラービットを満たしていない場合 + if (elSystem::WindowMode() && elSystem::ColorBit()SetCooperativeLevel(hwnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN| + DDSCL_ALLOWREBOOT); + + #ifdef REPORT + + REP_IN + "フルスクリーン表示 / " + REP_OUT + + #endif + } + else + { + ddret=DDObject->SetCooperativeLevel(hwnd,DDSCL_NORMAL); + + #ifdef REPORT + + REP_IN + "ウィンドウ表示 / " + REP_OUT + + #endif + + #ifdef DIRECT3D + + if (_SetWindow&RUN_LOWVRAM) + { + memory=DDSCAPS_SYSTEMMEMORY; + } + + #endif + } + + if (ddret!=DD_OK) + { + #ifndef SAVER + + return elDraw::Error("elDraw::Screen", + "フルスクリーン化できません",ddret); + + #else + + return FALSE; + + #endif + } + + // 解像度の変更 + if (_FullScreen) + { + #ifdef NEWCODE + + ddret=DDObject->SetDisplayMode(Width,Height,ColorBit,0,0); + + #else + + ddret=DDObject->SetDisplayMode(Width,Height,ColorBit); + + #endif + + // 解像度変更に失敗した場合 + if (ddret!=DD_OK) + { + // 次に優先するカラービット数が指定されていた場合 + if (RetryColorBit1) + { + ColorBit=RetryColorBit1; + + #ifdef NEWCODE + + ddret=DDObject->SetDisplayMode(Width,Height,ColorBit,0,0); + + #else + + ddret=DDObject->SetDisplayMode(Width,Height,ColorBit); + + #endif + + // 解像度変更に失敗した場合 + if (ddret!=DD_OK) + { + // 最も優先度が低いカラービット数が指定されていた場合 + if (RetryColorBit2) + { + ColorBit=RetryColorBit2; + + #ifdef NEWCODE + + ddret=DDObject->SetDisplayMode(Width,Height,ColorBit,0,0); + + #else + + ddret=DDObject->SetDisplayMode(Width,Height,ColorBit); + + #endif + } + } + } + + // 全ての解像度変更に失敗した場合 + if (ddret!=DD_OK) + { + #ifndef SAVER + + return elDraw::Error("elDraw::Screen", + "解像度が変更できません",ddret); + + #else + + return FALSE; + + #endif + } + } + } + // ウィンドウ表示の場合 + else + { + // デスクトップのカラービット数を取得 + ColorBit=elSystem::ColorBit(); + } + + #ifdef REPORT + + REP_IN + "%dビットカラー\n",ColorBit + REP_OUT + + memset(&RepHal,0x00,sizeof(DDCAPS)); + RepHal.dwSize=sizeof(DDCAPS); + memset(&RepHel,0x00,sizeof(DDCAPS)); + RepHel.dwSize=sizeof(DDCAPS); + DDObject->GetCaps(&RepHal,&RepHel); + + REP_IN + "使用可能VRAM = %2.3f MB\n\n",F(RepHal.dwVidMemFree)/F(1024)/F(1024) + REP_OUT + + #endif + + // 表画面の作成 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + ddsd.dwFlags=DDSD_CAPS; + ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE|memory; + + #ifdef REPORT + + REP_IN + "表画面の生成 = " + REP_OUT + + if (memory) + { + REP_IN + "RAM\n" + REP_OUT + } + else + { + REP_IN + "VRAM\n" + REP_OUT + } + + #endif + + ddret=DDObject->CreateSurface(&ddsd,&DDFront,NULL); + + if (ddret!=DD_OK) + { + return elDraw::Error("elDraw::Screen", + "表画面が生成できません",ddret); + } + + // 裏画面の作成 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH; + ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|memory; + ddsd.dwWidth=Width; + ddsd.dwHeight=Height; + + #ifdef DIRECT3D + + if (el3D::Mode&DRAW_BACKLAYER) + { + ddsd.ddsCaps.dwCaps|=DDSCAPS_3DDEVICE; + } + + #endif + + #ifdef DIRECT3D_IM + + ddsd.ddsCaps.dwCaps|=DDSCAPS_3DDEVICE; + ddsd.ddsCaps.dwCaps2|=DDSCAPS2_HINTANTIALIASING; + + #endif + + ddret=DDObject->CreateSurface(&ddsd,&DDBack,NULL); + + #ifdef REPORT + + REP_IN + "裏画面の生成 = " + REP_OUT + + if (memory) + { + REP_IN + "RAM\n" + REP_OUT + } + else + { + REP_IN + "VRAM\n" + REP_OUT + } + + #endif + + #ifdef REPORT + + memset(&RepHal,0x00,sizeof(DDCAPS)); + RepHal.dwSize=sizeof(DDCAPS); + memset(&RepHel,0x00,sizeof(DDCAPS)); + RepHel.dwSize=sizeof(DDCAPS); + DDObject->GetCaps(&RepHal,&RepHel); + + REP_IN + "画面生成後のVRAM空き = %2.3f MB\n\n",F(RepHal.dwVidMemFree)/F(1024)/F(1024) + REP_OUT + + #endif + + if (ddret!=DD_OK) + { + return elDraw::Error("elDraw::Screen", + "裏画面が生成できません",ddret); + } + + // Clipの作成 + if (!_FullScreen) + { + #ifdef REPORT + + REP_IN + "クリップの生成 = " + REP_OUT + + #endif + + ddret=DDObject->CreateClipper(0,&DDClip,NULL); + + if (ddret!=DD_OK) + { + return elDraw::Error("elDraw::Screen", + "クリップが生成できません",ddret); + } + + #ifdef REPORT + + REP_IN + "OK / " + REP_OUT + + #endif + + ddret=DDClip->SetHWnd(0,hwnd); + + if (ddret!=DD_OK) + { + return elDraw::Error("elDraw::Screen", + "クリップにウィンドウハンドルを設定できません", + ddret); + } + + ddret=DDFront->SetClipper(DDClip); + + if (ddret!=DD_OK) + { + return elDraw::Error("elDraw::Screen", + "表画面をクリップできません", + ddret); + } + + #ifdef REPORT + + REP_IN + "表画面\n\n" + REP_OUT + + #endif + } + + // Bufferスプライトの作成 + if (Memory==CREATE_SCREEN_ONLY) + { + memory=DDSCAPS_SYSTEMMEMORY; + } + + #if defined(DIRECT3D) || defined(DIRECT3D_IM) + + memory=DDSCAPS_SYSTEMMEMORY; + + #endif + + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH; + ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|memory; + ddsd.dwWidth=Width; + ddsd.dwHeight=Height; + + ddret=DDObject->CreateSurface(&ddsd,&Sprite[BUFFER_SPRITE].Object,NULL); + + #ifdef REPORT + + REP_IN + "描画バッファ用スプライトの生成(No.0) = " + REP_OUT + + if (memory) + { + REP_IN + "RAM\n" + REP_OUT + } + else + { + REP_IN + "VRAM\n" + REP_OUT + } + + #endif + + if (ddret!=DD_OK) + { + return elDraw::Error("elDraw::Screen", + "Bufferスプライトが生成できません",ddret); + } + + DDSetColorKey(Sprite[BUFFER_SPRITE].Object,RGB(0,0,0)); + + strcpy(Sprite[BUFFER_SPRITE].FileName,"内部用1"); + Sprite[BUFFER_SPRITE].PackData=FALSE; + Sprite[BUFFER_SPRITE].Memory=LOAD_DEFAULT; + Sprite[BUFFER_SPRITE].Color=RGB(0,0,0); + Sprite[BUFFER_SPRITE].SizeX=Width; + Sprite[BUFFER_SPRITE].SizeY=Height; + + // Screenスプライトの作成 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH; + ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|memory; + ddsd.dwWidth=Width; + ddsd.dwHeight=Height; + + ddret=DDObject->CreateSurface(&ddsd,&Sprite[SCREEN_SPRITE].Object,NULL); + + #ifdef REPORT + + REP_IN + "画面退避用スプライトの生成(No.1) = " + REP_OUT + + if (memory) + { + REP_IN + "RAM\n" + REP_OUT + } + else + { + REP_IN + "VRAM\n" + REP_OUT + } + + #endif + + if (ddret!=DD_OK) + { + return elDraw::Error("elDraw::Screen", + "Screenスプライトが生成できません",ddret); + } + + DDSetColorKey(Sprite[SCREEN_SPRITE].Object,RGB(0,0,0)); + + strcpy(Sprite[SCREEN_SPRITE].FileName,"内部用2"); + Sprite[SCREEN_SPRITE].PackData=FALSE; + Sprite[SCREEN_SPRITE].Memory=LOAD_DEFAULT; + Sprite[SCREEN_SPRITE].Color=RGB(0,0,0); + Sprite[SCREEN_SPRITE].SizeX=Width; + Sprite[SCREEN_SPRITE].SizeY=Height; + + // Fontスプライトの作成 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH; + ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY; + ddsd.dwWidth=Width; + ddsd.dwHeight=Height; + + ddret=DDObject->CreateSurface(&ddsd,&Sprite[FONT_SPRITE].Object,NULL); + + #ifdef REPORT + + REP_IN + "フォント用スプライトの生成(No.2) = RAM\n" + REP_OUT + + #endif + + if (ddret!=DD_OK) + { + return elDraw::Error("elDraw::Screen", + "Fontスプライトが生成できません",ddret); + } + + DDSetColorKey(Sprite[FONT_SPRITE].Object,RGB(0,0,0)); + + strcpy(Sprite[FONT_SPRITE].FileName,"内部用3"); + Sprite[FONT_SPRITE].PackData=FALSE; + Sprite[FONT_SPRITE].Memory=LOAD_DEFAULT; + Sprite[FONT_SPRITE].Color=RGB(0,0,0); + Sprite[FONT_SPRITE].SizeX=Width; + Sprite[FONT_SPRITE].SizeY=Height; + + // Fontバッファスプライトの作成 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH; + ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY; + ddsd.dwWidth=Width; + ddsd.dwHeight=Height; + + ddret=DDObject->CreateSurface(&ddsd,&Sprite[FONTBUFFER_SPRITE].Object,NULL); + + #ifdef REPORT + + REP_IN + "フォントバッファ用スプライトの生成(No.3) = RAM\n" + REP_OUT + + #endif + + if (ddret!=DD_OK) + { + return elDraw::Error("elDraw::Screen", + "Fontバッファスプライトが生成できません",ddret); + } + + DDSetColorKey(Sprite[FONTBUFFER_SPRITE].Object,RGB(0,0,0)); + + strcpy(Sprite[FONTBUFFER_SPRITE].FileName,"内部用4"); + Sprite[FONTBUFFER_SPRITE].PackData=FALSE; + Sprite[FONTBUFFER_SPRITE].Memory=LOAD_DEFAULT; + Sprite[FONTBUFFER_SPRITE].Color=RGB(0,0,0); + Sprite[FONTBUFFER_SPRITE].SizeX=Width; + Sprite[FONTBUFFER_SPRITE].SizeY=Height; + + #ifdef REPORT + + memset(&RepHal,0x00,sizeof(DDCAPS)); + RepHal.dwSize=sizeof(DDCAPS); + memset(&RepHel,0x00,sizeof(DDCAPS)); + RepHel.dwSize=sizeof(DDCAPS); + DDObject->GetCaps(&RepHal,&RepHel); + + REP_IN + "内部スプライト生成後のVRAM空き = %2.3f MB\n\n", + F(RepHal.dwVidMemFree)/F(1024)/F(1024) + REP_OUT + + #endif + + // 拡大縮小機能のチェック + memset(&Hal,0x00,sizeof(DDCAPS)); + Hal.dwSize=sizeof(DDCAPS); + memset(&Hel,0x00,sizeof(DDCAPS)); + Hel.dwSize=sizeof(DDCAPS); + + DDObject->GetCaps(&Hal,&Hel); + + if (SearchVideoCard && Hal.dwCaps&DDCAPS_BLTSTRETCH || + !SearchVideoCard && Hel.dwCaps&DDCAPS_BLTSTRETCH) + { + UseStretch=TRUE; + + #ifdef REPORT + + REP_IN + "ハードウェアサポート = 拡大縮小\n" + REP_OUT + + #endif + } + else + { + UseStretch=FALSE; + } + + // ピクセル情報の取得 + memset(&format,0x00,sizeof(DDPIXELFORMAT)); + format.dwSize=sizeof(DDPIXELFORMAT); + + ddret=DDBack->GetPixelFormat(&format); + + if (ddret==DD_OK) + { + // RGBビット数と、RGBシフト数の取得 + BitR=format.dwRBitMask; + ShiftR=0; + + while ((BitR&0x0001)==0x0000) + { + BitR>>=1; + ShiftR++; + } + + BitG=format.dwGBitMask; + ShiftG=0; + + while ((BitG&0x0001)==0x0000) + { + BitG>>=1; + ShiftG++; + } + + BitB=format.dwBBitMask; + ShiftB=0; + + while ((BitB&0x0001)==0x0000) + { + BitB>>=1; + ShiftB++; + } + + // RGB:555に統一したRGBシフト数の取得 + ShiftR2=ShiftR+(BitR==0x3F); + ShiftG2=ShiftG+(BitG==0x3F); + ShiftB2=ShiftB+(BitB==0x3F); + + // RGBそれぞれの上位1ビットを0にしたマスクの生成 + MaskR=BitR>>1; + MaskG=BitG>>1; + MaskB=BitB>>1; + + MaskRGB=(MaskR<>=1; + if (gg==64) green>>=1; + if (bb==64) blue>>=1; + + GetRGB[(i<=0) + { + x+=i-b; + } + + if (j-(31-b)>=0) + { + x+=j-(31-b); + } + + switch (c) + { + case 0: x<<=sr; break; + case 1: x<<=sg; break; + case 2: x<<=sb; break; + } + + BlendList[(c<<15)+(b<<10)+(i<<5)+j]=x; + } + } + } + } + + // 加算ブレンド合成結果リストの作成 + for (c=0;c<3;c++) + { + for (b=0;b<32;b++) + { + for (i=0;i<32;i++) + { + for (j=0;j<32;j++) + { + x=0; + + if (i-b>0) + { + x=i-b; + } + + x+=j; + if (x>31) x=31; + + switch (c) + { + case 0: x<<=sr; break; + case 1: x<<=sg; break; + case 2: x<<=sb; break; + } + + AddBlendList[(c<<15)+(b<<10)+(i<<5)+j]=x; + } + } + } + } + + // 減算ブレンド合成結果リストの作成 + for (c=0;c<3;c++) + { + for (i=0;i<32;i++) + { + for (j=0;j<32;j++) + { + x=0; + + if (i-j>0) + { + x=i-j; + } + + switch (c) + { + case 0: x<<=sr; break; + case 1: x<<=sg; break; + case 2: x<<=sb; break; + } + + DelBlendList[(c<<10)+(i<<5)+j]=x; + } + } + } + + // グレースケール計算結果リストの作成 + for (i=0;i<32;i++) + { + for (j=0;j<32;j++) + { + for (k=0;k<32;k++) + { + GrayList[i+j+k]=(i+j+k)/3; + } + } + } + + // elEffect::Fire関数用ランダムリストの算出 + for (i=0;i<10000;i++) + { + elEffect::FireRandomList[i]=rand()%3; + } + } + + // スプライト情報の初期化 + for (i=4;iCreateSurface(&ddsd,&DD3D,NULL); + + if (ddret!=DD_OK) + { + return elDraw::Error("elDraw::Screen", + "3Dスプライトが生成できません",ddret); + } + } + + // Z Bufferスプライトの作成 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + ddsd.dwFlags=DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_ZBUFFERBITDEPTH; + ddsd.dwWidth=Width; + ddsd.dwHeight=Height; + ddsd.ddsCaps.dwCaps=DDSCAPS_ZBUFFER|el3D::ZBufferMemory; + ddsd.dwZBufferBitDepth=el3D::ZBufferSize; + + #ifdef REPORT + + REP_IN + "Zバッファの生成 = %dビット / ",el3D::ZBufferSize + REP_OUT + + if (el3D::ZBufferMemory==DDSCAPS_VIDEOMEMORY) + { + REP_IN + "VRAM\n" + REP_OUT + } + else + { + REP_IN + "RAM\n" + REP_OUT + } + + #endif + + ddret=DDObject->CreateSurface(&ddsd,&DDZBuffer,NULL); + + if (ddret!=DD_OK) + { + return elDraw::Error("elDraw::Screen", + "Z Bufferが生成できません",ddret); + } + + ddret=DDBack->AddAttachedSurface(DDZBuffer); + + if (ddret!=DD_OK) + { + if (ddret==DDERR_CANNOTATTACHSURFACE) + { + return elDraw::Error("elDraw::Screen", + "裏画面(RAM)にZ Bufferを接続できません",ddret); + } + else + { + return elDraw::Error("elDraw::Screen", + "Z Bufferが接続できません",ddret); + } + } + + #ifdef REPORT + + REP_IN + "レンダリング先 = " + REP_OUT + + if (el3D::Mode&DRAW_BACKLAYER) + { + REP_IN + "裏画面(直接)\n" + REP_OUT + } + else + { + REP_IN + "3Dスプライト(間接)\n" + REP_OUT + } + + #endif + + // el3Dクラスの初期化 + el3D::Init(); + + #endif + + #ifdef DIRECT3D_IM + + // el4Dクラスの初期化 + el4D::Init(); + + #endif + + // elSoundクラスの初期化 + #ifndef SAVER + + elSound::Init(); + + #else + + if (!elSound::Init()) return FALSE; + + #endif + + // elSound::Init関数に含まれない変数を初期化 + for (i=0;i %s関数 / %s\n",Function,Message + REP_OUT + + if (Code) + { + REP_IN + " <詳 細> %s ( DirectX SDKのヘルプで確認 )\n",GetError(Code) + REP_OUT + } + + REP_IN + "\n" + REP_OUT + + #endif + + if (DDObject) + { + DDObject->FlipToGDISurface(); + } + + elSound::Beep(); + MessageBox(hwnd,Buffer,"エラー発生",MB_OK|MB_SYSTEMMODAL|MB_ICONEXCLAMATION); + + ErrorCheck=TRUE; + + return FALSE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- エラー発生状態の取得 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 以前にエラーが発生している -*/ +/*- FALSE = 全て正常 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw::Error(void) +{ + return ErrorCheck; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- エラー発生状態の取得とプログラム終了 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 以前にエラーが発生していたのでプログラム終了済 -*/ +/*- FALSE = 全て正常 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw::ErrorExit(void) +{ + if (ErrorCheck) elDraw::Exit(); + + return ErrorCheck; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ビットマップの読み込み -*/ +/*- -*/ +/*- char* FileName : BMPファイル名またはリソース名 -*/ +/*- int Memory : スプライトの保存先 -*/ +/*- 省略/LOAD_DEFAULT = VRAMかRAMに保存 -*/ +/*- LOAD_RAM = RAMに保存 -*/ +/*- LOAD_TEXTURE = テクスチャー用 -*/ +/*- -*/ +/*- 戻り値 : スプライト情報 ( DDOBJ型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +DDOBJ elDraw::LoadObject(char* FileName,int Memory=LOAD_DEFAULT) +{ + DDOBJ ObjDD; + DDSURFACEDESC ddsd; + HRESULT ddret; + HBITMAP hbm; + BITMAP bm; + BOOL Error; + char Buffer[256]; + int i; + + #ifdef REPORT + + REP_IN + "LoadObject = %s / ",FileName + REP_OUT + + #endif + + if (strlen(FileName)>30) + { + return (DDOBJ)elDraw::Error("elDraw::LoadObject", + "ファイル名またはリソース名が長すぎます"); + } + + ObjDD=-1; + + for (i=4;iddsd.dwWidth; + ddsd.dwWidth<<=1); + for (ddsd.dwHeight=1;(DWORD)bm.bmHeight>ddsd.dwHeight; + ddsd.dwHeight<<=1); + } + + if (Texture) + { + if (ddsd.dwWidthel4D::Texture::MaxWidth) + { + ddsd.dwWidth=el4D::Texture::MaxWidth; + } + + if (ddsd.dwHeightel4D::Texture::MaxHeight) + { + ddsd.dwHeight=el4D::Texture::MaxHeight; + } + } + + if (Texture&0002) + { + if (ddsd.dwWidth>ddsd.dwHeight) + { + ddsd.dwHeight=ddsd.dwWidth; + } + else + { + ddsd.dwWidth=ddsd.dwHeight; + } + } + } + + if (Texture==0x0000) + + #endif + + { + if (Memory==LOAD_DEFAULT) + { + ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN; + } + else + { + ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN| + DDSCAPS_SYSTEMMEMORY; + + #ifdef REPORT + + REP_IN + "RAMを要求 / " + REP_OUT + + #endif + } + } + + Sprite[ObjDD].SizeX=(WORD)ddsd.dwWidth; + Sprite[ObjDD].SizeY=(WORD)ddsd.dwHeight; + + ddret=DDObject->CreateSurface(&ddsd,&Sprite[ObjDD].Object,NULL); + + if (ddret!=DD_OK) break; + + if (SpriteLeftTop) + { + DDSetColorKey(Sprite[ObjDD].Object,0xFFFFFFFF); + + Sprite[ObjDD].Color=0xFFFFFFFF; + } + else + { + DDSetColorKey(Sprite[ObjDD].Object,SpriteColor); + + Sprite[ObjDD].Color=SpriteColor; + } + + ddret=DDCopyBitmap(Sprite[ObjDD].Object,hbm,0,0,0,0); + + if (ddret!=DD_OK) break; + + DeleteObject(hbm); + + Error=FALSE; + + break; + } + + if (Error) + { + return (DDOBJ)elDraw::Error("elDraw::LoadObject", + "BMPファイルを読み込めません",ddret); + } + } + else + { + if (SpriteLeftTop) + { + DDSetColorKey(Sprite[ObjDD].Object,0xFFFFFFFF); + + Sprite[ObjDD].Color=0xFFFFFFFF; + } + else + { + DDSetColorKey(Sprite[ObjDD].Object,SpriteColor); + + Sprite[ObjDD].Color=SpriteColor; + } + } + + #ifdef REPORT + + memset(&RepHal,0x00,sizeof(DDCAPS)); + RepHal.dwSize=sizeof(DDCAPS); + memset(&RepHel,0x00,sizeof(DDCAPS)); + RepHel.dwSize=sizeof(DDCAPS); + DDObject->GetCaps(&RepHal,&RepHel); + + REP_IN + "VRAM %2.3f MB\n", + F(RepHal.dwVidMemFree)/F(1024)/F(1024) + REP_OUT + + #endif + + return ObjDD; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 空スプライトの生成 -*/ +/*- -*/ +/*- int Sx : Xサイズ -*/ +/*- 省略 = 画面のXサイズ -*/ +/*- int Sy : Yサイズ -*/ +/*- 省略 = 画面のYサイズ -*/ +/*- int Memory : スプライトの保存先 -*/ +/*- 省略/LOAD_DEFAULT = VRAMかRAMに保存 -*/ +/*- LOAD_RAM = RAMに保存 -*/ +/*- LOAD_TEXTURE = テクスチャー用 -*/ +/*- LOAD_TARGET = レンダリング先 -*/ +/*- -*/ +/*- 戻り値 : スプライト情報 ( DDOBJ型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +#ifdef DIRECT3D_IM + +static const int LOAD_TARGET=4; // レンダリング先として使用 + +#endif + +DDOBJ elDraw::CreateObject(int Sx=Width,int Sy=Height,int Memory=LOAD_DEFAULT) +{ + DDOBJ ObjDD; + DDSURFACEDESC ddsd; + HRESULT ddret; + int i; + + #ifdef REPORT + + REP_IN + "CreateObject = %d×%d / ",Sx,Sy + REP_OUT + + #endif + + ObjDD=-1; + + for (i=4;iddsd.dwWidth;ddsd.dwWidth<<=1); + for (ddsd.dwHeight=1;(DWORD)Sy>ddsd.dwHeight;ddsd.dwHeight<<=1); + } + + if (Texture) + { + if (ddsd.dwWidthel4D::Texture::MaxWidth) + { + ddsd.dwWidth=el4D::Texture::MaxWidth; + } + + if (ddsd.dwHeightel4D::Texture::MaxHeight) + { + ddsd.dwHeight=el4D::Texture::MaxHeight; + } + } + + if (Texture&0002) + { + if (ddsd.dwWidth>ddsd.dwHeight) + { + ddsd.dwHeight=ddsd.dwWidth; + } + else + { + ddsd.dwWidth=ddsd.dwHeight; + } + } + + #ifdef REPORT + + if ((DWORD)Sx!=ddsd.dwWidth || (DWORD)Sy!=ddsd.dwHeight) + { + REP_IN + "リサイズ %d×%d / ",ddsd.dwWidth,ddsd.dwHeight + REP_OUT + } + + #endif + + if (Texture==0x0000) + + #endif + + { + if (Memory==LOAD_DEFAULT) + { + ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN; + } + else + { + ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY; + + #ifdef REPORT + + REP_IN + "RAMを要求 / " + REP_OUT + + #endif + } + } + + Sprite[ObjDD].SizeX=(WORD)ddsd.dwWidth; + Sprite[ObjDD].SizeY=(WORD)ddsd.dwHeight; + + ddret=DDObject->CreateSurface(&ddsd,&Sprite[ObjDD].Object,NULL); + + if (ddret!=DD_OK) + { + return (DDOBJ)elDraw::Error("elDraw::CreateObject", + "スプライトを作成できません"); + } + + if (SpriteLeftTop) + { + DDSetColorKey(Sprite[ObjDD].Object,0xFFFFFFFF); + + Sprite[ObjDD].Color=0xFFFFFFFF; + } + else + { + DDSetColorKey(Sprite[ObjDD].Object,SpriteColor); + + Sprite[ObjDD].Color=SpriteColor; + } + + #ifdef REPORT + + memset(&RepHal,0x00,sizeof(DDCAPS)); + RepHal.dwSize=sizeof(DDCAPS); + memset(&RepHel,0x00,sizeof(DDCAPS)); + RepHel.dwSize=sizeof(DDCAPS); + DDObject->GetCaps(&RepHal,&RepHel); + + REP_IN + "VRAM %2.3f MB\n", + F(RepHal.dwVidMemFree)/F(1024)/F(1024) + REP_OUT + + #endif + + return ObjDD; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトを削除してメモリから解放 -*/ +/*- -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::FreeObject(DDOBJ ObjDD) +{ + if (Sprite[ObjDD].Object!=NULL) + { + #ifdef REPORT + + REP_IN + "FreeObject = " + REP_OUT + + REP_IN + "No.%d / ",ObjDD + REP_OUT + + #endif + + Sprite[ObjDD].Object->Release(); + Sprite[ObjDD].Object=NULL; + Sprite[ObjDD].FileName[0]=NULL; + Sprite[ObjDD].Color=RGB(0,0,0); + Sprite[ObjDD].SizeX=0; + Sprite[ObjDD].SizeY=0; + + #ifdef REPORT + + memset(&RepHal,0x00,sizeof(DDCAPS)); + RepHal.dwSize=sizeof(DDCAPS); + memset(&RepHel,0x00,sizeof(DDCAPS)); + RepHel.dwSize=sizeof(DDCAPS); + DDObject->GetCaps(&RepHal,&RepHel); + + REP_IN + "VRAM %2.3f MB\n", + F(RepHal.dwVidMemFree)/F(1024)/F(1024) + REP_OUT + + #endif + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ビットマップの交換 -*/ +/*- -*/ +/*- char* FileName : BMPファイル名またはリソース名 -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int Memory : スプライトの保存先 -*/ +/*- 省略/LOAD_DEFAULT = VRAMかRAMに保存 -*/ +/*- LOAD_RAM = RAMに保存 -*/ +/*- LOAD_TEXTURE = テクスチャー用 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw::SwapObject(char* FileName,DDOBJ ObjDD,int Memory=LOAD_DEFAULT) +{ + DDSURFACEDESC ddsd; + HRESULT ddret; + HBITMAP hbm; + BITMAP bm; + BOOL Error; + char Buffer[256]; + + #ifdef REPORT + + REP_IN + "SwapObject = %s / ",FileName + REP_OUT + + REP_IN + "No.%d / ",ObjDD + REP_OUT + + #endif + + if (strlen(FileName)>30) + { + return elDraw::Error("elDraw::SwapObject", + "ファイル名またはリソース名が長すぎます"); + } + + if (Sprite[ObjDD].Object!=NULL) + { + Sprite[ObjDD].Object->Release(); + Sprite[ObjDD].Object=NULL; + } + + strcpy(Sprite[ObjDD].FileName,FileName); + Sprite[ObjDD].PackData=FALSE; + Sprite[ObjDD].Memory=LOAD_DEFAULT; + + strcpy(Buffer,elSystem::Directory()); + strcat(Buffer,FileName); + + #ifdef DIRECT3D_IM + + WORD Texture=0x0000; + + if (Memory==LOAD_TEXTURE) + { + if (el4D::Config::Driver&DC4D_HAL) + { + Texture|=0x1000; + } + else + { + Texture|=0x2000; + } + + if (el4D::Config::Texture&DC4D_2POWERS) Texture|=0001; + if (el4D::Config::Texture&DC4D_SQUAREONLY) Texture|=0002; + } + + Sprite[ObjDD].Object=DDLoadBitmap(DDObject,Buffer,&Sprite[ObjDD].SizeX, + &Sprite[ObjDD].SizeY,Memory,Texture, + el4D::Texture::MinWidth, + el4D::Texture::MinHeight, + el4D::Texture::MaxWidth, + el4D::Texture::MaxHeight, + el4D::Texture::AtmMode,NULL); + + #else + + Sprite[ObjDD].Object=DDLoadBitmap(DDObject,Buffer,&Sprite[ObjDD].SizeX, + &Sprite[ObjDD].SizeY,Memory); + + #endif + + if (Sprite[ObjDD].Object==NULL) + { + Error=TRUE; + + while (TRUE) + { + hbm=(HBITMAP)LoadImage(GetModuleHandle(NULL),FileName,IMAGE_BITMAP, + 0,0,LR_CREATEDIBSECTION); + + if (hbm==NULL) break; + + #ifdef REPORT + + REP_IN + "リソース / " + REP_OUT + + #endif + + GetObject(hbm,sizeof(bm),&bm); + + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH; + ddsd.dwWidth=bm.bmWidth; + ddsd.dwHeight=bm.bmHeight; + + #ifdef DIRECT3D_IM + + if (Texture) + { + ddsd.dwFlags|=DDSD_TEXTURESTAGE; + ddsd.ddsCaps.dwCaps=DDSCAPS_TEXTURE; + + #ifdef REPORT + + REP_IN + "テクスチャー / " + REP_OUT + + #endif + } + + if (Texture&0x1000 && el4D::Texture::AtmMode) + { + ddsd.ddsCaps.dwCaps2|=DDSCAPS2_TEXTUREMANAGE; + } + + if (Texture&0x2000) ddsd.ddsCaps.dwCaps|=DDSCAPS_SYSTEMMEMORY; + + if (Texture&0001) + { + for (ddsd.dwWidth=1;(DWORD)bm.bmWidth>ddsd.dwWidth; + ddsd.dwWidth<<=1); + for (ddsd.dwHeight=1;(DWORD)bm.bmHeight>ddsd.dwHeight; + ddsd.dwHeight<<=1); + } + + if (Texture) + { + if (ddsd.dwWidthel4D::Texture::MaxWidth) + { + ddsd.dwWidth=el4D::Texture::MaxWidth; + } + + if (ddsd.dwHeightel4D::Texture::MaxHeight) + { + ddsd.dwHeight=el4D::Texture::MaxHeight; + } + } + + if (Texture&0002) + { + if (ddsd.dwWidth>ddsd.dwHeight) + { + ddsd.dwHeight=ddsd.dwWidth; + } + else + { + ddsd.dwWidth=ddsd.dwHeight; + } + } + + if (Texture==0x0000) + + #endif + + { + if (Memory==LOAD_DEFAULT) + { + ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN; + } + else + { + ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN| + DDSCAPS_SYSTEMMEMORY; + + #ifdef REPORT + + REP_IN + "RAMを要求 / " + REP_OUT + + #endif + } + } + + Sprite[ObjDD].SizeX=(WORD)ddsd.dwWidth; + Sprite[ObjDD].SizeY=(WORD)ddsd.dwHeight; + + ddret=DDObject->CreateSurface(&ddsd,&Sprite[ObjDD].Object,NULL); + + if (ddret!=DD_OK) break; + + if (SpriteLeftTop) + { + DDSetColorKey(Sprite[ObjDD].Object,0xFFFFFFFF); + + Sprite[ObjDD].Color=0xFFFFFFFF; + } + else + { + DDSetColorKey(Sprite[ObjDD].Object,SpriteColor); + + Sprite[ObjDD].Color=SpriteColor; + } + + ddret=DDCopyBitmap(Sprite[ObjDD].Object,hbm,0,0,0,0); + + DeleteObject(hbm); + + Error=FALSE; + + break; + } + + if (Error) + { + return elDraw::Error("elDraw::SwapObject", + "BMPファイルを読み込めません",ddret); + } + } + else + { + if (SpriteLeftTop) + { + DDSetColorKey(Sprite[ObjDD].Object,0xFFFFFFFF); + + Sprite[ObjDD].Color=0xFFFFFFFF; + } + else + { + DDSetColorKey(Sprite[ObjDD].Object,SpriteColor); + + Sprite[ObjDD].Color=SpriteColor; + } + } + + #ifdef REPORT + + memset(&RepHal,0x00,sizeof(DDCAPS)); + RepHal.dwSize=sizeof(DDCAPS); + memset(&RepHel,0x00,sizeof(DDCAPS)); + RepHel.dwSize=sizeof(DDCAPS); + DDObject->GetCaps(&RepHal,&RepHel); + + REP_IN + "VRAM %2.3f MB\n", + F(RepHal.dwVidMemFree)/F(1024)/F(1024) + REP_OUT + + #endif + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 全オブジェクトの再読み込み ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::ReloadObject(void) +{ + int i; + + DDFront->Restore(); + + if (DDBack->IsLost()!=DD_OK) + { + DDBack->Restore(); + } + + #ifdef DIRECT3D + + if (DD3D->IsLost()!=DD_OK) + { + DD3D->Restore(); + } + + if (DDZBuffer->IsLost()!=DD_OK) + { + DDZBuffer->Restore(); + } + + #endif + + #ifdef DIRECT3D_IM + + if (D3ZBuffer->IsLost()!=DD_OK) + { + D3ZBuffer->Restore(); + } + + for (i=0;iIsLost()!=DD_OK) + { + STStreamSurface->Restore(); + } + + #endif + + #ifdef DIRECTSHOW + + if (elMovieRender::DDVideo->IsLost()!=DD_OK) + { + elMovieRender::DDVideo->Restore(); + } + + #endif + + if (Sprite[BUFFER_SPRITE].Object->IsLost()!=DD_OK) + { + Sprite[BUFFER_SPRITE].Object->Restore(); + } + + if (Sprite[SCREEN_SPRITE].Object->IsLost()!=DD_OK) + { + Sprite[SCREEN_SPRITE].Object->Restore(); + } + + if (Sprite[FONT_SPRITE].Object->IsLost()!=DD_OK) + { + Sprite[FONT_SPRITE].Object->Restore(); + } + + if (Sprite[FONTBUFFER_SPRITE].Object->IsLost()!=DD_OK) + { + Sprite[FONTBUFFER_SPRITE].Object->Restore(); + } + + for (i=4;iIsLost()!=DD_OK) + { + Sprite[i].Object->Restore(); + + if (Sprite[i].FileName[0]!='*') + { + elDraw::SetSpriteColor(Sprite[i].Color); + + if (Sprite[i].PackData) + { + elDraw::SwapPack(Sprite[i].FileName,i,Sprite[i].Memory); + } + else + { + elDraw::SwapObject(Sprite[i].FileName,i,Sprite[i].Memory); + } + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 全オブジェクトの破棄 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::DestroyObject(void) +{ + int i; + + if (DDObject!=NULL) + { + for (i=0;iGetAttachedSurface(&ddscaps,&ZBuffer); + + if (ZBuffer) + { + Sprite[i].Object->DeleteAttachedSurface(0,ZBuffer); + ZBuffer->Release(); + } + + #endif + + Sprite[i].Object->Release(); + Sprite[i].Object=NULL; + Sprite[i].FileName[0]=NULL; + Sprite[i].PackData=FALSE; + Sprite[i].Memory=LOAD_DEFAULT; + Sprite[i].Color=RGB(0,0,0); + Sprite[i].SizeX=0; + Sprite[i].SizeY=0; + + #ifdef REPORT + + memset(&RepHal,0x00,sizeof(DDCAPS)); + RepHal.dwSize=sizeof(DDCAPS); + memset(&RepHel,0x00,sizeof(DDCAPS)); + RepHel.dwSize=sizeof(DDCAPS); + DDObject->GetCaps(&RepHal,&RepHel); + + REP_IN + "VRAM %2.3f MB\n", + F(RepHal.dwVidMemFree)/F(1024)/F(1024) + REP_OUT + + #endif + } + } + + if (!_FullScreen) + { + if (DDClip!=NULL) + { + DDClip->Release(); + DDClip=NULL; + } + } + + if (DDFront!=NULL) + { + DDFront->Release(); + DDFront=NULL; + } + + if (DDBack!=NULL) + { + DDBack->Release(); + DDBack=NULL; + } + + #ifdef DIRECT3D + + if (!(el3D::Mode&DRAW_BACKLAYER)) + { + if (DD3D!=NULL) + { + DD3D->Release(); + DD3D=NULL; + } + } + + if (DDZBuffer!=NULL) + { + DDZBuffer->Release(); + DDZBuffer=NULL; + } + + #endif + + if (_FullScreen) + { + DDObject->RestoreDisplayMode(); + DDObject->SetCooperativeLevel(hwnd,DDSCL_NORMAL); + } + + DDObject->Release(); + DDObject=NULL; + } + + if (_FullScreen || _FullWindow) CloseWindow(hwnd); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- パックファイルの指定 -*/ +/*- -*/ +/*- char* PackName : パックファイル名 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::SetPack(char* PackName) +{ + strcpy(PackFileName,elSystem::Directory()); + strcat(PackFileName,PackName); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ビットマップの読み込み ( パックファイル ) -*/ +/*- -*/ +/*- char* FileName : BMPファイル名 -*/ +/*- int Memory : スプライトの保存先 -*/ +/*- 省略/LOAD_DEFAULT = VRAMかRAMに保存 -*/ +/*- LOAD_RAM = RAMに保存 -*/ +/*- LOAD_TEXTURE = テクスチャー用 -*/ +/*- -*/ +/*- 戻り値 : スプライト情報 ( DDOBJ型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +DDOBJ elDraw::LoadPack(char* FileName,int Memory=LOAD_DEFAULT) +{ + DDSURFACEDESC ddsd; + LPWORD data; + long AddPitch; + UINT x,y; + unsigned short Sx,Sy; + WORD Pixel,R,G,B; + DDOBJ ObjDD,BuffObjDD; + FILE* Fpt; + char Buffer1[128],Buffer2[128]; + RECT rect1,rect2; + HRESULT ddret; + BYTE c; + BOOL Ok; + int i; + + #ifdef REPORT + + REP_IN + "LoadPack = " + REP_OUT + + #endif + + // パックファイルからBMPファイルを検索 + if ((Fpt=fopen(PackFileName,"rb"))!=NULL) + { + Ok=FALSE; + + while (!feof(Fpt)) + { + // BMPサイズの読み込み + if (fread(&Sx,2,1,Fpt)<=0) break; + if (fread(&Sy,2,1,Fpt)<=0) break; + + // BMPファイル名の読み込み + for (i=0;;i++) + { + fread(&c,1,1,Fpt); + Buffer1[i]=c; + if (c==0x00) break; + } + + strcpy(Buffer2,FileName); + CharUpperBuff(Buffer2,strlen(Buffer2)); + + // 指定されたBMPファイル名の場合 + if (!strcmp(Buffer1,Buffer2)) + { + // 検索の終了 + Ok=TRUE; + + #ifdef REPORT + + REP_IN + "%s\n",Buffer2 + REP_OUT + + #endif + + break; + } + else + { + // 次のBMPファイルを検索 + if (fseek(Fpt,Sx*Sy*2,SEEK_CUR)) break; + } + } + + if (!Ok) + { + return (DDOBJ)elDraw::Error("elDraw::LoadPack", + "BMPファイルを読み込めません"); + } + + #ifdef REPORT + + REP_IN + " Sprite > " + REP_OUT + + #endif + + // 空スプライトの生成 + ObjDD=elDraw::CreateObject(Sx,Sy,Memory); + + #ifdef REPORT + + REP_IN + " Buffer > " + REP_OUT + + #endif + + // バッファスプライトの生成 + BuffObjDD=elDraw::CreateObject(Sx,Sy); + + // 構造体の初期化 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + if (Sprite[BuffObjDD].Object->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL) + !=DD_OK) + { + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch=ddsd.lPitch>>1; + + // スプライトの先頭位置を取得 + data=(LPWORD)ddsd.lpSurface; + + for (y=0;y>10)&0x1F; + G=(Pixel>>5)&0x1F; + B=Pixel&0x1F; + + // DirectDrawのRGB構成に変換 + R<<=elDraw::ShiftR2; + G<<=elDraw::ShiftG2; + B<<=elDraw::ShiftB2; + + // スプライトにドットを書き込み + *(data+x)=R|G|B; + } + + // Y方向に加算 + data+=AddPitch; + } + + // スプライトのロック解除 + DD_UNLOCK(Sprite[BuffObjDD].Object,ddsd.lpSurface); + + fclose(Fpt); + + // バッファスプライトから実際のスプライトに転送 + rect1.left=0; + rect1.top=0; + rect1.right=Sprite[ObjDD].SizeX; + rect1.bottom=Sprite[ObjDD].SizeY; + + rect2.left=0; + rect2.top=0; + rect2.right=Sx; + rect2.bottom=Sy; + + for (i=0;i<10;i++) + { + ddret=Sprite[ObjDD].Object->Blt(&rect1,Sprite[BuffObjDD].Object, + &rect2,DDBLT_WAIT,NULL); + + if (ddret==DDERR_SURFACELOST) elDraw::ReloadObject(); + + if (ddret==DD_OK) break; + } + + if (ddret!=DD_OK) + { + return (DDOBJ)elDraw::Error("elDraw::LoadPack", + "サーフェース間で展開できません",ddret); + } + + #ifdef REPORT + + REP_IN + " Buffer > " + REP_OUT + + #endif + + // バッファスプライトの開放 + elDraw::FreeObject(BuffObjDD); + + // 透明色の再設定 + if (SpriteLeftTop) + { + DDSetColorKey(Sprite[ObjDD].Object,0xFFFFFFFF); + + Sprite[ObjDD].Color=0xFFFFFFFF; + } + else + { + DDSetColorKey(Sprite[ObjDD].Object,SpriteColor); + + Sprite[ObjDD].Color=SpriteColor; + } + + // スプライト情報の格納 + strcpy(Sprite[ObjDD].FileName,Buffer2); + Sprite[ObjDD].PackData=TRUE; + Sprite[ObjDD].Memory=LOAD_DEFAULT; + Sprite[ObjDD].SizeX=(WORD)Sx; + Sprite[ObjDD].SizeY=(WORD)Sy; + } + else + { + return (DDOBJ)elDraw::Error("elDraw::LoadPack", + "パックファイル名が指定されていません"); + } + + return ObjDD; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ビットマップの交換 ( パックファイル ) -*/ +/*- -*/ +/*- char* FileName : BMPファイル名 -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int Memory : スプライトの保存先 -*/ +/*- 省略/LOAD_DEFAULT = VRAMかRAMに保存 -*/ +/*- LOAD_RAM = RAMに保存 -*/ +/*- LOAD_TEXTURE = テクスチャー用 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +DDOBJ elDraw::SwapPack(char* FileName,DDOBJ ObjDD,int Memory=LOAD_DEFAULT) +{ + DDSURFACEDESC ddsd; + LPWORD data; + long AddPitch; + UINT x,y; + unsigned short Sx,Sy; + WORD Pixel,R,G,B; + DDOBJ BuffObjDD; + FILE* Fpt; + char Buffer1[128],Buffer2[128]; + RECT rect1,rect2; + HRESULT ddret; + BYTE c; + BOOL Ok; + int i; + + #ifdef REPORT + + REP_IN + "SwapPack = " + REP_OUT + + #endif + + // パックファイルからBMPファイルを検索 + if ((Fpt=fopen(PackFileName,"rb"))!=NULL) + { + Ok=FALSE; + + while (!feof(Fpt)) + { + // BMPサイズの読み込み + if (fread(&Sx,2,1,Fpt)<=0) break; + if (fread(&Sy,2,1,Fpt)<=0) break; + + // BMPファイル名の読み込み + for (i=0;;i++) + { + fread(&c,1,1,Fpt); + Buffer1[i]=c; + if (c==0x00) break; + } + + strcpy(Buffer2,FileName); + CharUpperBuff(Buffer2,strlen(Buffer2)); + + // 指定されたBMPファイル名の場合 + if (!strcmp(Buffer1,Buffer2)) + { + // 検索の終了 + Ok=TRUE; + + #ifdef REPORT + + REP_IN + "%s\n",Buffer2 + REP_OUT + + #endif + + break; + } + else + { + // 次のBMPファイルを検索 + if (fseek(Fpt,Sx*Sy*2,SEEK_CUR)) break; + } + } + + if (!Ok) + { + return (DDOBJ)elDraw::Error("elDraw::SwapPack", + "BMPファイルを読み込めません"); + } + + // オブジェクトの開放 + if (Sprite[ObjDD].Object!=NULL) + { + Sprite[ObjDD].Object->Release(); + Sprite[ObjDD].Object=NULL; + Sprite[ObjDD].FileName[0]=NULL; + } + + #ifdef REPORT + + REP_IN + " Sprite > " + REP_OUT + + #endif + + // 空スプライトの生成 + ObjDD=elDraw::CreateObject(Sx,Sy,Memory); + + #ifdef REPORT + + REP_IN + " Buffer > " + REP_OUT + + #endif + + // バッファスプライトの生成 + BuffObjDD=elDraw::CreateObject(Sx,Sy); + + // 構造体の初期化 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + if (Sprite[BuffObjDD].Object->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL) + !=DD_OK) + { + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch=ddsd.lPitch>>1; + + // スプライトの先頭位置を取得 + data=(LPWORD)ddsd.lpSurface; + + for (y=0;y>10)&0x1F; + G=(Pixel>>5)&0x1F; + B=Pixel&0x1F; + + // DirectDrawのRGB構成に変換 + R<<=elDraw::ShiftR2; + G<<=elDraw::ShiftG2; + B<<=elDraw::ShiftB2; + + // スプライトにドットを書き込み + *(data+x)=R|G|B; + } + + // Y方向に加算 + data+=AddPitch; + } + + // スプライトのロック解除 + DD_UNLOCK(Sprite[BuffObjDD].Object,ddsd.lpSurface); + + fclose(Fpt); + + // バッファスプライトから実際のスプライトに転送 + rect1.left=0; + rect1.top=0; + rect1.right=Sprite[ObjDD].SizeX; + rect1.bottom=Sprite[ObjDD].SizeY; + + rect2.left=0; + rect2.top=0; + rect2.right=Sx; + rect2.bottom=Sy; + + for (i=0;i<10;i++) + { + ddret=Sprite[ObjDD].Object->Blt(&rect1,Sprite[BuffObjDD].Object, + &rect2,DDBLT_WAIT,NULL); + + if (ddret==DDERR_SURFACELOST) elDraw::ReloadObject(); + + if (ddret==DD_OK) break; + } + + if (ddret!=DD_OK) + { + return (DDOBJ)elDraw::Error("elDraw::SwapPack", + "サーフェース間で展開できません",ddret); + } + + #ifdef REPORT + + REP_IN + " Buffer > " + REP_OUT + + #endif + + // バッファスプライトの開放 + elDraw::FreeObject(BuffObjDD); + + // 透明色の再設定 + if (SpriteLeftTop) + { + DDSetColorKey(Sprite[ObjDD].Object,0xFFFFFFFF); + + Sprite[ObjDD].Color=0xFFFFFFFF; + } + else + { + DDSetColorKey(Sprite[ObjDD].Object,SpriteColor); + + Sprite[ObjDD].Color=SpriteColor; + } + + // スプライト情報の格納 + strcpy(Sprite[ObjDD].FileName,Buffer2); + Sprite[ObjDD].PackData=TRUE; + Sprite[ObjDD].Memory=LOAD_DEFAULT; + Sprite[ObjDD].SizeX=(WORD)Sx; + Sprite[ObjDD].SizeY=(WORD)Sy; + } + else + { + return (DDOBJ)elDraw::Error("elDraw::SwapPack", + "パックファイル名が指定されていません"); + } + + return ObjDD; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ビットマップをパック化 ※ フルカラー専用 -*/ +/*- -*/ +/*- char* PackName : パックファイル名 -*/ +/*- char* BmpDir : BMPファイルがあるディレクトリィ -*/ +/*- BOOL Delete : パックファイル削除フラグ -*/ +/*- 省略/TRUE = 削除する -*/ +/*- FALSE = 削除しない -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw::Convert(char* PackName,char* BmpDir,BOOL Delete=TRUE) +{ + char Buffer[256]; + WIN32_FIND_DATA fd; + HANDLE hd; + + // フルカラーを要求 + if (elSystem::ColorBit()<=16) + { + return elDraw::Error("elDraw::Convert", + "画面をフルカラーにして下さい"); + } + + // パックファイルを削除する場合 + if (Delete) + { + // 現在のパックファイルを削除 + strcpy(Buffer,elSystem::Directory()); + strcat(Buffer,PackName); + remove(Buffer); + } + + // BMPファイルの検索 + strcpy(Buffer,elSystem::Directory()); + + if (BmpDir[0]!=NULL) + { + strcat(Buffer,BmpDir); + strcat(Buffer,"\\*.BMP"); + } + else + { + strcat(Buffer,"*.BMP"); + } + + hd=FindFirstFile(Buffer,&fd); + + if (hd!=INVALID_HANDLE_VALUE) + { + while (TRUE) + { + // 見つかったBMPファイルの変換 + if (BmpDir[0]!=NULL) + { + strcpy(Buffer,BmpDir); + strcat(Buffer,"\\"); + } + else + { + Buffer[0]=NULL; + } + + strcat(Buffer,fd.cFileName); + + CharUpperBuff(Buffer,strlen(Buffer)); + + ConvertFile(PackName,Buffer); + + if (!FindNextFile(hd,&fd)) break; + } + + FindClose(hd); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ビットマップをフルカラーからハイカラーに変換 ※ 内部で使用 -*/ +/*- -*/ +/*- char* PackName : パックファイル名 -*/ +/*- char* BmpName : BMPファイル名 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::ConvertFile(char* PackName,char* BmpName) +{ + UINT x,y; + WORD R,G,B; + DDOBJ ObjDD; + COLORREF Color; + WORD Data; + HDC Hdc; + FILE* Fpt; + char Buffer[256]; + int i,j; + + // ビットマップの読み込み + ObjDD=elDraw::LoadObject(BmpName,LOAD_RAM); + + Sprite[ObjDD].Object->GetDC(&Hdc); + + // パックファイルのオープン + strcpy(Buffer,elSystem::Directory()); + strcat(Buffer,PackName); + + if ((Fpt=fopen(Buffer,"ab"))!=NULL) + { + // BMPサイズの書き込み + fwrite(&(unsigned short)Sprite[ObjDD].SizeX,2,1,Fpt); + fwrite(&(unsigned short)Sprite[ObjDD].SizeY,2,1,Fpt); + + // BMPファイル名の書き込み + for (i=(int)strlen(BmpName);i>=0 && BmpName[i]!='\\';i--); + + for (i++,j=0;BmpName[i]!=NULL;i++,j++) + { + Buffer[j]=BmpName[i]; + } + + Buffer[j]=NULL; + + fwrite(Buffer,strlen(Buffer)+1,1,Fpt); + + // フルカラーをハイカラーに変換 + for (y=0;y<(UINT)Sprite[ObjDD].SizeY;y++) + { + for (x=0;x<(UINT)Sprite[ObjDD].SizeX;x++) + { + Color=GetPixel(Hdc,x,y); + + R=GetRValue(Color); + G=GetGValue(Color); + B=GetBValue(Color); + + // 黒以外の場合 + if (R || G || B) + { + // 8ビットを5ビットに変換 + R>>=3; + G>>=3; + B>>=3; + + // 黒になった場合、最低明度の青に設定 + if (R==0 && G==0 && B==0) B=1; + } + + // 5ビットのみを使用 + R&=0x1F; + G&=0x1F; + B&=0x1F; + + // 16ビット化 + Data=(R<<10)|(G<<5)|B; + + // ドットの書き込み + fwrite(&Data,2,1,Fpt); + } + } + + fclose(Fpt); + } + + Sprite[ObjDD].Object->ReleaseDC(Hdc); + + // ビットマップの開放 + elDraw::FreeObject(ObjDD); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライト透明色の指定 ( elDraw::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*- COLORREF Color : 透明色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::SetSpriteColor(COLORREF Color) +{ + SpriteColor=Color; + SpriteLeftTop=FALSE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライト透明色を左上ドットに指定 ( elDraw::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::SetSpriteLeftTop(void) +{ + SpriteLeftTop=TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 透明色を別なスプライトにコピー -*/ +/*- -*/ +/*- DDOBJ ObjDD1 : スプライト情報 ( コピー先 ) -*/ +/*- DDOBJ ObjDD2 : スプライト情報 ( コピー元 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::CopySpriteColor(DDOBJ ObjDD1,DDOBJ ObjDD2) +{ + DDCOLORKEY color; + + Sprite[ObjDD2].Object->GetColorKey(DDCKEY_SRCBLT,&color); + Sprite[ObjDD1].Object->SetColorKey(DDCKEY_SRCBLT,&color); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライト透明色の変更 -*/ +/*- -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- COLORREF Color : 透明色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::ChangeSpriteColor(DDOBJ ObjDD,COLORREF Color) +{ + Sprite[ObjDD].Color=Color; + + DDSetColorKey(Sprite[ObjDD].Object,Color); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライト透明色を左上ドットに変更 -*/ +/*- -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::ChangeSpriteLeftTop(DDOBJ ObjDD) +{ + Sprite[ObjDD].Color=0xFFFFFFFF; + + DDSetColorKey(Sprite[ObjDD].Object,0xFFFFFFFF); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 画面全体を黒で初期化 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::Clear(void) +{ + static DDBLTFX ddbltfx; + static RECT rect; + + rect.left=0; + rect.top=0; + rect.right=Width; + rect.bottom=Height; + + ddbltfx.dwSize=sizeof(ddbltfx); + ddbltfx.dwFillColor=0; + + DDBack->Blt(&rect,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライト全体を黒で初期化 -*/ +/*- -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::SpriteClear(DDOBJ ObjDD) +{ + static DDBLTFX ddbltfx; + static RECT rect; + + rect.left=0; + rect.top=0; + rect.right=Sprite[ObjDD].SizeX; + rect.bottom=Sprite[ObjDD].SizeY; + + ddbltfx.dwSize=sizeof(ddbltfx); + ddbltfx.dwFillColor=0; + + Sprite[ObjDD].Object->Blt(&rect,NULL,NULL, + DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx); +} + +#ifdef DIRECT3D + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 3Dスプライト全体を黒で初期化 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::Clear3D(void) +{ + if (!(el3D::Mode&DRAW_BACKLAYER)) + { + static DDBLTFX ddbltfx; + static RECT rect; + + rect.left=0; + rect.top=0; + rect.right=Width; + rect.bottom=Height; + + ddbltfx.dwSize=sizeof(ddbltfx); + ddbltfx.dwFillColor=0; + + DD3D->Blt(&rect,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx); + } +} + +#endif + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定された領域を黒で初期化 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::ClearArea(int X1,int Y1,int X2,int Y2) +{ + static DDBLTFX ddbltfx; + static RECT rect; + + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + ddbltfx.dwSize=sizeof(ddbltfx); + ddbltfx.dwFillColor=0; + + DDBack->Blt(&rect,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定された領域の枠を黒で初期化 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::ClearFrame(int X1,int Y1,int X2,int Y2) +{ + static DDBLTFX ddbltfx; + static RECT rect; + + ddbltfx.dwSize=sizeof(ddbltfx); + ddbltfx.dwFillColor=0; + + #define CLEAR_FRAME(x1,y1,x2,y2)\ + \ + rect.left=x1;\ + rect.top=y1;\ + rect.right=x2;\ + rect.bottom=y2;\ + \ + DDBack->Blt(&rect,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx); + + CLEAR_FRAME(X1,Y1,X2,Y1+1); + CLEAR_FRAME(X1,Y2-1,X2,Y2); + CLEAR_FRAME(X1,Y1,X1+1,Y2); + CLEAR_FRAME(X2-1,Y1,X2,Y2); + + #undef CLEAR_FRAME +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 画面全体を白で初期化 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::Flash(void) +{ + static DDBLTFX ddbltfx; + static RECT rect; + + rect.left=0; + rect.top=0; + rect.right=Width; + rect.bottom=Height; + + ddbltfx.dwSize=sizeof(ddbltfx); + ddbltfx.dwFillColor=WhiteRGB; + + DDBack->Blt(&rect,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定された領域を白で初期化 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::FlashArea(int X1,int Y1,int X2,int Y2) +{ + static DDBLTFX ddbltfx; + static RECT rect; + + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + ddbltfx.dwSize=sizeof(ddbltfx); + ddbltfx.dwFillColor=WhiteRGB; + + DDBack->Blt(&rect,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定された領域を任意の色で初期化 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- WORD Color : 色 ( RGB16(赤,緑,青)で指定 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::ColorFill(int X1,int Y1,int X2,int Y2,WORD Color) +{ + static DDBLTFX ddbltfx; + static RECT rect; + + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + ddbltfx.dwSize=sizeof(ddbltfx); + ddbltfx.dwFillColor=Color; + + DDBack->Blt(&rect,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カラーブレンド ( 50% ) ※ ハイカラー専用 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- WORD Color : 色 ( RGB16(赤,緑,青)で指定 ) -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw::ColorBlend(int X1,int Y1,int X2,int Y2,WORD Color) +{ + static HRESULT ddret; + static DDSURFACEDESC ddsd; + static LPWORD data; + static long AddPitch; + static int x,y; + static WORD Buff,Buff2; + + // 描画領域の計算 + if (X2>Vx2) X2-=X2-Vx2; + if (Y2>Vy2) Y2-=Y2-Vy2; + if (X1=X1 && Y2>=Y1) + { + // 構造体の初期化 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch=ddsd.lPitch>>1; + + // スプライトの先頭位置を取得 + data=(LPWORD)ddsd.lpSurface+Y1*AddPitch; + + // 色を先に50%化 + Buff2=Color>>1; + Buff2&=MaskRGB; + + // データ転送 + for (y=Y1;y>=1; + Buff&=MaskRGB; + + *(data+x)=Buff+Buff2; + } + + // Y方向に加算 + data+=AddPitch; + } + + // スプライトのロック解除 + DD_UNLOCK(DDBack,ddsd.lpSurface); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::Layer(int Px,int Py,DDOBJ ObjDD,int X1,int Y1,int X2,int Y2) +{ + static RECT rect; + + if (Px+(X2-X1)>Vx2) + { + X2-=(Px+(X2-X1)-Vx2); + } + + if (Py+(Y2-Y1)>Vy2) + { + Y2-=(Py+(Y2-Y1)-Vy2); + } + + if (Px=X1 && Y2>=Y1) + { + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + if (DDBack->BltFast(Px,Py,Sprite[ObjDD].Object,&rect, + DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT)==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定されたスプライトにスプライトの描画 -*/ +/*- -*/ +/*- DDOBJ ObjDD1 : 描画先のスプライト情報 -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- DDOBJ ObjDD2 : 描画元のスプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::SpriteLayer(DDOBJ ObjDD1,int Px,int Py, + DDOBJ ObjDD2,int X1,int Y1,int X2,int Y2) +{ + static RECT rect; + + if (Px+(X2-X1)>Vx2) + { + X2-=(Px+(X2-X1)-Vx2); + } + + if (Py+(Y2-Y1)>Vy2) + { + Y2-=(Py+(Y2-Y1)-Vy2); + } + + if (Px=X1 && Y2>=Y1) + { + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + if (Sprite[ObjDD1].Object->BltFast(Px,Py,Sprite[ObjDD2].Object,&rect, + DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT)==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 透明色を無視してスプライトの描画 -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::DirectLayer(int Px,int Py,DDOBJ ObjDD,int X1,int Y1,int X2,int Y2) +{ + static RECT rect; + + if (Px+(X2-X1)>Vx2) + { + X2-=(Px+(X2-X1)-Vx2); + } + + if (Py+(Y2-Y1)>Vy2) + { + Y2-=(Py+(Y2-Y1)-Vy2); + } + + if (Px=X1 && Y2>=Y1) + { + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + if (DDBack->BltFast(Px,Py,Sprite[ObjDD].Object,&rect, + DDBLTFAST_NOCOLORKEY|DDBLTFAST_WAIT)==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定されたスプライトに透明色を無視してスプライトの描画 -*/ +/*- -*/ +/*- DDOBJ ObjDD1 : 描画先のスプライト情報 -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- DDOBJ ObjDD2 : 描画元のスプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::DirectSpriteLayer(DDOBJ ObjDD1,int Px,int Py, + DDOBJ ObjDD2,int X1,int Y1,int X2,int Y2) +{ + static RECT rect; + + if (Px+(X2-X1)>Vx2) + { + X2-=(Px+(X2-X1)-Vx2); + } + + if (Py+(Y2-Y1)>Vy2) + { + Y2-=(Py+(Y2-Y1)-Vy2); + } + + if (Px=X1 && Y2>=Y1) + { + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + if (Sprite[ObjDD1].Object->BltFast(Px,Py,Sprite[ObjDD2].Object,&rect, + DDBLTFAST_NOCOLORKEY|DDBLTFAST_WAIT)==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( ウェーブ ) -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- int Width : ウェーブの大きさ -*/ +/*- int Size : ウェーブの荒さ -*/ +/*- float Speed : ウェーブの速さ -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- BOOL Mode : ウェーブモード   -*/ +/*- 省略/FALSE = ノーマル -*/ +/*- TRUE = 1ラインごとに反転 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::WaveLayer(int Px,int Py,int Width,int Size,float Speed, + DDOBJ ObjDD,int X1,int Y1,int X2,int Y2,BOOL Mode=FALSE) +{ + static int x,y; + static float Angle=F(0); + static int LineX=1; + + // 1ラインごとに反転する場合 + if (Mode) + { + if (!Size) + { + for (y=Y1;y=F(360)) Angle-=F(360); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( タイル ) -*/ +/*- -*/ +/*- float PxSpeed : X方向の速さ -*/ +/*- float PySpeed : Y方向の速さ -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::TileLayer(float PxSpeed,float PySpeed, + DDOBJ ObjDD,int X1,int Y1,int X2,int Y2) +{ + static int x,y; + static float RollX=F(0); + static float RollY=F(0); + + for (y=0;yF(0)) RollX-=F(X2-X1); + if (RollYF(0)) RollY-=F(Y2-Y1); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( スクロール+ウェーブ ) -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- int Width : ウェーブの大きさ -*/ +/*- int Size : ウェーブの荒さ -*/ +/*- float WaveSpeed : ウェーブの速さ -*/ +/*- float RollSpeed : スクロールの速さ -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::RollWaveLayer(int Px,int Py,int Width,int Size, + float WaveSpeed,float RollSpeed, + DDOBJ ObjDD,int X1,int Y1,int X2,int Y2) +{ + static int x,y,yy; + static float Angle=F(0); + static float Roll=F(0); + + if (!Size) + { + for (y=Y1;y=Y2) yy=Y1+(yy-Y2+1); + + elDraw::Layer(Px+x,Py+y,ObjDD,X1,yy,X2,yy+1); + } + } + else + { + for (y=Y1;y=Y2) yy=Y1+(yy-Y2+1); + + elDraw::Layer(Px+x,Py+y,ObjDD,X1,yy,X2,yy+1); + } + } + + Angle+=FrameTime*WaveSpeed; + + if (Angle>=F(360)) Angle-=F(360); + + Roll-=FrameTime*RollSpeed; + + if (Roll=F(Y2-Y1)) Roll-=F(Y2-Y1); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( タイル+スクロール+ウェーブ ) -*/ +/*- -*/ +/*- int Py1 : 描画上部Y座標 -*/ +/*- int Py2 : 描画下部Y座標 -*/ +/*- int Width : ウェーブの大きさ -*/ +/*- int Size : ウェーブの荒さ -*/ +/*- float WaveSpeed : ウェーブの速さ -*/ +/*- float RollSpeed : スクロールの速さ -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::TileRollWaveLayer(int Py1,int Py2,int Width,int Size, + float WaveSpeed,float RollSpeed, + DDOBJ ObjDD,int X1,int Y1,int X2,int Y2) +{ + static int x,y,xx,yy; + static float Angle=F(0); + static float Roll=F(0); + + if (!Size) + { + for (y=0;yY2-Y1-1) yy-=Y2-Y1; + + for (x=0;xY2-Y1-1) yy-=Y2-Y1; + + for (x=0;x=F(360)) Angle-=F(360); + + Roll-=FrameTime*RollSpeed; + + if (Roll=F(Y2-Y1)) Roll-=F(Y2-Y1); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( モザイク ) -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- int Size : モザイクの大きさ ( 1以上 ) -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::MosaicLayer(int Px,int Py,int Size,DDOBJ ObjDD, + int X1,int Y1,int X2,int Y2) +{ + static int y1,y2; + + for (y1=Y1;y1Blt(&rect1,Sprite[ObjDD].Object,&rect2, + DDBLT_KEYSRC|DDBLT_WAIT,NULL)==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } + else + { + Sprite[BUFFER_SPRITE].Object->GetDC(&hdc1); + Sprite[ObjDD].Object->GetDC(&hdc2); + + StretchBlt(hdc1,0,0,Sx,Sy,hdc2,X1,Y1,X2-X1,Y2-Y1,SRCCOPY); + + Sprite[BUFFER_SPRITE].Object->ReleaseDC(hdc1); + Sprite[ObjDD].Object->ReleaseDC(hdc2); + + elDraw::Layer(Px,Py,BUFFER_SPRITE,0,0,Sx,Sy); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 透明色を無視してスプライトの描画 ( 拡大縮小 ) -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- int Sx : 拡縮後のXサイズ ( 画面のXサイズまで ) -*/ +/*- int Sy : 拡縮後のYサイズ ( 画面のYサイズまで ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::DirectStretchLayer(int Px,int Py,DDOBJ ObjDD, + int X1,int Y1,int X2,int Y2,int Sx,int Sy) +{ + static RECT rect1,rect2; + static HDC hdc1,hdc2; + + if (UseStretch) + { + rect1.left=Px; + rect1.top=Py; + rect1.right=Px+Sx; + rect1.bottom=Py+Sy; + + rect2.left=X1; + rect2.top=Y1; + rect2.right=X2; + rect2.bottom=Y2; + + if (DDBack->Blt(&rect1,Sprite[ObjDD].Object,&rect2, + DDBLT_WAIT,NULL)==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } + else + { + Sprite[BUFFER_SPRITE].Object->GetDC(&hdc1); + Sprite[ObjDD].Object->GetDC(&hdc2); + + StretchBlt(hdc1,0,0,Sx,Sy,hdc2,X1,Y1,X2-X1,Y2-Y1,SRCCOPY); + + Sprite[BUFFER_SPRITE].Object->ReleaseDC(hdc1); + Sprite[ObjDD].Object->ReleaseDC(hdc2); + + elDraw::DirectLayer(Px,Py,BUFFER_SPRITE,0,0,Sx,Sy); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( 反転 ) -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- int Mirror : 反転タイプ -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// 反転タイプ +static const int NORMAL=0; // 反転なし +static const int MIRROR_X=1; // 左右反転 +static const int MIRROR_Y=2; // 上下反転 +static const int MIRROR_XY=3; // 上下左右反転 + +BOOL elDraw::MirrorLayer(int Px,int Py,int Mirror,DDOBJ ObjDD, + int X1,int Y1,int X2,int Y2) +{ + static HRESULT ddret; + static DDSURFACEDESC ddsd1,ddsd2; + static LPWORD data1,data2; + static long AddPitch1,AddPitch2; + static int Px2,Py2; + static DWORD x,y,Sx,Sy,Ex,Ey; + static WORD Buff; + + // 描画領域の計算 + Sx=0; + Sy=0; + Ex=X2-X1; + Ey=Y2-Y1; + Px2=Px; + Py2=Py; + + if (Px2+((int)Ex-(int)Sx)>Vx2) + { + Ex-=(Px2+(Ex-Sx)-Vx2); + } + + if (Py2+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py2+(Ey-Sy)-Vy2); + } + + if (Px2=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + if (Mirror==NORMAL) + { + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px2+Py2*AddPitch2; + + // データ転送 + for (y=Sy;y=Vx1 && Py>=Vy1) + { + data1=(LPWORD)ddsd1.lpSurface+(X2-(Ex-Sx))+ + (Y1+Ey-Sy-1+Y2-Y1-(Ey-Sy))*AddPitch1; + } + else if (Px0) + { + for (i=Y1+Size;i0) + { + for (i=Y1;i=F(Y2-Y1)) rt-=F(Y2-Y1); + } +} + +#ifdef DIRECT3D + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 3Dスプライトの描画 -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::Layer3D(int Px,int Py,int X1,int Y1,int X2,int Y2) +{ + static RECT rect; + + if (!(el3D::Mode&DRAW_BACKLAYER)) + { + if (Px+(X2-X1)>Vx2) + { + X2-=(Px+(X2-X1)-Vx2); + } + + if (Py+(Y2-Y1)>Vy2) + { + Y2-=(Py+(Y2-Y1)-Vy2); + } + + if (Px=X1 && Y2>=Y1) + { + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + if (DDBack->BltFast(Px,Py,DD3D,&rect, + DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT)==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 透明色を無視して3Dスプライトの描画 -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::DirectLayer3D(int Px,int Py,int X1,int Y1,int X2,int Y2) +{ + static RECT rect; + + if (!(el3D::Mode&DRAW_BACKLAYER)) + { + if (Px+(X2-X1)>Vx2) + { + X2-=(Px+(X2-X1)-Vx2); + } + + if (Py+(Y2-Y1)>Vy2) + { + Y2-=(Py+(Y2-Y1)-Vy2); + } + + if (Px=X1 && Y2>=Y1) + { + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + if (DDBack->BltFast(Px,Py,DD3D,&rect, + DDBLTFAST_NOCOLORKEY|DDBLTFAST_WAIT)==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } + } +} + +#endif + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( 50%ブレンド ) ※ ハイカラー専用 -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw::BlendLayer(int Px,int Py,DDOBJ ObjDD,int X1,int Y1,int X2,int Y2) +{ + static HRESULT ddret; + static DDSURFACEDESC ddsd1,ddsd2; + static LPWORD data1,data2; + static long AddPitch1,AddPitch2; + static DWORD x,y,Sx,Sy,Ex,Ey; + static WORD Buff,Buff2; + + // 描画領域の計算 + Sx=0; + Sy=0; + Ex=X2-X1; + Ey=Y2-Y1; + + if (Px+((int)Ex-(int)Sx)>Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + for (y=Sy;y>=1; + Buff&=MaskRGB; + Buff2=*(data2+x)>>1; + Buff2&=MaskRGB; + + *(data2+x)=Buff+Buff2; + } + } + + // Y方向に加算 + data1+=AddPitch1; + data2+=AddPitch2; + } + + // スプライトのロック解除 + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + DD_UNLOCK(DDBack,ddsd2.lpSurface); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( 値指定ブレンド ) ※ ハイカラー専用 -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- float Blend : 混合率 ( 0.0〜1.0 ) -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw::BlendLayer(int Px,int Py,float Blend,DDOBJ ObjDD, + int X1,int Y1,int X2,int Y2) +{ + static HRESULT ddret; + static DDSURFACEDESC ddsd1,ddsd2; + static LPWORD data1,data2; + static long AddPitch1,AddPitch2; + static unsigned int x,y,Sx,Sy,Ex,Ey; + static unsigned int Buff,R1,G1,B1,R2,G2,B2; + static float Bd; + + // 描画領域の計算 + Sx=0; + Sy=0; + Ex=X2-X1; + Ey=Y2-Y1; + + if (Px+((int)Ex-(int)Sx)>Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch/2; + AddPitch2=ddsd2.lPitch/2; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ブレンド値の算出 + Bd=F(1)-Blend; + + // データ転送 + for (y=Sy;y>ShiftR)&BitR; + G1=(Buff>>ShiftG)&BitG; + B1=(Buff>>ShiftB)&BitB; + + Buff=*(data2+x); + + R2=(Buff>>ShiftR)&BitR; + G2=(Buff>>ShiftG)&BitG; + B2=(Buff>>ShiftB)&BitB; + + R1=(unsigned int)(F(R1)*Blend+F(R2)*Bd); + G1=(unsigned int)(F(G1)*Blend+F(G2)*Bd); + B1=(unsigned int)(F(B1)*Blend+F(B2)*Bd); + + *(data2+x)=(R1<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch/2; + AddPitch2=ddsd2.lPitch/2; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ブレンド値の算出 + BdR=F(1)-BlendR; + BdG=F(1)-BlendG; + BdB=F(1)-BlendB; + + // データ転送 + for (y=Sy;y>ShiftR)&BitR; + G1=(Buff>>ShiftG)&BitG; + B1=(Buff>>ShiftB)&BitB; + + Buff=*(data2+x); + + R2=(Buff>>ShiftR)&BitR; + G2=(Buff>>ShiftG)&BitG; + B2=(Buff>>ShiftB)&BitB; + + R1=(unsigned int)(F(R1)*BlendR+F(R2)*BdR); + G1=(unsigned int)(F(G1)*BlendG+F(G2)*BdG); + B1=(unsigned int)(F(B1)*BlendB+F(B2)*BdB); + + *(data2+x)=(R1<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch/2; + AddPitch2=ddsd2.lPitch/2; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ブレンド値の算出 + Bd=(31-Blend)<<10; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ブレンド値の算出 + BdR=(31-BlendR)<<10; + BdG=(31-BlendG)<<10; + BdB=(31-BlendB)<<10; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ブレンド値の算出 + BdR=F(1)-BlendR; + BdG=F(1)-BlendG; + BdB=F(1)-BlendB; + + Gr=0; + + // X方向へのグラデーションの場合 + if (Mode==BLEND_X) + { + BdR2=BdR; + BdG2=BdG; + BdB2=BdB; + + // データ転送 + for (y=Sy;y(WORD)Start) + { + if (++Gr>=Size) + { + Gr=0; + + BdR-=F(1)/F(32); + BdG-=F(1)/F(32); + BdB-=F(1)/F(32); + + if (BdR>ShiftR)&BitR); + G1=(WORD)((Buff>>ShiftG)&BitG); + B1=(WORD)((Buff>>ShiftB)&BitB); + + Buff=*(data2+x); + + R2=(WORD)((Buff>>ShiftR)&BitR); + G2=(WORD)((Buff>>ShiftG)&BitG); + B2=(WORD)((Buff>>ShiftB)&BitB); + + R1=(unsigned int)(F(R1)*BlendR+F(R2)*BdR); + G1=(unsigned int)(F(G1)*BlendG+F(G2)*BdG); + B1=(unsigned int)(F(B1)*BlendB+F(B2)*BdB); + + *(data2+x)=(R1<(WORD)Start) + { + if (++Gr>=Size) + { + Gr=0; + + BdR-=F(1)/F(32); + BdG-=F(1)/F(32); + BdB-=F(1)/F(32); + + if (BdR>ShiftR)&BitR); + G1=(WORD)((Buff>>ShiftG)&BitG); + B1=(WORD)((Buff>>ShiftB)&BitB); + + Buff=*(data2+x); + + R2=(WORD)((Buff>>ShiftR)&BitR); + G2=(WORD)((Buff>>ShiftG)&BitG); + B2=(WORD)((Buff>>ShiftB)&BitB); + + R1=(WORD)(F(R1)*BlendR+F(R2)*BdR); + G1=(WORD)(F(G1)*BlendG+F(G2)*BdG); + B1=(WORD)(F(B1)*BlendB+F(B2)*BdB); + + *(data2+x)=(R1<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ブレンド値の算出 + BdR=31-BlendR; + BdG=31-BlendG; + BdB=31-BlendB; + + Gr=0; + + // X方向へのグラデーションの場合 + if (Mode==BLEND_X) + { + BdR2=BdR; + BdG2=BdG; + BdB2=BdB; + + // データ転送 + for (y=Sy;y(WORD)Start) + { + if (++Gr>=Size) + { + Gr=0; + + if (BdR) BdR--; + if (BdG) BdG--; + if (BdB) BdB--; + } + } + + Buff=*(data1+x); + + if (Buff!=0x0000) + { + R1=GetRGB[Buff].r; + G1=GetRGB[Buff].g; + B1=GetRGB[Buff].b; + + Buff=*(data2+x); + + R2=GetRGB[Buff].r; + G2=GetRGB[Buff].g; + B2=GetRGB[Buff].b; + + R1=BlendList[(BdR<<10)+(R1<<5)+R2]; + G1=BlendList[(1<<15)+(BdG<<10)+(G1<<5)+G2]; + B1=BlendList[(2<<15)+(BdB<<10)+(B1<<5)+B2]; + + *(data2+x)=R1|G1|B1; + } + } + + // Y方向に加算 + data1+=AddPitch1; + data2+=AddPitch2; + } + } + else + { + // データ転送 + for (y=Sy;y(WORD)Start) + { + if (++Gr>=Size) + { + Gr=0; + + if (BdR) BdR--; + if (BdG) BdG--; + if (BdB) BdB--; + } + } + + for (x=Sx;xVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ブレンド値の算出 + Bd=((int)(F(31)-Blend*F(31)))<<10; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + for (y=Sy;ySx) + { + if (*(data1+x-1)==0x0000) + { + Buff2=*(data2+x-1); + + R+=GetRGB[Buff2].r; + G+=GetRGB[Buff2].g; + B+=GetRGB[Buff2].b; + + Count++; + } + } + + if (xSy) + { + if (*(data1+x-AddPitch1)==0x0000) + { + Buff2=*(data2+x-AddPitch2); + + R+=GetRGB[Buff2].r; + G+=GetRGB[Buff2].g; + B+=GetRGB[Buff2].b; + + Count++; + } + } + + if (y1) + { + R/=Count; + G/=Count; + B/=Count; + + *(data2+x)=(R<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // マスクの作成 + Color=0x0000; + if (PlainR) Color|=MaskR; + if (PlainG) Color|=MaskG; + if (PlainB) Color|=MaskB; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch/2; + AddPitch2=ddsd2.lPitch/2; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + for (y=Sy;y>ShiftR)&BitR; + G=(Buff>>ShiftG)&BitG; + B=(Buff>>ShiftB)&BitB; + + R=(unsigned int)(F(R)*Bright); + G=(unsigned int)(F(G)*Bright); + B=(unsigned int)(F(B)*Bright); + + *(data2+x)=(R<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch/2; + AddPitch2=ddsd2.lPitch/2; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + for (y=Sy;y>ShiftR)&BitR; + G=(Buff>>ShiftG)&BitG; + B=(Buff>>ShiftB)&BitB; + + R=(unsigned int)(F(R)*BrightR); + G=(unsigned int)(F(G)*BrightG); + B=(unsigned int)(F(B)*BrightB); + + *(data2+x)=(R<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ブライト値の算出 + Bt=31-Bright; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ブライト値の算出 + BtR=31-BrightR; + BtG=31-BrightG; + BtB=31-BrightB; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ぼかし値の算出 + Sd=Shade*Shade; + + // データ転送 + for (y=Sy;yEy) + { + Sy2-=y+Ey2-Ey; + Ey2-=y+Ey2-Ey; + } + + for (x=Sx;xEx) + { + Sx2-=x+Ex2-Ex; + Ex2-=x+Ex2-Ex; + } + + if (Shade==2) + { + Buff=*(data1+x+Sx2+Sy2*AddPitch1); + + R+=GetRGB[Buff].r; + G+=GetRGB[Buff].g; + B+=GetRGB[Buff].b; + + Buff=*(data1+x+Sx2+1+Sy2*AddPitch1); + + R+=GetRGB[Buff].r; + G+=GetRGB[Buff].g; + B+=GetRGB[Buff].b; + + Buff=*(data1+x+Sx2+(Sy2+1)*AddPitch1); + + R+=GetRGB[Buff].r; + G+=GetRGB[Buff].g; + B+=GetRGB[Buff].b; + + Buff=*(data1+x+Sx2+1+(Sy2+1)*AddPitch1); + + R+=GetRGB[Buff].r; + G+=GetRGB[Buff].g; + B+=GetRGB[Buff].b; + + R>>=2; + G>>=2; + B>>=2; + } + else + { + for (xx=Sx2;xxVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + for (y=Sy;y=Vx1 && Px+Dx=Vy1 && Py+DyVx2) + { + Ex-=(Px1+Ex-Vx2); + } + + if (Py1+Ey>Vy2) + { + Ey-=(Py1+Ey-Vy2); + } + + if (Px1=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/2; + data2=(LPWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/2; + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // 回転の中心点を取得 + cx1=(Px2-Px1)>>1; + cy1=(Py2-Py1)>>1; + cx2=((Px2-Px1)-(X2-X1))>>1; + cy2=((Py2-Py1)-(Y2-Y1))>>1; + tx1=cx1*360-cx1*RotateData[Angle+90]+cy1*RotateData[Angle]; + ty1=cy1*360-cx1*RotateData[Angle]-cy1*RotateData[Angle+90]; + + for (y=0;y=0 && rx=0 && ry=Sx && x=Sy && yVx2) + { + Ex-=(Px1+Ex-Vx2); + } + + if (Py1+Ey>Vy2) + { + Ey-=(Py1+Ey-Vy2); + } + + if (Px1=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/2; + data2=(LPWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/2; + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // 回転の中心点を取得 + cx1=(Px2-Px1)>>1; + cy1=(Py2-Py1)>>1; + cx2=((Px2-Px1)-(X2-X1))>>1; + cy2=((Py2-Py1)-(Y2-Y1))>>1; + tx1=cx1*360-cx1*RotateData[Angle+90]+cy1*RotateData[Angle]; + ty1=cy1*360-cx1*RotateData[Angle]-cy1*RotateData[Angle+90]; + + for (y=0;y=Sx && x=Sy && yVx2) + { + Ex-=(Px1+Ex-Vx2); + } + + if (Py1+Ey>Vy2) + { + Ey-=(Py1+Ey-Vy2); + } + + if (Px1=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/2; + data2=(LPWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/2; + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // 回転の中心点を取得 + cx1=(Px2-Px1)>>1; + cy1=(Py2-Py1)>>1; + cx2=((Px2-Px1)-(int)(F(X2-X1)*Zoom))>>1; + cy2=((Py2-Py1)-(int)(F(Y2-Y1)*Zoom))>>1; + tx1=cx1*360-cx1*RotateData[Angle+90]+cy1*RotateData[Angle]; + ty1=cy1*360-cx1*RotateData[Angle]-cy1*RotateData[Angle+90]; + + for (y=0;y=0 && rx=0 && ry=Sx && x=Sy && yVx2) + { + Ex-=(Px1+Ex-Vx2); + } + + if (Py1+Ey>Vy2) + { + Ey-=(Py1+Ey-Vy2); + } + + if (Px1=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/2; + data2=(LPWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/2; + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // 回転の中心点を取得 + cx1=(Px2-Px1)>>1; + cy1=(Py2-Py1)>>1; + cx2=((Px2-Px1)-(X2-X1))>>1; + cy2=((Py2-Py1)-(Y2-Y1))>>1; + tx1=cx1*360-cx1*RotateData[Angle+90]+cy1*RotateData[Angle]; + ty1=cy1*360-cx1*RotateData[Angle]-cy1*RotateData[Angle+90]; + + for (y=0;y=Sx && x=Sy && yVx2) + { + Ex-=(Px1+Ex-Vx2); + } + + if (Py1+Ey>Vy2) + { + Ey-=(Py1+Ey-Vy2); + } + + if (Px1=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/2; + data2=(LPWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/2; + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // 回転の中心点を取得 + cx1=(Px2-Px1)>>1; + cy1=(Py2-Py1)>>1; + cx2=((Px2-Px1)-(X2-X1))>>1; + cy2=((Py2-Py1)-(Y2-Y1))>>1; + tx1=cx1*360-cx1*RotateData[Angle+90]+cy1*RotateData[Angle]; + ty1=cy1*360-cx1*RotateData[Angle]-cy1*RotateData[Angle+90]; + + // 拡大率の初期化 + ZoomX=ZoomStartX; + ZoomY=ZoomStartY; + + for (y=0;y=Sx && x=Sy && yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + if (Mode==PICK_LEFT) + { + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // シフト値の算出 + St=(int)(F(31)-Shift*F(31)); + + // データ転送 + for (y=Sy;y0) + { + Buff-=St; + } + else + { + Buff=0; + } + + if (Buff>=Ey-y) Buff=0; + + *(data2+x)=*(data2+x+Buff*AddPitch2); + } + } + + // Y方向に加算 + data1+=AddPitch1; + data2+=AddPitch2; + } + + // スプライトのロック解除 + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + DD_UNLOCK(DDBack,ddsd2.lpSurface); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- トンネル変換情報の生成 ※ ハイカラー専用 -*/ +/*- -*/ +/*- int Sx : スプライトのXサイズ -*/ +/*- int Sy : スプライトのYサイズ -*/ +/*- int Dx : 描画先のXサイズ ( 〜640 ) -*/ +/*- int Dy : 描画先のYサイズ ( 〜480 ) -*/ +/*- int Cx : トンネル中央のX座標 -*/ +/*- 省略/TUNNEL_CENTER = 中央 -*/ +/*- 0〜 = 任意の位置 -*/ +/*- int Cy : トンネル中央のY座標 -*/ +/*- 省略/TUNNEL_CENTER = 中央 -*/ +/*- 0〜 = 任意の位置 -*/ +/*- int Size : トンネルの大きさ ( 見た目 ) -*/ +/*- 省略/TUNNEL_DEFAULT_SIZE = 8 -*/ +/*- 2〜 = 任意の大きさ -*/ +/*- int Center : トンネル中央の設定 -*/ +/*- 省略 = TUNNEL_NORMAL/普通 -*/ +/*- int Type : トンネル形状の設定 -*/ +/*- 省略 = TUNNEL_TYPE_CIRCLE/円 -*/ +/*- int Line : トンネル曲線の設定 -*/ +/*- 省略 = TUNNEL_LINE_NORMAL/普通 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// トンネル中央の位置 +static const int TUNNEL_CENTER=-1; // 画面中央 + +// トンネルの大きさ +static const int TUNNEL_DEFAULT_SIZE=-1; // デフォルト + +// トンネル中央 +static const int TUNNEL_NORMAL=0; // 普通 ( 拡大も歪みもなし ) +static const int TUNNEL_WIDE_X=1; // 左右に拡大 +static const int TUNNEL_WIDE_Y=2; // 上下に拡大 +static const int TUNNEL_TO_RIGHT=3; // 右に歪む +static const int TUNNEL_TO_LEFT=4; // 左に歪む + +// トンネル形状 +static const int TUNNEL_TYPE_CIRCLE=0; // 円 +static const int TUNNEL_TYPE_BOX1=1; // 四角 +static const int TUNNEL_TYPE_BOX2=2; // 菱形 +static const int TUNNEL_TYPE_CROSS=3; // 十字 +static const int TUNNEL_TYPE_WALL=4; // 左右の壁 +static const int TUNNEL_TYPE_GROUND=5; // 上下の地面 +static const int TUNNEL_TYPE_FLASH=6; // フラッシュ効果 + +// トンネル曲線 +static const int TUNNEL_LINE_NORMAL=0; // 普通 ( 直線 ) +static const int TUNNEL_LINE_X=1; // X曲線 +static const int TUNNEL_LINE_Y=2; // Y曲線 +static const int TUNNEL_LINE_BOX1=3; // 四角曲線 +static const int TUNNEL_LINE_BOX2=4; // 菱形曲線 +static const int TUNNEL_LINE_CROSS=5; // 十字曲線 + +void elDraw::CreateTunnel(int Sx,int Sy,int Dx,int Dy, + int Cx=TUNNEL_CENTER,int Cy=TUNNEL_CENTER, + int Size=TUNNEL_DEFAULT_SIZE,int Center=TUNNEL_NORMAL, + int Type=TUNNEL_TYPE_CIRCLE,int Line=TUNNEL_LINE_NORMAL) +{ + int x,y; // 汎用カウンター + float f1,f2; // 汎用変数 + int xx,yy; // スプライト参照位置 + int cx,cy; // ディスプレイ中央位置 + + // TunnelLayer関数用に保存 + TunnelSpriteX=Sx; + TunnelSpriteY=Sy; + TunnelDisplayX=Dx; + TunnelDisplayY=Dy; + + // 画面の中央位置を取得 + cx=Cx; + cy=Cy; + + if (Cx==TUNNEL_CENTER) cx=Dx/2; + if (Cy==TUNNEL_CENTER) cy=Dy/2; + + // トンネルのサイズを取得 + if (Size==TUNNEL_DEFAULT_SIZE) Size=8; + if (Size<2) Size=2; + + // トンネル中央の設定 + switch (Center) + { + case TUNNEL_WIDE_X: + { + cy=Dy; + + break; + } + + case TUNNEL_TO_RIGHT: + { + cx=Dx; + + break; + } + + case TUNNEL_TO_LEFT: + { + cx=0; + + break; + } + } + + // Y方向の処理 + for (y=0;y=Dx) cx=Dx; + + break; + } + + case TUNNEL_WIDE_Y: + { + cx=Dx; + + break; + } + } + + // X方向の処理 + for (x=0;x=Sx) xx%=Sx; + if (yy>=Sy) yy%=Sy; + + // トンネルリストに保存 + TunnelList[y*Dx+x].x=xx; + TunnelList[y*Dx+x].y=yy; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( トンネル ) ※ ハイカラー専用 -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- int Rotate : 回転 ( 0〜スプライトのXサイズ ) -*/ +/*- int Dist : 距離 ( 0〜スプライトのYサイズ ) -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw::TunnelLayer(int Px,int Py,int Rotate,int Dist,DDOBJ ObjDD) +{ + static HRESULT ddret; + static DDSURFACEDESC ddsd1,ddsd2; + static LPWORD data1,data2; + static long AddPitch1,AddPitch2; + static int x,y,y2; + static WORD Buff; + static int Gx,Gy; + + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + for (y=0,y2=0;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + for (y=Sy;y>=Red; + G>>=Green; + B>>=Blue; + + i=elEffect::FireRandomList[Count]; + if (++Count==10000) Count=0; + + if (R>=i) + { + R-=i; + } + else + { + R=0; + } + + if (G>=i) + { + G-=i; + } + else + { + G=0; + } + + if (B>=i) + { + B-=i; + } + else + { + B=0; + } + + data3=data2; + data4=data2; + + for (i=0;i<31;i++) + { + if (R) R--; + if (G) G--; + if (B) B--; + + if (R+G+B==0x0000) break; + + if ((int)(Py+y)-(int)i>=Vy1) + { + data3-=AddPitch2; + + if (Dir&0x40) + { + Buff=*(data3+x); + + R2=R+GetRGB[Buff].r; + G2=G+GetRGB[Buff].g; + B2=B+GetRGB[Buff].b; + + if (R2>31) R2=31; + if (G2>31) G2=31; + if (B2>31) B2=31; + + *(data3+x)=(R2<=Vx1) + { + Buff=*(data3+x-i); + + R2=R+GetRGB[Buff].r; + G2=G+GetRGB[Buff].g; + B2=B+GetRGB[Buff].b; + + if (R2>31) R2=31; + if (G2>31) G2=31; + if (B2>31) B2=31; + + *(data3+x-i)=(R2<31) R2=31; + if (G2>31) G2=31; + if (B2>31) B2=31; + + *(data3+x+i)=(R2<31) R2=31; + if (G2>31) G2=31; + if (B2>31) B2=31; + + *(data4+x)=(R2<=Vx1) + { + Buff=*(data4+x-i); + + R2=R+GetRGB[Buff].r; + G2=G+GetRGB[Buff].g; + B2=B+GetRGB[Buff].b; + + if (R2>31) R2=31; + if (G2>31) G2=31; + if (B2>31) B2=31; + + *(data4+x-i)=(R2<31) R2=31; + if (G2>31) G2=31; + if (B2>31) B2=31; + + *(data4+x+i)=(R2<=Vx1) + { + Buff=*(data2+x-i); + + R2=R+GetRGB[Buff].r; + G2=G+GetRGB[Buff].g; + B2=B+GetRGB[Buff].b; + + if (R2>31) R2=31; + if (G2>31) G2=31; + if (B2>31) B2=31; + + *(data2+x-i)=(R2<31) R2=31; + if (G2>31) G2=31; + if (B2>31) B2=31; + + *(data2+x+i)=(R2<0) return FALSE; + + if (EffectOn==-1) + { + Vx1=Wx1; + Vy1=Wy1; + Vx2=Wx2; + Vy2=Wy2; + } + + Wx1=Vx1; + Wy1=Vy1; + Wx2=Vx2; + Wy2=Vy2; + + if (Type==WIPE_RANDOM) Type=rand()%9+1; + + WipeIn=FALSE; + WipeOut=FALSE; + EffectInOut=InOut; + EffectType=Type; + EffectSpeed=Speed; + EffectSize=Size; + + if (InOut==WIPE_IN) + { + EffectOn=1; + + switch (Type) + { + // 上に + case WIPE_UP: + { + Vy1=Wy2; + + break; + } + + // 下に + case WIPE_DOWN: + { + Vy2=Wy1; + + break; + } + + // 左に + case WIPE_LEFT: + { + Vx1=Wx2; + + break; + } + + // 右に + case WIPE_RIGHT: + { + Vx2=Wx1; + + break; + } + + // 上下に + case WIPE_UPDOWN: + { + Vy1=(Wy2-Wy1)/2+Wy1; + Vy2=Vy1; + + break; + } + + // 左右に + case WIPE_LEFTRIGHT: + { + Vx1=(Wx2-Wx1)/2+Wx1; + Vx2=Vx1; + + break; + } + + // 四角形で外側に + case WIPE_BOX: + { + Vx1=(Wx2-Wx1)/2+Wx1; + Vx2=Vx1; + Vy1=(Wy2-Wy1)/2+Wy1; + Vy2=Vy1; + + break; + } + + // 細く上下に、その後左右に + case WIPE_LINE_UPDOWN: + { + Vx1=(Wx2-Wx1)/2+Wx1; + Vx2=Vx1; + Vy1=(Wy2-Wy1)/2+Wy1; + Vy2=Vy1; + + Vx1-=Size/2; + Vx2+=Size/2; + + break; + } + + // 細く左右に、その後上下に + case WIPE_LINE_LEFTRIGHT: + { + Vx1=(Wx2-Wx1)/2+Wx1; + Vx2=Vx1; + Vy1=(Wy2-Wy1)/2+Wy1; + Vy2=Vy1; + + Vy1-=Size/2; + Vy2+=Size/2; + + break; + } + } + } + else + { + EffectOn=2; + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ワイプアウト状態に設定 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::SetWipeOut(void) +{ + Wx1=Vx1; + Wy1=Vy1; + Wx2=Vx2; + Wy2=Vy2; + + Vx2=Vx1; + Vy2=Vy1; + + EffectOn=-1; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ワイプの実行 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw::Wipe(void) +{ + if (EffectOn<=0) return FALSE; + + // ワイプインの場合 + if (EffectInOut==WIPE_IN) + { + switch (EffectType) + { + // 上に + case WIPE_UP: + { + Vy1-=(int)(FrameTime*EffectSpeed)+1; + + if (Vy1<=Wy1) + { + Vy1=Wy1; + EffectOn=0; + WipeIn=TRUE; + } + + break; + } + + // 下に + case WIPE_DOWN: + { + Vy2+=(int)(FrameTime*EffectSpeed)+1; + + if (Vy2>=Wy2) + { + Vy2=Wy2; + EffectOn=0; + WipeIn=TRUE; + } + + break; + } + + // 左に + case WIPE_LEFT: + { + Vx1-=(int)(FrameTime*EffectSpeed)+1; + + if (Vx1<=Wx1) + { + Vx1=Wx1; + EffectOn=0; + WipeIn=TRUE; + } + + break; + } + + // 右に + case WIPE_RIGHT: + { + Vx2+=(int)(FrameTime*EffectSpeed)+1; + + if (Vx2>=Wx2) + { + Vx2=Wx2; + EffectOn=0; + WipeIn=TRUE; + } + + break; + } + + // 上下に + case WIPE_UPDOWN: + { + Vy1-=(int)(FrameTime*EffectSpeed)+1; + Vy2+=(int)(FrameTime*EffectSpeed)+1; + + if (Vy1<=Wy1 || Vy2>=Wy2) + { + Vy1=Wy1; + Vy2=Wy2; + EffectOn=0; + WipeIn=TRUE; + } + + break; + } + + // 左右に + case WIPE_LEFTRIGHT: + { + Vx1-=(int)(FrameTime*EffectSpeed)+1; + Vx2+=(int)(FrameTime*EffectSpeed)+1; + + if (Vx1<=Wx1 || Vx2>=Wx2) + { + Vx1=Wx1; + Vx2=Wx2; + EffectOn=0; + WipeIn=TRUE; + } + + break; + } + + // 四角形で外側に + case WIPE_BOX: + { + Vx1-=(int)(FrameTime*EffectSpeed)+1; + Vx2+=(int)(FrameTime*EffectSpeed)+1; + Vy1-=(int)(FrameTime*EffectSpeed)+1; + Vy2+=(int)(FrameTime*EffectSpeed)+1; + + if (Vx1<=Wx1 || Vx2>=Wx2) + { + Vx1=Wx1; + Vx2=Wx2; + } + + if (Vy1<=Wy1 || Vy2>=Wy2) + { + Vy1=Wy1; + Vy2=Wy2; + } + + if (Vx1==Wx1 && Vx2==Wx2 && Vy1==Wy1 && Vy2==Wy2) + { + EffectOn=0; + WipeIn=TRUE; + } + + break; + } + + // 細く上下に、その後左右に + case WIPE_LINE_UPDOWN: + { + if (Vy1==Wy1 && Vy2==Wy2) + { + Vx1-=(int)(FrameTime*EffectSpeed)+1; + Vx2+=(int)(FrameTime*EffectSpeed)+1; + + if (Vx1<=Wx1 || Vx2>=Wx2) + { + Vx1=Wx1; + Vx2=Wx2; + } + } + else + { + Vy1-=(int)(FrameTime*EffectSpeed)+1; + Vy2+=(int)(FrameTime*EffectSpeed)+1; + + if (Vy1<=Wy1 || Vy2>=Wy2) + { + Vy1=Wy1; + Vy2=Wy2; + } + } + + if (Vx1==Wx1 && Vx2==Wx2 && Vy1==Wy1 && Vy2==Wy2) + { + EffectOn=0; + WipeIn=TRUE; + } + + break; + } + + // 細く左右に、その後上下に + case WIPE_LINE_LEFTRIGHT: + { + if (Vx1==Wx1 && Vx2==Wx2) + { + Vy1-=(int)(FrameTime*EffectSpeed)+1; + Vy2+=(int)(FrameTime*EffectSpeed)+1; + + if (Vy1<=Wy1 || Vy2>=Wy2) + { + Vy1=Wy1; + Vy2=Wy2; + } + } + else + { + Vx1-=(int)(FrameTime*EffectSpeed)+1; + Vx2+=(int)(FrameTime*EffectSpeed)+1; + + if (Vx1<=Wx1 || Vx2>=Wx2) + { + Vx1=Wx1; + Vx2=Wx2; + } + } + + if (Vx1==Wx1 && Vx2==Wx2 && Vy1==Wy1 && Vy2==Wy2) + { + EffectOn=0; + WipeIn=TRUE; + } + + break; + } + } + } + // ワイプアウトの場合 + else + { + switch (EffectType) + { + // 上から + case WIPE_UP: + { + Vy1+=(int)(FrameTime*EffectSpeed)+1; + + if (Vy1>=Wy2) + { + EffectOn=-1; + WipeOut=TRUE; + } + + break; + } + + // 下から + case WIPE_DOWN: + { + Vy2-=(int)(FrameTime*EffectSpeed)+1; + + if (Vy2<=Wy1) + { + EffectOn=-1; + WipeOut=TRUE; + } + + break; + } + + // 左から + case WIPE_LEFT: + { + Vx1+=(int)(FrameTime*EffectSpeed)+1; + + if (Vx1>=Wx2) + { + EffectOn=-1; + WipeOut=TRUE; + } + + break; + } + + // 右から + case WIPE_RIGHT: + { + Vx2-=(int)(FrameTime*EffectSpeed)+1; + + if (Vx2<=Wx1) + { + EffectOn=-1; + WipeOut=TRUE; + } + + break; + } + + // 上下から + case WIPE_UPDOWN: + { + Vy1+=(int)(FrameTime*EffectSpeed)+1; + Vy2-=(int)(FrameTime*EffectSpeed)+1; + + if (Vy1>=Vy2) + { + EffectOn=-1; + WipeOut=TRUE; + } + + break; + } + + // 左右から + case WIPE_LEFTRIGHT: + { + Vx1+=(int)(FrameTime*EffectSpeed)+1; + Vx2-=(int)(FrameTime*EffectSpeed)+1; + + if (Vx1>=Vx2) + { + EffectOn=-1; + WipeOut=TRUE; + } + + break; + } + + // 四角形で外側から + case WIPE_BOX: + { + Vx1+=(int)(FrameTime*EffectSpeed)+1; + Vx2-=(int)(FrameTime*EffectSpeed)+1; + Vy1+=(int)(FrameTime*EffectSpeed)+1; + Vy2-=(int)(FrameTime*EffectSpeed)+1; + + if (Vx1>=Vx2) + { + Vx1=(Wx2-Wx1)/2+Wx1; + Vx2=Vx1; + } + + if (Vy1>=Vy2) + { + Vy1=(Wy2-Wy1)/2+Wy1; + Vy2=Vy1; + } + + if (Vx1==Vx2 && Vy1==Vy2) + { + EffectOn=-1; + WipeOut=TRUE; + } + + break; + } + + // 左右から、その後細く上下から + case WIPE_LINE_UPDOWN: + { + if (Vx1!=(Wx2-Wx1)/2+Wx1-EffectSize/2 && + Vx2!=(Wx2-Wx1)/2+Wx1+EffectSize/2) + { + Vx1+=(int)(FrameTime*EffectSpeed)+1; + Vx2-=(int)(FrameTime*EffectSpeed)+1; + + if (Vx1>=(Wx2-Wx1)/2+Wx1-EffectSize/2 || + Vx2<=(Wx2-Wx1)/2+Wx1+EffectSize/2) + { + Vx1=(Wx2-Wx1)/2+Wx1-EffectSize/2; + Vx2=(Wx2-Wx1)/2+Wx1+EffectSize/2; + } + } + else + { + Vy1+=(int)(FrameTime*EffectSpeed)+1; + Vy2-=(int)(FrameTime*EffectSpeed)+1; + + if (Vy1>=Vy2) + { + EffectOn=-1; + WipeOut=TRUE; + } + } + + break; + } + + // 上下から、その後細く左右から + case WIPE_LINE_LEFTRIGHT: + { + if (Vy1!=(Wy2-Wy1)/2+Wy1-EffectSize/2 && + Vy2!=(Wy2-Wy1)/2+Wy1+EffectSize/2) + { + Vy1+=(int)(FrameTime*EffectSpeed)+1; + Vy2-=(int)(FrameTime*EffectSpeed)+1; + + if (Vy1>=(Wy2-Wy1)/2+Wy1-EffectSize/2 || + Vy2<=(Wy2-Wy1)/2+Wy1+EffectSize/2) + { + Vy1=(Wy2-Wy1)/2+Wy1-EffectSize/2; + Vy2=(Wy2-Wy1)/2+Wy1+EffectSize/2; + } + } + else + { + Vx1+=(int)(FrameTime*EffectSpeed)+1; + Vx2-=(int)(FrameTime*EffectSpeed)+1; + + if (Vx1>=Vx2) + { + EffectOn=-1; + WipeOut=TRUE; + } + } + + break; + } + } + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 色反転 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::Reverse(int X1,int Y1,int X2,int Y2) +{ + static HDC hdc; + static RECT rect; + + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + DDBack->GetDC(&hdc); + + InvertRect(hdc,&rect); + + DDBack->ReleaseDC(hdc); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 画面のリフレッシュ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::Refresh(void) +{ + static int x,y; + static HRESULT ddret; + + // フェイドがある場合 + if (FadeNo) + { + if (FadeType==FADE_MASK) + { + for (x=0;x<10;x++) + { + for (y=0;y<10;y++) + { + elDraw::Layer(x*64,y*48,MaskBMP, + (FadeNo-1)*64,0,(FadeNo-1)*64+64,48); + } + } + } + else + { + switch (FadeType) + { + case FADE_LINE1: + { + for (y=0;y10) + { + FadeNo=0; + FadeAdd=0; + } + } + + // ヘルプ表示中の場合 + if (HelpOn) + { + for (x=0;x<11;x++) + { + for (y=0;y<11;y++) + { + elDraw::Layer(x*64+(int)HelpBackX,y*48+(int)HelpBackY, + HelpBMP[1],0,0,64,48); + } + } + + HelpBackX-=FrameTime*F(10); + HelpBackY-=FrameTime*F(10); + + if (HelpBackX<=F(-64)) HelpBackX+=F(64); + if (HelpBackY<=F(-48)) HelpBackY+=F(48); + + elDraw::Layer(Vx1,Vy1,HelpBMP[0], + 0,(int)HelpY,Vx2-Vx1,(int)HelpY+(Vy2-Vy1)); + + if (HelpKey==VK_UP) HelpY-=FrameTime*F(100); + if (HelpKey==VK_LEFT) HelpY-=FrameTime*F(300); + if (HelpKey==VK_DOWN) HelpY+=FrameTime*F(100); + if (HelpKey==VK_RIGHT) HelpY+=FrameTime*F(300); + + if (HelpYF(HelpSize-(Vy2-Vy1))) HelpY=F(HelpSize-(Vy2-Vy1)); + } + + #ifdef SHOW_FPS + + // FPSの表示 + FPS; + + #endif + + #if defined(SAVER) || defined(SAVER_NO_CONFIG) + + // プレビュー状態の場合 + if (elSaver::Preview) + { + // 自動的にプレビューサイズに合わせる場合 + if (elSaver::AutoPreviewFlag) + { + // 裏画面をプレビューサイズに拡大縮小 + RefreshSize.left=0; + RefreshSize.top=0; + RefreshSize.right=Width; + RefreshSize.bottom=Height; + + RefreshPos.left=0; + RefreshPos.top=0; + RefreshPos.right=elSaver::PrevWidth; + RefreshPos.bottom=elSaver::PrevHeight; + + if (Sprite[BUFFER_SPRITE].Object->Blt(&RefreshPos,DDBack, + &RefreshSize,DDBLT_WAIT,NULL)==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + + // 再度、裏画面に転送 + elDraw::DirectLayer(0,0,BUFFER_SPRITE,0,0, + elSaver::PrevWidth,elSaver::PrevHeight); + } + + // プレビューサイズのみ転送 + RefreshSize.left=0; + RefreshSize.top=0; + RefreshSize.right=elSaver::PrevWidth; + RefreshSize.bottom=elSaver::PrevHeight; + + RefreshPos.left=_WindowX; + RefreshPos.top=_WindowY; + RefreshPos.right=_WindowX+elSaver::PrevWidth; + RefreshPos.bottom=_WindowY+elSaver::PrevHeight; + } + + #endif + + // 同期待ちする場合 + if (RefreshMode) + { + if (DDObject->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,NULL)==DD_OK) + { + if (DDFront->Blt(&RefreshPos,DDBack,&RefreshSize,DDBLT_WAIT,NULL) + ==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } + } + else + { + if (DDFront->Blt(&RefreshPos,DDBack,&RefreshSize,DDBLT_WAIT,NULL) + ==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- リフレッシュ時の同期待ち設定 -*/ +/*- -*/ +/*- BOOL Mode : 垂直帰線期間待ちの指定 -*/ +/*- TRUE = 同期する -*/ +/*- FALSE = 同期しない -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::SetRefreshMode(BOOL Mode) +{ + RefreshMode=Mode; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- fpsの描画 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::ShowFPS(void) +{ + static char Buffer[64]; + + if (timeGetTime()>=FpsTime) + { + FpsData=(float)FpsCnt/F(2); + + if (FpsData>FpsDataMax) FpsDataMax=FpsData; + if (FpsData>F(0) && FpsData999) FpsCnt=999; + + sprintf(Buffer,"%3.1f fps ( max %3.1f / min %3.1f )", + FpsData,FpsDataMax,FpsDataMin); + + elFont::Begin(GOTHIC,12,0,FALSE,FALSE,FALSE); + elFont::Color(RGB(255,255,255),RGB(0,0,128),FALSE); + elFont::Draw(0,0,Buffer); + elFont::Before(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 文字の描画 -*/ +/*- -*/ +/*- int x : 描画X座標 -*/ +/*- int y : 描画Y座標 -*/ +/*- char* Str : 文字 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::ShowString(int x,int y,char* Str) +{ + elFont::Begin(GOTHIC,12,0,FALSE,FALSE,FALSE); + elFont::Color(RGB(255,255,255),RGB(0,0,128),FALSE); + elFont::Draw(x,y,Str); + elFont::Before(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 書式指定して文字の描画 -*/ +/*- -*/ +/*- int x : 描画X座標 -*/ +/*- int y : 描画Y座標 -*/ +/*- char* Format ... : printf関数の書式と同様 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::ShowFormat(int x,int y,char* Format,...) +{ + char Buffer[256]; + + vsprintf(Buffer,Format,(char*)(&Format+1)); + + elFont::Begin(GOTHIC,12,0,FALSE,FALSE,FALSE); + elFont::Color(RGB(255,255,255),RGB(0,0,128),FALSE); + elFont::Draw(x,y,Buffer); + elFont::Before(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 図形の描画 -*/ +/*- -*/ +/*- POINT* Point : 描画座標 -*/ +/*- int Count : 頂点の数 -*/ +/*- COLORREF FrontColor : 線の色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- COLORREF BackColor : 塗りつぶす色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- int PenSize : 線の太さ -*/ +/*- int DrawFlag : 図形の描画方式 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// 図形の描画方式 +static const int LINE_DRAW=0; // 図形の枠のみ描画 +static const int CROSS_PAINT=1; // 網模様で塗りつぶす +static const int TRANSPARENT_PAINT=2; // 背景が透ける網模様で描画 + +void elDraw::FillPattern(POINT* Point,int Count,COLORREF FrontColor, + COLORREF BackColor,int PenSize,int DrawFlag) +{ + static HDC hdc; + static LOGBRUSH LogBrush; + static HBRUSH NowBrush,OldBrush; + static HPEN NowPen,OldPen; + + DDBack->GetDC(&hdc); + + if (DrawFlag==LINE_DRAW) + { + LogBrush.lbStyle=BS_HOLLOW; + } + else + { + LogBrush.lbStyle=BS_HATCHED; + } + + LogBrush.lbColor=FrontColor; + LogBrush.lbHatch=HS_DIAGCROSS; + + NowBrush=CreateBrushIndirect(&LogBrush); + OldBrush=(HBRUSH)SelectObject(hdc,NowBrush); + + NowPen=CreatePen(PS_SOLID,PenSize,FrontColor); + OldPen=(HPEN)SelectObject(hdc,NowPen); + + if (DrawFlag==TRANSPARENT_PAINT) + { + SetBkMode(hdc,TRANSPARENT); + } + else + { + SetBkColor(hdc,BackColor); + } + + Polygon(hdc,Point,Count); + + SelectObject(hdc,OldPen); + DeleteObject(NowPen); + + SelectObject(hdc,OldBrush); + DeleteObject(NowBrush); + + DDBack->ReleaseDC(hdc); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マスクデータの読み込み -*/ +/*- -*/ +/*- char* FileName : BMPファイル名 ( 横:64×10、縦:48 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::LoadMask(char* FileName) +{ + elDraw::SetSpriteColor(RGB(0,0,0)); + MaskBMP=elDraw::LoadObject(FileName); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ヘルプデータの読み込み -*/ +/*- -*/ +/*- char* FileName1 : BMPファイル名 ( ヘルプデータ / 横:仮想画面サイズ ) -*/ +/*- char* FileName2 : BMPファイル名 ( 背景データ / 横:64、縦:48 ) -*/ +/*- int Size : ヘルプデータのYサイズ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::LoadHelp(char* FileName1,char* FileName2,int Size) +{ + elDraw::SetSpriteColor(RGB(0,0,0)); + + if (HelpBMP[0]==NULL) + { + HelpBMP[0]=elDraw::LoadObject(FileName1); + HelpBMP[1]=elDraw::LoadObject(FileName2); + } + else + { + elDraw::SwapObject(FileName1,HelpBMP[0]); + elDraw::SwapObject(FileName2,HelpBMP[1]); + } + + HelpY=F(0); + HelpSize=Size; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ヘルプの表示切り換え -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::Help(void) +{ + if (HelpOn) + { + HelpOn=FALSE; + } + else + { + if (HelpSize) HelpOn=TRUE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フェイドイン -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::FadeIn(void) +{ + FadeNo=10; + FadeAdd=-1; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フェイドアウト -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::FadeOut(void) +{ + FadeNo=1; + FadeAdd=1; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 裏画面をビットマップとして保存 -*/ +/*- -*/ +/*- char* FileName : BMPファイル名 -*/ +/*- int Width : 幅 -*/ +/*- 省略 = 裏画面の幅 -*/ +/*- int Height : 高さ -*/ +/*- 省略 = 裏画面の高さ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw::SaveBitmap(char* FileName, + int Width=elDraw::Width,int Height=elDraw::Height) +{ + BITMAPFILEHEADER Bf; + BITMAPINFO Bi; + FILE* Fpt; + DDSURFACEDESC ddsd; + LPWORD data16; + LPDWORD data32; + long AddPitch; + WORD Buff16; + DWORD Buff32; + BYTE R,G,B,None=0x00; + int BmpWidth,BmpWidth4,BmpHeight; + int x,y; + char Buffer[256]; + + // ビットマップサイズの取得 + BmpWidth=Width; + BmpHeight=Height; + + BmpWidth4=BmpWidth*3/4*4; + if (BmpWidth4!=BmpWidth*3) BmpWidth4=(BmpWidth*3/4+1)*4; + + // ヘッダーの設定 + Bf.bfType=('M'<<8)|'B'; + Bf.bfSize=BmpWidth4*BmpHeight; + Bf.bfReserved1=0; + Bf.bfReserved2=0; + Bf.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO); + + Bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); + Bi.bmiHeader.biWidth=BmpWidth; + Bi.bmiHeader.biHeight=BmpHeight; + Bi.bmiHeader.biPlanes=1; + Bi.bmiHeader.biBitCount=24; + Bi.bmiHeader.biCompression=BI_RGB; + Bi.bmiHeader.biSizeImage=BmpWidth*BmpHeight*3; + Bi.bmiHeader.biXPelsPerMeter=(int)(F(72)/F(2.54)*F(100)); + Bi.bmiHeader.biYPelsPerMeter=(int)(F(72)/F(2.54)*F(100)); + Bi.bmiHeader.biClrUsed=0; + Bi.bmiHeader.biClrImportant=0; + + Bi.bmiColors[0].rgbBlue=0; + Bi.bmiColors[0].rgbGreen=0; + Bi.bmiColors[0].rgbRed=0; + Bi.bmiColors[0].rgbReserved=0; + + // 構造体の初期化 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + + // 裏画面のロック + if (DDBack->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL)!=DD_OK) return FALSE; + + // 16ビットカラーの場合 + if (elSystem::ColorBit()==16) + { + // Y方向への追加バイト数の取得 + AddPitch=ddsd.lPitch>>1; + + // 裏画面の先頭位置を取得 + data16=(LPWORD)ddsd.lpSurface+(BmpHeight-1)*AddPitch; + + // ビットマップに書き込み + strcpy(Buffer,elSystem::Directory()); + strcat(Buffer,FileName); + + if ((Fpt=fopen(Buffer,"wb"))!=NULL) + { + // ヘッダーの書き込み + fwrite(&Bf,sizeof(BITMAPFILEHEADER),1,Fpt); + fwrite(&Bi,sizeof(BITMAPINFO),1,Fpt); + + // RGBデータの書き込み + for (y=0;y>2; + + // 裏画面の先頭位置を取得 + data32=(LPDWORD)ddsd.lpSurface+(BmpHeight-1)*AddPitch; + + // ビットマップに書き込み + strcpy(Buffer,elSystem::Directory()); + strcat(Buffer,FileName); + + if ((Fpt=fopen(Buffer,"wb"))!=NULL) + { + // ヘッダーの書き込み + fwrite(&Bf,sizeof(BITMAPFILEHEADER),1,Fpt); + fwrite(&Bi,sizeof(BITMAPINFO),1,Fpt); + + // RGBデータの書き込み + for (y=0;y>ShiftR)&0xFF; + G=(BYTE)(Buff32>>ShiftG)&0xFF; + B=(BYTE)(Buff32>>ShiftB)&0xFF; + + // BGRとして書き込み + fwrite(&B,1,1,Fpt); + fwrite(&G,1,1,Fpt); + fwrite(&R,1,1,Fpt); + } + + // 幅のバイト数を4の倍数化 + for (x*=3;xGetCaps(&DriverCaps,&HELCaps); + + if (DriverCaps.dwCaps&DDCAPS_3D) + { + if (DriverCaps.ddsCaps.dwCaps&DDSCAPS_TEXTURE) + { + *(LPDIRECTDRAW*)lpContext=CheckDD; + + SearchVideoCard=TRUE; + + #ifdef DIRECT3D + + el3D::DriverType=D3DCOLOR_RGB; + + #endif + + DDDEVICEIDENTIFIER2 dvi; + CheckDD->GetDeviceIdentifier(&dvi,0); + strcpy(VideoCardName,dvi.szDescription); + + return DDENUMRET_CANCEL; + } + } + + *(LPDIRECTDRAW*)lpContext=NULL; + + CheckDD->Release(); + + return DDENUMRET_OK; +} + +#else + +CLBKB elDraw::SearchDriver(GUID FAR* lpGUID,LPSTR lpDriverDesc, + LPSTR lpDriverName,LPVOID lpContext) +{ + LPDIRECTDRAW CheckDD; + DDCAPS DriverCaps,HELCaps; + + SearchVideoCard=FALSE; + + if (FAILED(DirectDrawCreate(lpGUID,&CheckDD,NULL))) return DDENUMRET_OK; + + memset(&DriverCaps,0x00,sizeof(DDCAPS)); + DriverCaps.dwSize=sizeof(DDCAPS); + + memset(&HELCaps,0x00,sizeof(DDCAPS)); + HELCaps.dwSize=sizeof(DDCAPS); + + CheckDD->GetCaps(&DriverCaps,&HELCaps); + + if (DriverCaps.dwCaps&DDCAPS_3D) + { + if (DriverCaps.ddsCaps.dwCaps&DDSCAPS_TEXTURE) + { + *(LPDIRECTDRAW*)lpContext=CheckDD; + + SearchVideoCard=TRUE; + + #ifdef DIRECT3D + + el3D::DriverType=D3DCOLOR_RGB; + + #endif + + return DDENUMRET_CANCEL; + } + } + + *(LPDIRECTDRAW*)lpContext=NULL; + + CheckDD->Release(); + + return DDENUMRET_OK; +} + +#endif + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- デバイスコンテキストの取得 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::GetDC(void) +{ + DDBack->GetDC(&hdc); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- デバイスコンテキストの解放 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::ReleaseDC(void) +{ + DDBack->ReleaseDC(hdc); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ドット色の取得 -*/ +/*- -*/ +/*- int x : X座標 -*/ +/*- int y : Y座標 -*/ +/*- int* Red : 赤 -*/ +/*- int* Green : 緑 -*/ +/*- int* Blue : 青 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::GetColor(int x,int y,int* Red,int* Green,int* Blue) +{ + static HDC hdc; + static COLORREF Color; + + DDBack->GetDC(&hdc); + + Color=GetPixel(hdc,x,y); + + DDBack->ReleaseDC(hdc); + + *Red=(int)(Color&0xFF); + *Green=(int)(Color>>8&0xFF); + *Blue=(int)(Color>>16&0xFF); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 画面のスプライト化 -*/ +/*- -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::SpriteScreen(DDOBJ ObjDD,int X1,int Y1,int X2,int Y2) +{ + static RECT rect; + + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + if (Sprite[ObjDD].Object->BltFast(0,0,DDBack,&rect,DDBLTFAST_WAIT) + ==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ドットの描画 -*/ +/*- -*/ +/*- int Px : X座標 -*/ +/*- int Py : Y座標 -*/ +/*- COLORREF Color : ドットの色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::Pixel(int Px,int Py,COLORREF Color) +{ + static HDC hdc; + + DDBack->GetDC(&hdc); + + SetPixel(hdc,Px,Py,Color); + + DDBack->ReleaseDC(hdc); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ラインの描画 -*/ +/*- -*/ +/*- int X1 : 開始X座標 -*/ +/*- int Y1 : 開始Y座標 -*/ +/*- int X2 : 終了X座標 -*/ +/*- int Y2 : 終了Y座標 -*/ +/*- COLORREF Color : 線の色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- int Size : 線の太さ -*/ +/*- 省略 = 1 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::Line(int X1,int Y1,int X2,int Y2,COLORREF Color,int Size=1) +{ + static HDC hdc; + static HPEN NowPen,OldPen; + + DDBack->GetDC(&hdc); + + NowPen=CreatePen(PS_SOLID,Size,Color); + OldPen=(HPEN)SelectObject(hdc,NowPen); + + MoveToEx(hdc,X1,Y1,NULL); + LineTo(hdc,X2,Y2); + + SelectObject(hdc,OldPen); + DeleteObject(NowPen); + + DDBack->ReleaseDC(hdc); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ボックスの描画 -*/ +/*- -*/ +/*- int X1 : 開始X座標 -*/ +/*- int Y1 : 開始Y座標 -*/ +/*- int X2 : 終了X座標 -*/ +/*- int Y2 : 終了Y座標 -*/ +/*- COLORREF Color : ボックスの色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- COLORREF Color : 線の色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- int Size : 線の太さ -*/ +/*- 省略 = 1 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::Box(int X1,int Y1,int X2,int Y2,COLORREF Color1,COLORREF Color2, + int Size=1) +{ + static HDC hdc; + static HPEN NowPen,OldPen; + static LOGBRUSH LogBrush; + static HBRUSH NowBrush,OldBrush; + + DDBack->GetDC(&hdc); + + LogBrush.lbStyle=BS_SOLID; + LogBrush.lbColor=Color1; + + NowBrush=CreateBrushIndirect(&LogBrush); + OldBrush=(HBRUSH)SelectObject(hdc,NowBrush); + + NowPen=CreatePen(PS_SOLID,Size,Color2); + OldPen=(HPEN)SelectObject(hdc,NowPen); + + Rectangle(hdc,X1,Y1,X2,Y2); + + SelectObject(hdc,OldPen); + DeleteObject(NowPen); + + SelectObject(hdc,OldBrush); + DeleteObject(NowBrush); + + DDBack->ReleaseDC(hdc); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ベジェ曲線の描画 -*/ +/*- -*/ +/*- POINT* Point : 座標データ -*/ +/*- ( 0:始点 / 1:制御点1 / 2:制御点2 / 3:終点 / -*/ +/*- 以下、1〜3の繰り返し ) -*/ +/*- int Count : 座標データ数 ( 終点の数×3+1 ) -*/ +/*- COLORREF Color : 線の色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- int Size : 線の太さ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::Bezier(POINT* Point,int Count,COLORREF Color,int Size) +{ + static HDC hdc; + static HPEN NowPen,OldPen; + + DDBack->GetDC(&hdc); + + NowPen=CreatePen(PS_SOLID,Size,Color); + OldPen=(HPEN)SelectObject(hdc,NowPen); + + PolyBezier(hdc,(const POINT*)Point,Count); + + SelectObject(hdc,OldPen); + DeleteObject(NowPen); + + DDBack->ReleaseDC(hdc); +} + +#ifdef MENU + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- メニューの描画 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw::Menu(void) +{ + static int i; + static int CallKey; + + // キーボード状態の取得 + elSystem::GetKey(elMenu::ViewKey,&CallKey); + + // メニューを呼び出す場合 + if (CallKey==PUSH_KEY) + { + // メニュー情報が読み込まれている場合 + if (elMenu::MenuTopCount) + { + // メニュー表示フラグをON + elMenu::MenuOn=TRUE; + MenuKey=NULL; + + // カーソル位置の初期化 + elMenu::MenuPosX=-1; + elMenu::MenuPosY=-1; + } + } + + // メニュー描画 + if (elMenu::MenuOn) + { + elMenu::Draw(); + } +} + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= エフェクトクラス定義 ( elEffect ) =*/ +/*= =*/ +/*==============================================================================*/ + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 炎 ※ ハイカラー専用 -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- UINT Width : 幅 -*/ +/*- UINT Height : 高さ -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elEffect::Fire(int Px,int Py,UINT Width,UINT Height) +{ + static HRESULT ddret; + static DDSURFACEDESC ddsd; + static LPWORD data; + static long AddPitch; + static DWORD x,y; + static WORD Buff,R,G,B; + static int Count=0,Count2=0; + + // 構造体の初期化 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch=ddsd.lPitch>>1; + + // スプライトの先頭位置を取得 + data=(LPWORD)ddsd.lpSurface+Px+(Py+1)*AddPitch; + + // 1ライン分、Y方向に加算 + data+=AddPitch; + + // データ転送 + for (y=1;y>=2; + G>>=2; + B>>=2; + + Buff=(R<Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch=ddsd.lPitch>>1; + + // スプライトの先頭位置を取得 + data=(LPWORD)ddsd.lpSurface+Px+(Py+1)*AddPitch; + + // 1ライン分、Y方向に加算 + data+=AddPitch; + + // データ転送 + for (y=1;y>=2; + G>>=2; + B>>=2; + + if (Red && R>0) R--; + if (Green && G>0) G--; + if (Blue && B>0) B--; + + Buff=(R<Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch=ddsd.lPitch>>1; + + // スプライトの先頭位置を取得 + data=(LPWORD)ddsd.lpSurface+Px+(Py+1)*AddPitch; + + // データ転送 + for (y=1;y>=2; + G>>=2; + B>>=2; + + Buff=(R<Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch=ddsd.lPitch>>1; + + // スプライトの先頭位置を取得 + data=(LPWORD)ddsd.lpSurface+Px+(Py+1)*AddPitch; + + // データ転送 + for (y=1;y>=2; + G>>=2; + B>>=2; + + if (Red && R>0) R--; + if (Green && G>0) G--; + if (Blue && B>0) B--; + + Buff=(R<Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[BUFFER_SPRITE].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch; + + // データ転送 + if (!Mesh) + { + for (y=0;yLock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[BUFFER_SPRITE].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch=ddsd2.lPitch>>1; + AddPitchZoom=ddsd2.lPitch<<1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch; + + // データ転送 + if (!Mesh) + { + for (y=0;y=elDraw::Width) Ex-=Px+Ex-elDraw::Width; + if (Py+Ey>=elDraw::Height) Ey-=Py+Ey-elDraw::Height; + + // 構造体の初期化 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch=ddsd.lPitch>>1; + + // スプライトの先頭位置を取得 + data=(LPWORD)ddsd.lpSurface+Px+(Py+Sy)*AddPitch; + + // データ転送 + for (y=Sy;y=elDraw::Width) Ex2-=Px+x+Ex2-elDraw::Width; + if (Py+y+Ey2>=elDraw::Height) Ey2-=Py+y+Ey2-elDraw::Height; + + for (y2=0;y2=Radius) continue; + + *(data+x2+y2*AddPitch)=Buff; + } + } + } + + // Y方向に加算 + data+=AddPitch*Size; + } + + // スプライトのロック解除 + DD_UNLOCK(DDBack,ddsd.lpSurface); + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ノイズ ※ ハイカラー専用 -*/ +/*- -*/ +/*- int Force : 強さ ( 0〜 ) -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- UINT Width : 幅 -*/ +/*- UINT Height : 高さ -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elEffect::Noise(int Force,int Px,int Py,UINT Width,UINT Height) +{ + static HRESULT ddret; + static DDSURFACEDESC ddsd; + static LPWORD data; + static long AddPitch; + static DWORD x,y; + static WORD Buff,R,G,B,P; + static int Count=0; + + // 構造体の初期化 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch=ddsd.lPitch>>1; + + // スプライトの先頭位置を取得 + data=(LPWORD)ddsd.lpSurface+Px+Py*AddPitch; + + // データ転送 + if (Force==0) + { + for (y=0;y31) R=31; + if (G>31) G=31; + if (B>31) B=31; + + Buff=(R<31) R=31; + if (G>31) G=31; + if (B>31) B=31; + + Buff=(R<Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch=ddsd.lPitch>>1; + + // スプライトの先頭位置を取得 + data=(LPWORD)ddsd.lpSurface+Px+Py*AddPitch; + + // データ転送 + if (Force==0) + { + for (y=0;y31) R=31; + } + + if (Green) + { + G+=P; + + if (G>31) G=31; + } + + if (Blue) + { + B+=P; + + if (B>31) B=31; + } + + Buff=(R<31) R=31; + } + + if (Green) + { + G+=P; + + if (G>31) G=31; + } + + if (Blue) + { + B+=P; + + if (B>31) B=31; + } + + Buff=(R<SetCooperativeLevel(hwnd,DSSCL_PRIORITY)!=DS_OK) + { + DSObject->SetCooperativeLevel(hwnd,DSSCL_NORMAL); + } + + // バッファ1の初期化 + memset(&dsbd,0x00,sizeof(DSBUFFERDESC)); + dsbd.dwSize=sizeof(DSBUFFERDESC); + dsbd.dwFlags=DSBCAPS_PRIMARYBUFFER; + DSObject->CreateSoundBuffer(&dsbd,&DSBuff1,NULL); + + // バッファ2の初期化 + for (i=0;iStop(); + DSBuff2[i][j]->Release(); + DSBuff2[i][j]=NULL; + } + } + } + } + + // バッファ1の解放 + if (DSBuff1!=NULL) DSBuff1->Release(); + + // DirectSoundの解放 + if (DSObject!=NULL) DSObject->Release(); + } + + #ifdef CDDA + + // CDの停止 + elCD::Stop(); + + #endif +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- サウンドの読み込み -*/ +/*- -*/ +/*- char* FileName : WAVEファイル名またはリソース名 -*/ +/*- int Mix : ミックス数 -*/ +/*- 省略/1 = ミックスなし ( 1音だけ再生 ) -*/ +/*- 2〜 = 指定された数だけミックスあり -*/ +/*- -*/ +/*- 戻り値 : サウンド情報 ( DSOBJ型 ) -*/ +/*- -1 = エラー -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +DSOBJ elSound::LoadObject(char* FileName,int Mix=1) +{ + // DirectSoundが使用可能な場合 + if (Ok) + { + int i; + HRSRC hrsrc; + HRESULT ret; + DSBUFFERDESC dsbd; + DWORD* lpdword; + LPVOID lpbuf1,lpbuf2; + DWORD dwbuf1,dwbuf2; + BOOL ReadFile; + UINT Size,HeadSize; + LPWAVEFORMATEX Wave=NULL; + BYTE* Byte=NULL; + int TopThrough; + char Buffer[256]; + + // ミックス数の確認 + if (abs(Mix)>MIX_MAX) + { + elDraw::Error("elSound::LoadObject", + "ミックス数が多過ぎます"); + + return -1; + } + + // オブジェクト定義Noの検索 + if (!Reload) + { + ListNo=-1; + + for (i=0;i1) + { + // エフェクト可に設定 + ListEffectCount[ListNo]=0; + } + else + { + // エフェクト不可に設定 + ListEffectCount[ListNo]=-1; + } + + if (!Reload) ListUseMix[ListNo]=0; + + for (i=0;iCreateSoundBuffer(&dsbd,&DSBuff2[ListNo][i],NULL); + + if (ret!=DS_OK) + { + elDraw::Error("elSound::LoadObject", + "サウンドバッファが生成できません",ret); + + return -1; + } + + // バッファ2のロック + if (ReadFile) + { + DSBuff2[ListNo][i]->Lock(0,Size,&lpbuf1, + &dwbuf1,&lpbuf2,&dwbuf2,0); + } + else + { + DSBuff2[ListNo][i]->Lock(0,*(lpdword+10),&lpbuf1, + &dwbuf1,&lpbuf2,&dwbuf2,0); + } + + // 音源データの設定 + if (ReadFile) + { + memcpy(lpbuf1,Byte,Size); + } + else + { + CopyMemory(lpbuf1,(BYTE*)(lpdword+11),dwbuf1); + + if (dwbuf2!=0) CopyMemory(lpbuf2,(BYTE*)(lpdword+11)+dwbuf1, + dwbuf2); + } + + // バッファ2のロック解除 + DSBuff2[ListNo][i]->Unlock(lpbuf1,dwbuf1,lpbuf2,dwbuf2); + + if (!Reload) + { + // ピッチの取得と初期化 + DSBuff2[ListNo][i]->GetFrequency(&ListPitch[ListNo][i]); + ListPitchDef[ListNo]=ListPitch[ListNo][i]; + + // ボリュームとパンの初期化 + ListVolume[ListNo][i]=0L; + ListPan[ListNo][i]=0L; + } + else + { + // ボリューム・ピッチ・パンを再設定 + DSBuff2[ListNo][i]->SetVolume(ListVolume[ListNo][i]); + DSBuff2[ListNo][i]->SetFrequency(ListPitch[ListNo][i]); + DSBuff2[ListNo][i]->SetPan(ListPan[ListNo][i]); + } + } + + // サウンドフラグの設定 + ListUse[ListNo]=TRUE; + ListPack[ListNo]=FALSE; + + // メモリの解放 + if (Wave!=NULL) GlobalFreePtr(Wave); + if (Byte!=NULL) GlobalFreePtr(Byte); + + // ストリームを未使用に設定 + SoundStream[ListNo].DataSize=0; + + // ファイル名またはリソース名の保存 + if (!Reload) + { + if (strlen(FileName)>30) + { + elDraw::Error("elSound::LoadObject", + "ファイル名またはリソース名が長すぎます"); + + return -1; + } + else + { + strcpy(ListName[ListNo],FileName); + } + } + + return ListNo; + } + + return -1; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- サウンドの再読み込み -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::ReloadObject(void) +{ + // DirectSoundが使用可能な場合 + if (Ok) + { + elSound::Init(); + + Reload=TRUE; + + for (ListNo=0;ListNo0) + { + elSound::SetPack(SoundStream[ListNo].PackName); + + elSound::LoadStream(ListName[ListNo], + SoundStream[ListNo].LoopPos- + SoundStream[ListNo].StartPos); + } + else if (ListPack[ListNo]) + { + elSound::LoadPack(ListName[ListNo],ListMix[ListNo]); + } + else + { + elSound::LoadObject(ListName[ListNo],ListMix[ListNo]); + } + } + } + + Reload=FALSE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- サウンドを削除してメモリから解放 -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::FreeObject(DSOBJ ObjDS) +{ + // DirectSoundが使用可能な場合 + if (Ok) + { + int i; + + if (ListUse[ObjDS]) + { + ListUse[ObjDS]=FALSE; + ListPitchDef[ObjDS]=0UL; + ListName[ObjDS][0]=NULL; + ListPack[ObjDS]=FALSE; + SoundStream[ObjDS].DataSize=0; + + for (i=0;iStop(); + DSBuff2[ObjDS][i]->Release(); + DSBuff2[ObjDS][i]=NULL; + } + + ListMix[ObjDS]=1; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- パックファイルの指定 -*/ +/*- -*/ +/*- char* PackName : パックファイル名 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::SetPack(char* PackName) +{ + strcpy(PackFileName,elSystem::Directory()); + strcat(PackFileName,PackName); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- サウンドの読み込み ( パックファイル ) -*/ +/*- -*/ +/*- char* FileName : WAVEファイル名 -*/ +/*- int Mix : ミックス数 -*/ +/*- 省略/1 = ミックスなし ( 1音だけ再生 ) -*/ +/*- 2〜 = 指定された数だけミックスあり -*/ +/*- -*/ +/*- 戻り値 : サウンド情報 ( DSOBJ型 ) -*/ +/*- -1 = エラー -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +DSOBJ elSound::LoadPack(char* FileName,int Mix=1) +{ + // DirectSoundが使用可能な場合 + if (Ok) + { + int i; + HRESULT ret; + DSBUFFERDESC dsbd; + DWORD* lpdword; + LPVOID lpbuf1,lpbuf2; + DWORD dwbuf1,dwbuf2; + UINT Size,HeadSize; + LPWAVEFORMATEX Wave=NULL; + BYTE* Byte=NULL; + FILE* Fpt; + char Buffer1[128],Buffer2[128]; + BYTE c; + BOOL Ok; + + // ミックス数の確認 + if (abs(Mix)>MIX_MAX) + { + elDraw::Error("elSound::LoadPack", + "ミックス数が多過ぎます"); + + return -1; + } + + // オブジェクト定義Noの検索 + if (!Reload) + { + ListNo=-1; + + for (i=0;i1) + { + // エフェクト可に設定 + ListEffectCount[ListNo]=0; + } + else + { + // エフェクト不可に設定 + ListEffectCount[ListNo]=-1; + } + + if (!Reload) ListUseMix[ListNo]=0; + + for (i=0;iCreateSoundBuffer(&dsbd,&DSBuff2[ListNo][i],NULL); + + if (ret!=DS_OK) + { + elDraw::Error("elSound::LoadPack", + "サウンドバッファが生成できません",ret); + + return -1; + } + + // バッファ2のロック + DSBuff2[ListNo][i]->Lock(0,Size,&lpbuf1, + &dwbuf1,&lpbuf2,&dwbuf2,0); + + // 音源データの設定 + memcpy(lpbuf1,Byte,Size); + + // バッファ2のロック解除 + DSBuff2[ListNo][i]->Unlock(lpbuf1,dwbuf1,lpbuf2,dwbuf2); + + if (!Reload) + { + // ピッチの取得と初期化 + DSBuff2[ListNo][i]->GetFrequency(&ListPitch[ListNo][i]); + ListPitchDef[ListNo]=ListPitch[ListNo][i]; + + // ボリュームとパンの初期化 + ListVolume[ListNo][i]=0L; + ListPan[ListNo][i]=0L; + } + else + { + // ボリューム・ピッチ・パンを再設定 + DSBuff2[ListNo][i]->SetVolume(ListVolume[ListNo][i]); + DSBuff2[ListNo][i]->SetFrequency(ListPitch[ListNo][i]); + DSBuff2[ListNo][i]->SetPan(ListPan[ListNo][i]); + } + } + + // サウンドフラグの設定 + ListUse[ListNo]=TRUE; + ListPack[ListNo]=TRUE; + + // メモリの解放 + if (Wave!=NULL) GlobalFreePtr(Wave); + if (Byte!=NULL) GlobalFreePtr(Byte); + + // ストリームを未使用に設定 + SoundStream[ListNo].DataSize=0; + + // ファイル名の保存 + if (!Reload) + { + if (strlen(FileName)>30) + { + elDraw::Error("elSound::LoadPack", + "ファイル名が長すぎます"); + + return -1; + } + else + { + strcpy(ListName[ListNo],FileName); + } + } + + return ListNo; + } + else + { + elDraw::Error("elSound::LoadPack", + "パックファイル名が指定されていません"); + + return -1; + } + } + + return -1; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- サウンドのストリーミング読み込み ( パックファイル ) -*/ +/*- -*/ +/*- char* FileName : WAVEファイル名 -*/ +/*- DWORD LoopPoint : ループ再生時の巻き戻し位置 ( 先頭からのバイト数 ) -*/ +/*- 省略/0 = ファイル先頭からループ再生 -*/ +/*- 1〜 = 指定された位置からループ再生 -*/ +/*- -*/ +/*- 戻り値 : サウンド情報 ( DSOBJ型 ) -*/ +/*- -1 = エラー -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +DSOBJ elSound::LoadStream(char* FileName,DWORD LoopPoint=0) +{ + // DirectSoundが使用可能な場合 + if (Ok) + { + int i; + HRESULT ret; + DSBUFFERDESC dsbd; + DWORD* lpdword; + LPVOID lpbuf1,lpbuf2; + DWORD dwbuf1,dwbuf2; + UINT Size,HeadSize; + LPWAVEFORMATEX Wave=NULL; + BYTE* Byte=NULL; + FILE* Fpt; + char Buffer1[128],Buffer2[128]; + BYTE c; + BOOL Ok; + + // オブジェクト定義Noの検索 + if (!Reload) + { + ListNo=-1; + + for (i=0;inAvgBytesPerSecnAvgBytesPerSec*SOUND_STREAM_TIME; + + // 書き込むデータサイズを取得 + SoundStream[ListNo].WriteSize=Wave->nAvgBytesPerSec* + SOUND_STREAM_TIME/2; + + // 次のデータ書き込み用のチェック位置を初期化 + SoundStream[ListNo].WriteCheck=0; + + // 次のデータ書き込み位置を初期化 + SoundStream[ListNo].NextWrite=SoundStream[ListNo].WriteSize; + + // ファイルの先頭シーク位置を取得 + SoundStream[ListNo].StartPos=ftell(Fpt); + + // ファイルのループシーク位置を取得 + SoundStream[ListNo].LoopPos=SoundStream[ListNo].StartPos+LoopPoint; + + // WAVEサウンドデータの読み込み + Byte=(BYTE*)GlobalAlloc(GMEM_FIXED,SoundStream[ListNo].WriteSize); + + fread(Byte,SoundStream[ListNo].WriteSize,1,Fpt); + + // ファイルのシーク位置を取得 + SoundStream[ListNo].SeekPos=ftell(Fpt); + + fclose(Fpt); + + // 読み込んだデータサイズを取得 + SoundStream[ListNo].ReadData=SoundStream[ListNo].WriteSize; + + // 前回の処理での再生位置を初期化 + SoundStream[ListNo].PlayPos=0xFFFFFFFF; + + // 直前フレームでの再生位置を初期化 + SoundStream[ListNo].LastPos=0; + + // 次の判定での停止フラグを初期化 + SoundStream[ListNo].NextStop=0; + + // バッファ2を生成 + ListMix[ListNo]=1; + ListEffectCount[ListNo]=-1; + + if (!Reload) ListUseMix[ListNo]=0; + + // バッファ2の初期化 + memset(&dsbd,0x00,sizeof(DSBUFFERDESC)); + dsbd.dwSize=sizeof(DSBUFFERDESC); + dsbd.dwFlags=DSBCAPS_STATIC|DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLPAN| + DSBCAPS_CTRLVOLUME|DSBCAPS_GETCURRENTPOSITION2| + DSBCAPS_GLOBALFOCUS; + dsbd.dwBufferBytes=SoundStream[ListNo].WriteMax; + dsbd.lpwfxFormat=(LPWAVEFORMATEX)(lpdword); + + ret=DSObject->CreateSoundBuffer(&dsbd,&DSBuff2[ListNo][0],NULL); + + if (ret!=DS_OK) + { + elDraw::Error("elSound::LoadStream", + "サウンドバッファが生成できません",ret); + + return -1; + } + + // バッファ2のロック + DSBuff2[ListNo][0]->Lock(0,SoundStream[ListNo].WriteSize, + &lpbuf1,&dwbuf1,&lpbuf2,&dwbuf2,0); + + // WAVEデータの設定 + memcpy(lpbuf1,Byte,SoundStream[ListNo].WriteSize); + + // バッファ2のロック解除 + DSBuff2[ListNo][0]->Unlock(lpbuf1,SoundStream[ListNo].WriteSize, + lpbuf2,dwbuf2); + + if (!Reload) + { + // ピッチの取得と初期化 + DSBuff2[ListNo][0]->GetFrequency(&ListPitch[ListNo][0]); + ListPitchDef[ListNo]=ListPitch[ListNo][0]; + + // ボリュームとパンの初期化 + ListVolume[ListNo][0]=0L; + ListPan[ListNo][0]=0L; + } + else + { + // ボリューム・ピッチ・パンを再設定 + DSBuff2[ListNo][0]->SetVolume(ListVolume[ListNo][0]); + DSBuff2[ListNo][0]->SetFrequency(ListPitch[ListNo][0]); + DSBuff2[ListNo][0]->SetPan(ListPan[ListNo][0]); + } + + // サウンドフラグの設定 + ListUse[ListNo]=TRUE; + ListPack[ListNo]=TRUE; + + // メモリの解放 + if (Wave!=NULL) GlobalFreePtr(Wave); + if (Byte!=NULL) GlobalFreePtr(Byte); + + // ファイル名の保存 + if (!Reload) + { + if (strlen(FileName)>30) + { + elDraw::Error("elSound::LoadStream", + "ファイル名が長すぎます"); + + return -1; + } + else + { + strcpy(ListName[ListNo],FileName); + } + } + + return ListNo; + } + else + { + elDraw::Error("elSound::LoadStream", + "パックファイル名が指定されていません"); + + return -1; + } + } + + return -1; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- サウンドのストリーミング -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elSound::Streaming(void) +{ + // DirectSoundが使用可能な場合 + if (Ok) + { + LPVOID lpbuf1,lpbuf2; + DWORD dwbuf1,dwbuf2; + BYTE* Byte; + FILE* Fpt; + DWORD PlayPos,WriteSize; + int i,a; + DWORD Status; + + for (i=0;iGetStatus(&Status); + + // 停止している場合 + if (!(Status&DSBSTATUS_PLAYING)) + { + // 未処理 + continue; + } + + // 現在の再生位置を取得 + DSBuff2[i][0]->GetCurrentPosition(&PlayPos,NULL); + + // まだ次のデータを読み込まなくて良い場合 + #define SSPP SoundStream[i].PlayPos + #define PP PlayPos + #define SSLP SoundStream[i].LastPos + #define SSWC SoundStream[i].WriteCheck + + if (SSPP==0xFFFFFFFF && + PP=SSLP || + SSPP!=0xFFFFFFFF && + (SSWC=SSPP) || + SSWC>=SSPP && PP0) + { + // 停止させる場合 + if (--SoundStream[i].NextStop==0) + { + // 停止 + elSound::Stop(i,-1); + + continue; + } + } + + // パックファイルからWAVEファイルを検索 + if ((Fpt=fopen(SoundStream[i].PackName,"rb"))!=NULL) + { + // データの読み込み位置までシーク + if (fseek(Fpt,SoundStream[i].SeekPos,SEEK_SET)) + { + return elDraw::Error("elSound::Streaming", + "ストリーミング再生できません"); + } + + // 書き込みサイズの算出 + WriteSize=SoundStream[i].WriteSize; + + // データの最大を超えた場合 + if (WriteSize+SoundStream[i].ReadData>SoundStream[i].DataSize) + { + // 超えない範囲を対象に設定 + a=WriteSize+SoundStream[i].ReadData-SoundStream[i].DataSize; + + WriteSize-=a; + } + // データの最大を超えていない場合 + else + { + // 書き込みサイズ未満のデータが残る可能性がある場合 + if (SoundStream[i].DataSize- + (WriteSize+SoundStream[i].ReadData)=SoundStream[i].DataSize) + { + // ループポイントにシーク位置を設定 + SoundStream[i].SeekPos=SoundStream[i].LoopPos; + SoundStream[i].ReadData=SoundStream[i].LoopPos- + SoundStream[i].StartPos; + + // ループ再生ではない場合 + if (!ListLoop[i]) + { + // 次の判定で停止 + SoundStream[i].NextStop=2; + } + } + + // バッファ2のロック + DSBuff2[i][0]->Lock(SoundStream[i].NextWrite,WriteSize, + &lpbuf1,&dwbuf1,&lpbuf2,&dwbuf2,0); + + // 次に停止させる場合 + if (SoundStream[i].NextStop==1) + { + // ノイズ防止のため音源データに無音を設定 + memset(lpbuf1,0x00,dwbuf1); + if (dwbuf2!=0) memset(lpbuf2,0x00,dwbuf2); + } + else + { + // WAVEデータの設定 + memcpy(lpbuf1,Byte,dwbuf1); + if (dwbuf2!=0) memcpy(lpbuf2,Byte+dwbuf1,dwbuf2); + } + + // バッファ2のロック解除 + DSBuff2[i][0]->Unlock(lpbuf1,dwbuf1,lpbuf2,dwbuf2); + + // ストリーミングバッファがループする場合 + if (SoundStream[i].NextWriteSoundStream[i].WriteMax) + { + SoundStream[i].WriteCheck-=SoundStream[i].WriteMax; + } + + // 次のデータ書き込み位置を算出 + SoundStream[i].NextWrite+=WriteSize; + + if (SoundStream[i].NextWrite>=SoundStream[i].WriteMax) + { + SoundStream[i].NextWrite-=SoundStream[i].WriteMax; + } + + // メモリの解放 + if (Byte!=NULL) GlobalFreePtr(Byte); + } + else + { + return elDraw::Error("elSound::Streaming", + "パックファイル名が指定されていません"); + } + } + + return TRUE; + } + + return FALSE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ストリームバッファのリセット -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elSound::ResetStream(DSOBJ ObjDS) +{ + // DirectSoundが使用可能な場合 + if (Ok) + { + LPVOID lpbuf1,lpbuf2; + DWORD dwbuf1,dwbuf2; + BYTE* Byte=NULL; + FILE* Fpt; + + // パックファイルからWAVEファイルを検索 + if ((Fpt=fopen(SoundStream[ObjDS].PackName,"rb"))!=NULL) + { + // ファイル先頭位置までシーク + if (fseek(Fpt,SoundStream[ObjDS].StartPos,SEEK_SET)) + { + return elDraw::Error("elSound::ResetStream", + "ストリーミング再生できません"); + } + + // 次のデータ書き込み書き込み用のチェック位置を初期化 + SoundStream[ObjDS].WriteCheck=0; + + // 次のデータ書き込み位置を初期化 + SoundStream[ObjDS].NextWrite=SoundStream[ObjDS].WriteSize; + + // WAVEサウンドデータの読み込み + Byte=(BYTE*)GlobalAlloc(GMEM_FIXED,SoundStream[ObjDS].WriteSize); + + fread(Byte,SoundStream[ObjDS].WriteSize,1,Fpt); + + // ファイルのシーク位置を取得 + SoundStream[ObjDS].SeekPos=ftell(Fpt); + + fclose(Fpt); + + // 読み込んだデータサイズを取得 + SoundStream[ObjDS].ReadData=SoundStream[ObjDS].WriteSize; + + // 前回の処理での再生位置を初期化 + SoundStream[ObjDS].PlayPos=0xFFFFFFFF; + + // 直前フレームでの再生位置を初期化 + SoundStream[ObjDS].LastPos=0; + + // 次の判定での停止フラグを初期化 + SoundStream[ObjDS].NextStop=0; + + // バッファ2のロック + DSBuff2[ObjDS][0]->Lock(0,SoundStream[ObjDS].WriteSize, + &lpbuf1,&dwbuf1,&lpbuf2,&dwbuf2,0); + + // WAVEデータの設定 + memcpy(lpbuf1,Byte,SoundStream[ObjDS].WriteSize); + + // バッファ2のロック解除 + DSBuff2[ObjDS][0]->Unlock(lpbuf1,SoundStream[ObjDS].WriteSize, + lpbuf2,dwbuf2); + + // メモリの解放 + if (Byte!=NULL) GlobalFreePtr(Byte); + + return TRUE; + } + else + { + return elDraw::Error("elSound::ResetStream", + "パックファイル名が指定されていません"); + } + } + + return FALSE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- サウンドをパック化 -*/ +/*- -*/ +/*- char* PackName : パックファイル名 -*/ +/*- char* WaveDir : WAVEファイルがあるディレクトリィ -*/ +/*- BOOL Delete : パックファイル削除フラグ -*/ +/*- 省略/TRUE = 削除する -*/ +/*- FALSE = 削除しない -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elSound::Convert(char* PackName,char* WaveDir,BOOL Delete=TRUE) +{ + char Buffer[256]; + WIN32_FIND_DATA fd; + HANDLE hd; + + // パックファイルを削除する場合 + if (Delete) + { + // 現在のパックファイルを削除 + strcpy(Buffer,elSystem::Directory()); + strcat(Buffer,PackName); + remove(Buffer); + } + + // WAVEファイルの検索 + strcpy(Buffer,elSystem::Directory()); + + if (WaveDir[0]!=NULL) + { + strcat(Buffer,WaveDir); + strcat(Buffer,"\\*.WAV"); + } + else + { + strcat(Buffer,"*.WAV"); + } + + hd=FindFirstFile(Buffer,&fd); + + if (hd!=INVALID_HANDLE_VALUE) + { + while (TRUE) + { + // 見つかったWAVEファイルの変換 + if (WaveDir[0]!=NULL) + { + strcpy(Buffer,WaveDir); + strcat(Buffer,"\\"); + } + else + { + Buffer[0]=NULL; + } + + strcat(Buffer,fd.cFileName); + + CharUpperBuff(Buffer,strlen(Buffer)); + + ConvertFile(PackName,Buffer); + + if (!FindNextFile(hd,&fd)) break; + } + + FindClose(hd); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- WAVEからサウンドデータを抽出 ※ 内部で使用 -*/ +/*- -*/ +/*- char* PackName : パックファイル名 -*/ +/*- char* WaveName : WAVEファイル名 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::ConvertFile(char* PackName,char* WaveName) +{ + UINT Size,HeadSize; + LPWAVEFORMATEX Wave=NULL; + BYTE* Byte=NULL; + FILE* Fpt; + char Buffer[256]; + int i,j; + + // WAVEの読み込み + strcpy(Buffer,elSystem::Directory()); + strcat(Buffer,WaveName); + + elSound::SearchFile(Buffer,&Wave,&HeadSize,&Byte,&Size); + + // パックファイルのオープン + strcpy(Buffer,elSystem::Directory()); + strcat(Buffer,PackName); + + if ((Fpt=fopen(Buffer,"ab"))!=NULL) + { + // WAVEサイズの書き込み + fwrite(&Size,4,1,Fpt); + + // WAVEファイル名の書き込み + for (i=(int)strlen(WaveName);i>=0 && WaveName[i]!='\\';i--); + + for (i++,j=0;WaveName[i]!=NULL;i++,j++) + { + Buffer[j]=WaveName[i]; + } + + Buffer[j]=NULL; + + fwrite(Buffer,strlen(Buffer)+1,1,Fpt); + + // WAVEフォーマットサイズの書き込み + fwrite(&HeadSize,4,1,Fpt); + + // WAVEフォーマットの書き込み + fwrite(Wave,HeadSize,1,Fpt); + + // WAVEサウンドデータの書き込み + fwrite(Byte,Size,1,Fpt); + + fclose(Fpt); + } + + // メモリの解放 + if (Wave!=NULL) GlobalFreePtr(Wave); + if (Byte!=NULL) GlobalFreePtr(Byte); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- サウンドの再生 -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Mix : 省略/-1 = 可能ならば自動でミックス再生 -*/ +/*- 0〜 = 指定されたミックスNoを再生 -*/ +/*- USE_EFFECT = エフェクト使用 -*/ +/*- -3 = エフェクト音 ( 内部で使用 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::Play(DSOBJ ObjDS,int Mix=-1) +{ + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + DSBuff2[ObjDS][Mix]->Stop(); + DSBuff2[ObjDS][Mix]->SetCurrentPosition(0L); + + if (SoundStream[ObjDS].DataSize==0) + { + DSBuff2[ObjDS][Mix]->Play(0,0,0); + } + else + { + ResetStream(ObjDS); + DSBuff2[ObjDS][Mix]->Play(0,0,DSBPLAY_LOOPING); + } + } + else + { + if (ListEffectCount[ObjDS]>=0 && Mix==USE_EFFECT) + { + elSound::InitPitch(ObjDS,-1); + elSound::InitPan(ObjDS,-1); + elSound::InitVolume(ObjDS,-1); + ListEffectCount[ObjDS]=1; + ListEffectTime[ObjDS]=F(0); + ListEffectLoop[ObjDS]=FALSE; + ListEffectPos[ObjDS]=F(ListPan[ObjDS][ListUseMix[ObjDS]]); + ListEffectDir[ObjDS]=((int)(rand()%2))*2-1; + } + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->Stop(); + DSBuff2[ObjDS][ListUseMix[ObjDS]]->SetCurrentPosition(0L); + + if (SoundStream[ObjDS].DataSize==0) + { + DSBuff2[ObjDS][ListUseMix[ObjDS]]->Play(0,0,0); + } + else + { + ResetStream(ObjDS); + DSBuff2[ObjDS][ListUseMix[ObjDS]]->Play(0,0,DSBPLAY_LOOPING); + } + + if (++ListUseMix[ObjDS]==ListMix[ObjDS]) + { + ListUseMix[ObjDS]=0; + } + } + + ListLoop[ObjDS]=FALSE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- サウンドのループ再生 -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Mix : 省略/-1 = 可能ならば自動でミックス再生 -*/ +/*- 0〜 = 指定されたミックスNoを再生 -*/ +/*- USE_EFFECT = エフェクト使用 -*/ +/*- -3 = エフェクト音 ( 内部で使用 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::Loop(DSOBJ ObjDS,int Mix=-1) +{ + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + DSBuff2[ObjDS][Mix]->Stop(); + + if (SoundStream[ObjDS].DataSize>0) + { + ResetStream(ObjDS); + } + + DSBuff2[ObjDS][Mix]->SetCurrentPosition(0L); + DSBuff2[ObjDS][Mix]->Play(0,0,DSBPLAY_LOOPING); + } + else + { + if (ListEffectCount[ObjDS]>=0 && Mix==USE_EFFECT) + { + elSound::InitPitch(ObjDS,-1); + elSound::InitPan(ObjDS,-1); + elSound::InitVolume(ObjDS,-1); + ListEffectCount[ObjDS]=1; + ListEffectTime[ObjDS]=F(0); + ListEffectLoop[ObjDS]=TRUE; + ListEffectPos[ObjDS]=F(ListPan[ObjDS][ListUseMix[ObjDS]]); + ListEffectDir[ObjDS]=((int)(rand()%2))*2-1; + } + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->Stop(); + + if (SoundStream[ObjDS].DataSize>0) + { + ResetStream(ObjDS); + } + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->SetCurrentPosition(0L); + DSBuff2[ObjDS][ListUseMix[ObjDS]]->Play(0,0,DSBPLAY_LOOPING); + + if (++ListUseMix[ObjDS]==ListMix[ObjDS]) + { + ListUseMix[ObjDS]=0; + } + } + + ListLoop[ObjDS]=TRUE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- サウンドの停止 -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Mix : 省略/-1 = 複数ミックスできる場合は全てを停止 -*/ +/*- 0〜 = 指定されたミックスNoを停止 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::Stop(DSOBJ ObjDS,int Mix=-1) +{ + static int i; + + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + DSBuff2[ObjDS][Mix]->Stop(); + DSBuff2[ObjDS][Mix]->SetCurrentPosition(0L); + } + else + { + if (ListEffectCount[ObjDS]>=0) ListEffectCount[ObjDS]=0; + + for (i=0;iStop(); + DSBuff2[ObjDS][i]->SetCurrentPosition(0L); + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- サウンドの一時停止及び一時停止解除 -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Mix : 省略/-1 = 複数ミックスできる場合は全てを処理 -*/ +/*- 0〜 = 指定されたミックスNoを処理 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::Pause(DSOBJ ObjDS,int Mix=-1) +{ + static int i; + static DWORD Status; + + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + DSBuff2[ObjDS][Mix]->GetStatus(&Status); + + if (Status&DSBSTATUS_PLAYING) + { + DSBuff2[ObjDS][Mix]->GetCurrentPosition(&ListPosition[ObjDS][Mix], + NULL); + + DSBuff2[ObjDS][Mix]->Stop(); + } + else + { + DSBuff2[ObjDS][Mix]->SetCurrentPosition(ListPosition[ObjDS][Mix]); + + if (ListLoop[ObjDS]) + { + DSBuff2[ObjDS][Mix]->Play(0,0,DSBPLAY_LOOPING); + } + else + { + DSBuff2[ObjDS][Mix]->Play(0,0,0); + } + } + } + else + { + for (i=0;iGetStatus(&Status); + + if (Status&DSBSTATUS_PLAYING) + { + DSBuff2[ObjDS][i]->GetCurrentPosition(&ListPosition[ObjDS][i], + NULL); + + DSBuff2[ObjDS][i]->Stop(); + } + else + { + DSBuff2[ObjDS][i]->SetCurrentPosition(ListPosition[ObjDS][i]); + + if (ListLoop[ObjDS]) + { + DSBuff2[ObjDS][i]->Play(0,0,DSBPLAY_LOOPING); + } + else + { + DSBuff2[ObjDS][i]->Play(0,0,0); + } + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ピッチの変調 ( 相対値 ) -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Value : 加減値 -*/ +/*- int Mix : 省略/-1 = 複数ミックスできる場合は全てを処理 -*/ +/*- 0〜 = 指定されたミックスNoを処理 -*/ +/*- NEXT_MIX = 次に再生されるミックスNoを処理 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::Pitch(DSOBJ ObjDS,int Value,int Mix=-1) +{ + static int i; + + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + ListPitch[ObjDS][Mix]+=(ULONG)Value*100UL; + + if (ListPitch[ObjDS][Mix]<100UL) ListPitch[ObjDS][Mix]=100UL; + if (ListPitch[ObjDS][Mix]>100000UL) ListPitch[ObjDS][Mix]=100000UL; + + DSBuff2[ObjDS][Mix]->SetFrequency(ListPitch[ObjDS][Mix]); + } + else + { + if (Mix==NEXT_MIX) + { + ListPitch[ObjDS][ListUseMix[ObjDS]]+=(ULONG)Value*100UL; + + if (ListPitch[ObjDS][ListUseMix[ObjDS]]<100UL) + { + ListPitch[ObjDS][ListUseMix[ObjDS]]=100UL; + } + + if (ListPitch[ObjDS][ListUseMix[ObjDS]]>100000UL) + { + ListPitch[ObjDS][ListUseMix[ObjDS]]=100000UL; + } + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->SetFrequency( + ListPitch[ObjDS][ListUseMix[ObjDS]]); + } + else + { + for (i=0;i100000UL) + { + ListPitch[ObjDS][i]=100000UL; + } + + DSBuff2[ObjDS][i]->SetFrequency(ListPitch[ObjDS][i]); + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ピッチの初期化 -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Mix : 省略/-1 = 複数ミックスできる場合は全てを処理 -*/ +/*- 0〜 = 指定されたミックスNoを処理 -*/ +/*- NEXT_MIX = 次に再生されるミックスNoを処理 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::InitPitch(DSOBJ ObjDS,int Mix=-1) +{ + static int i; + + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + ListPitch[ObjDS][Mix]=ListPitchDef[ObjDS]; + + DSBuff2[ObjDS][Mix]->SetFrequency(ListPitch[ObjDS][Mix]); + } + else + { + if (Mix==NEXT_MIX) + { + ListPitch[ObjDS][ListUseMix[ObjDS]]=ListPitchDef[ObjDS]; + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->SetFrequency( + ListPitch[ObjDS][ListUseMix[ObjDS]]); + } + else + { + for (i=0;iSetFrequency(ListPitch[ObjDS][i]); + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ピッチの変調 ( 絶対値 ) -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Value : 加減値 -*/ +/*- int Mix : 省略/-1 = 複数ミックスできる場合は全てを処理 -*/ +/*- 0〜 = 指定されたミックスNoを処理 -*/ +/*- NEXT_MIX = 次に再生されるミックスNoを処理 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::SetPitch(DSOBJ ObjDS,int Value,int Mix=-1) +{ + static int i; + + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + ListPitch[ObjDS][Mix]=ListPitchDef[ObjDS]+(ULONG)Value*100UL; + + if (ListPitch[ObjDS][Mix]<100UL) ListPitch[ObjDS][Mix]=100UL; + if (ListPitch[ObjDS][Mix]>100000UL) ListPitch[ObjDS][Mix]=100000UL; + + DSBuff2[ObjDS][Mix]->SetFrequency(ListPitch[ObjDS][Mix]); + } + else + { + if (Mix==NEXT_MIX) + { + ListPitch[ObjDS][ListUseMix[ObjDS]]=ListPitchDef[ObjDS]+ + (ULONG)Value*100UL; + + if (ListPitch[ObjDS][ListUseMix[ObjDS]]<100UL) + { + ListPitch[ObjDS][ListUseMix[ObjDS]]=100UL; + } + + if (ListPitch[ObjDS][ListUseMix[ObjDS]]>100000UL) + { + ListPitch[ObjDS][ListUseMix[ObjDS]]=100000UL; + } + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->SetFrequency( + ListPitch[ObjDS][ListUseMix[ObjDS]]); + } + else + { + for (i=0;i100000UL) + { + ListPitch[ObjDS][i]=100000UL; + } + + DSBuff2[ObjDS][i]->SetFrequency(ListPitch[ObjDS][i]); + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- パンの振り分け -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Value : 振り分け値 -*/ +/*- int Mix : 省略/-1 = 複数ミックスできる場合は全てを処理 -*/ +/*- 0〜 = 指定されたミックスNoを処理 -*/ +/*- NEXT_MIX = 次に再生されるミックスNoを処理 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::Pan(DSOBJ ObjDS,int Value,int Mix=-1) +{ + static int i; + + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + ListPan[ObjDS][Mix]+=(long)Value*100L; + + if (ListPan[ObjDS][Mix]<-10000L) ListPan[ObjDS][Mix]=-10000L; + if (ListPan[ObjDS][Mix]>10000L) ListPan[ObjDS][Mix]=10000L; + + DSBuff2[ObjDS][Mix]->SetPan(ListPan[ObjDS][Mix]); + } + else + { + if (Mix==NEXT_MIX) + { + ListPan[ObjDS][ListUseMix[ObjDS]]+=(long)Value*100L; + + if (ListPan[ObjDS][ListUseMix[ObjDS]]<-10000L) + { + ListPan[ObjDS][ListUseMix[ObjDS]]=-10000L; + } + + if (ListPan[ObjDS][ListUseMix[ObjDS]]>10000L) + { + ListPan[ObjDS][ListUseMix[ObjDS]]=10000L; + } + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->SetPan( + ListPan[ObjDS][ListUseMix[ObjDS]]); + } + else + { + for (i=0;i10000L) ListPan[ObjDS][i]=10000L; + + DSBuff2[ObjDS][i]->SetPan(ListPan[ObjDS][i]); + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- パンの初期化 -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Mix : 省略/-1 = 複数ミックスできる場合は全てを処理 -*/ +/*- 0〜 = 指定されたミックスNoを処理 -*/ +/*- NEXT_MIX = 次に再生されるミックスNoを処理 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::InitPan(DSOBJ ObjDS,int Mix=-1) +{ + static int i; + + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + ListPan[ObjDS][Mix]=0L; + + DSBuff2[ObjDS][Mix]->SetPan(ListPan[ObjDS][Mix]); + } + else + { + if (Mix==NEXT_MIX) + { + ListPan[ObjDS][ListUseMix[ObjDS]]=0L; + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->SetPan( + ListPan[ObjDS][ListUseMix[ObjDS]]); + } + else + { + for (i=0;iSetPan(ListPan[ObjDS][i]); + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- パンの振り分け ( 絶対値 ) -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Value : 振り分け値 -*/ +/*- int Mix : 省略/-1 = 複数ミックスできる場合は全てを処理 -*/ +/*- 0〜 = 指定されたミックスNoを処理 -*/ +/*- NEXT_MIX = 次に再生されるミックスNoを処理 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::SetPan(DSOBJ ObjDS,int Value,int Mix=-1) +{ + static int i; + + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + ListPan[ObjDS][Mix]=(long)Value*100L; + + if (ListPan[ObjDS][Mix]<-10000L) ListPan[ObjDS][Mix]=-10000L; + if (ListPan[ObjDS][Mix]>10000L) ListPan[ObjDS][Mix]=10000L; + + DSBuff2[ObjDS][Mix]->SetPan(ListPan[ObjDS][Mix]); + } + else + { + if (Mix==NEXT_MIX) + { + ListPan[ObjDS][ListUseMix[ObjDS]]=(long)Value*100L; + + if (ListPan[ObjDS][ListUseMix[ObjDS]]<-10000L) + { + ListPan[ObjDS][ListUseMix[ObjDS]]=-10000L; + } + + if (ListPan[ObjDS][ListUseMix[ObjDS]]>10000L) + { + ListPan[ObjDS][ListUseMix[ObjDS]]=10000L; + } + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->SetPan(ListPan[ObjDS] + [ListUseMix[ObjDS]]); + } + else + { + for (i=0;i10000L) ListPan[ObjDS][i]=10000L; + + DSBuff2[ObjDS][i]->SetPan(ListPan[ObjDS][i]); + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- パンを左に振り分け -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Mix : 省略/-1 = 複数ミックスできる場合は全てを処理 -*/ +/*- 0〜 = 指定されたミックスNoを処理 -*/ +/*- NEXT_MIX = 次に再生されるミックスNoを処理 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::LeftPan(DSOBJ ObjDS,int Mix=-1) +{ + static int i; + + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + ListPan[ObjDS][Mix]=-10000L; + + DSBuff2[ObjDS][Mix]->SetPan(ListPan[ObjDS][Mix]); + } + else + { + if (Mix==NEXT_MIX) + { + ListPan[ObjDS][ListUseMix[ObjDS]]=-10000L; + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->SetPan( + ListPan[ObjDS][ListUseMix[ObjDS]]); + } + else + { + for (i=0;iSetPan(ListPan[ObjDS][i]); + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- パンを右に振り分け -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Mix : 省略/-1 = 複数ミックスできる場合は全てを処理 -*/ +/*- 0〜 = 指定されたミックスNoを処理 -*/ +/*- NEXT_MIX = 次に再生されるミックスNoを処理 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::RightPan(DSOBJ ObjDS,int Mix=-1) +{ + static int i; + + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + ListPan[ObjDS][Mix]=10000L; + + DSBuff2[ObjDS][Mix]->SetPan(ListPan[ObjDS][Mix]); + } + else + { + if (Mix==NEXT_MIX) + { + ListPan[ObjDS][ListUseMix[ObjDS]]=10000L; + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->SetPan( + ListPan[ObjDS][ListUseMix[ObjDS]]); + } + else + { + for (i=0;iSetPan(ListPan[ObjDS][i]); + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ボリュームの調整 -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Value : 加減値 -*/ +/*- int Mix : 省略/-1 = 複数ミックスできる場合は全てを処理 -*/ +/*- 0〜 = 指定されたミックスNoを処理 -*/ +/*- NEXT_MIX = 次に再生されるミックスNoを処理 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::Volume(DSOBJ ObjDS,int Value,int Mix=-1) +{ + static int i; + + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + ListVolume[ObjDS][Mix]+=(long)Value*100L; + + if (ListVolume[ObjDS][Mix]>0L) ListVolume[ObjDS][Mix]=0L; + if (ListVolume[ObjDS][Mix]<-10000L) ListVolume[ObjDS][Mix]=-10000L; + + DSBuff2[ObjDS][Mix]->SetVolume(ListVolume[ObjDS][Mix]); + } + else + { + if (Mix==NEXT_MIX) + { + ListVolume[ObjDS][ListUseMix[ObjDS]]+=(long)Value*100L; + + if (ListVolume[ObjDS][ListUseMix[ObjDS]]>0L) + { + ListVolume[ObjDS][ListUseMix[ObjDS]]=0L; + } + + if (ListVolume[ObjDS][ListUseMix[ObjDS]]<-10000L) + { + ListVolume[ObjDS][ListUseMix[ObjDS]]=-10000L; + } + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->SetVolume( + ListVolume[ObjDS][ListUseMix[ObjDS]]); + } + else + { + for (i=0;i0L) + { + ListVolume[ObjDS][i]=0L; + } + + if (ListVolume[ObjDS][i]<-10000L) + { + ListVolume[ObjDS][i]=-10000L; + } + + DSBuff2[ObjDS][i]->SetVolume(ListVolume[ObjDS][i]); + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ボリュームの初期化 -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Mix : 省略/-1 = 複数ミックスできる場合は全てを処理 -*/ +/*- 0〜 = 指定されたミックスNoを処理 -*/ +/*- NEXT_MIX = 次に再生されるミックスNoを処理 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::InitVolume(DSOBJ ObjDS,int Mix=-1) +{ + static int i; + + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + ListVolume[ObjDS][Mix]=0L; + + DSBuff2[ObjDS][Mix]->SetVolume(ListVolume[ObjDS][Mix]); + } + else + { + if (Mix==NEXT_MIX) + { + ListVolume[ObjDS][ListUseMix[ObjDS]]=0L; + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->SetVolume( + ListVolume[ObjDS][ListUseMix[ObjDS]]); + } + else + { + for (i=0;iSetVolume(ListVolume[ObjDS][i]); + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ボリュームの調整 ( 絶対値 ) -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Value : 加減値 -*/ +/*- int Mix : 省略/-1 = 複数ミックスできる場合は全てを処理 -*/ +/*- 0〜 = 指定されたミックスNoを処理 -*/ +/*- NEXT_MIX = 次に再生されるミックスNoを処理 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::SetVolume(DSOBJ ObjDS,int Value,int Mix=-1) +{ + static int i; + + // DirectSoundが使用可能な場合 + if (Ok) + { + if (Mix>=0) + { + ListVolume[ObjDS][Mix]=(long)Value*100L; + + if (ListVolume[ObjDS][Mix]>0L) ListVolume[ObjDS][Mix]=0L; + if (ListVolume[ObjDS][Mix]<-10000L) ListVolume[ObjDS][Mix]=-10000L; + + DSBuff2[ObjDS][Mix]->SetVolume(ListVolume[ObjDS][Mix]); + } + else + { + if (Mix==NEXT_MIX) + { + ListVolume[ObjDS][ListUseMix[ObjDS]]=(long)Value*100L; + + if (ListVolume[ObjDS][ListUseMix[ObjDS]]>0L) + { + ListVolume[ObjDS][ListUseMix[ObjDS]]=0L; + } + + if (ListVolume[ObjDS][ListUseMix[ObjDS]]<-10000L) + { + ListVolume[ObjDS][ListUseMix[ObjDS]]=-10000L; + } + + DSBuff2[ObjDS][ListUseMix[ObjDS]]->SetVolume( + ListVolume[ObjDS][ListUseMix[ObjDS]]); + } + else + { + for (i=0;i0L) + { + ListVolume[ObjDS][i]=0L; + } + + if (ListVolume[ObjDS][i]<-10000L) + { + ListVolume[ObjDS][i]=-10000L; + } + + DSBuff2[ObjDS][i]->SetVolume(ListVolume[ObjDS][i]); + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ディレイエフェクト -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Time : ディレイ間隔 ( ミリ秒 ) -*/ +/*- int Count : ディレイ回数 ( 0〜 ) -*/ +/*- int Volume : ディレイ音量縮小速度 ( 1〜 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::Delay(DSOBJ ObjDS,int Time,int Count,int Volume) +{ + // DirectSoundが使用可能な場合 + if (Ok) + { + // ディレイ可能な場合 + if (ListEffectCount[ObjDS]>=1 && Count>=1) + { + // ディレイ間隔の更新 + ListEffectTime[ObjDS]+=FrameTime*F(1000); + + if (ListEffectTime[ObjDS]>=F(Time)) + { + ListEffectTime[ObjDS]=F(0); + + // 次のディレイ音の再生 + elSound::SetVolume(ObjDS,-ListEffectCount[ObjDS]*Volume,NEXT_MIX); + + if (ListEffectLoop[ObjDS]) + { + elSound::Loop(ObjDS,-3); + } + else + { + elSound::Play(ObjDS,-3); + } + + // 指定されたディレイ数を終えた場合 + if (++ListEffectCount[ObjDS]>Count) + { + // ディレイの終了 + ListEffectCount[ObjDS]=0; + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- コーラスエフェクト -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- int Time : コーラス間隔 ( ミリ秒 ) -*/ +/*- int Count : コーラス回数 ( 0〜 ) -*/ +/*- int Volume : コーラス音量縮小速度 ( 1〜 ) -*/ +/*- int Speed : コーラスパン速度 ( 1〜 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::Chorus(DSOBJ ObjDS,int Time,int Count,int Volume,int Speed) +{ + // DirectSoundが使用可能な場合 + if (Ok) + { + // コーラス可能な場合 + if (ListEffectCount[ObjDS]>=1 && Count>=1) + { + // コーラス間隔の更新 + ListEffectTime[ObjDS]+=FrameTime*F(1000); + + if (ListEffectTime[ObjDS]>=F(Time)) + { + ListEffectTime[ObjDS]=F(0); + + // パンの振り分け + ListEffectPos[ObjDS]+=FrameTime*ListEffectDir[ObjDS]*F(100)*F(Speed); + + if (ListEffectPos[ObjDS]F(30)) + { + ListEffectPos[ObjDS]=F(30); + ListEffectDir[ObjDS]*=-1; + } + + // 次のコーラス音の再生 + elSound::SetPan(ObjDS,(int)ListEffectPos[ObjDS],NEXT_MIX); + elSound::SetVolume(ObjDS,-ListEffectCount[ObjDS]*Volume,NEXT_MIX); + + if (ListEffectLoop[ObjDS]) + { + elSound::Loop(ObjDS,-3); + } + else + { + elSound::Play(ObjDS,-3); + } + + // 指定されたコーラス数を終えた場合 + if (++ListEffectCount[ObjDS]>Count) + { + // コーラスの終了 + ListEffectCount[ObjDS]=0; + } + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ベル音 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::Beep(void) +{ + MessageBeep((UINT)-1); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ファイルのサウンドを再生 -*/ +/*- -*/ +/*- char* FileName : WAVEファイル名 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSound::PlayFile(char* FileName) +{ + elSound::DestroyObject(); + + sndPlaySound(FileName,SND_SYNC); + + elSound::ReloadObject(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- WAVEファイルの検索 ※ 内部で使用 -*/ +/*- -*/ +/*- パラメーター省略 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elSound::SearchFile(char* FileName,WAVEFORMATEX **ppwfxInfo,UINT* cbHead, + BYTE** ppbData,UINT* cbSize) +{ + HMMIO hmmioIn; + MMCKINFO ckInRiff; + MMCKINFO ckIn; + UINT cbActualRead; + PCMWAVEFORMAT pcmWaveFormat; + WORD cbExtraAlloc; + MMIOINFO mmioinfoIn; + UINT cT,cbDataIn; + BOOL Error=FALSE; + + *ppbData=NULL; + *ppwfxInfo=NULL; + *cbSize=0; + *cbHead=0; + *ppwfxInfo=NULL; + hmmioIn=NULL; + + while (TRUE) + { + if ((hmmioIn=mmioOpen(FileName,NULL,MMIO_ALLOCBUF|MMIO_READ))==NULL) + { + Error=TRUE; + + break; + } + + if ((int)mmioDescend(hmmioIn,&ckInRiff,NULL,0)!=0) + { + Error=TRUE; + + break; + } + + if ((ckInRiff.ckid!=FOURCC_RIFF) || + (ckInRiff.fccType!=mmioFOURCC('W','A','V','E'))) + { + Error=TRUE; + + break; + } + + ckIn.ckid=mmioFOURCC('f','m','t',' '); + + if ((int)mmioDescend(hmmioIn,&ckIn,&ckInRiff,MMIO_FINDCHUNK)!=0) + { + Error=TRUE; + + break; + } + + if (ckIn.cksize<(long)sizeof(PCMWAVEFORMAT)) + { + Error=TRUE; + + break; + } + + if (mmioRead(hmmioIn,(HPSTR)&pcmWaveFormat, + (long)sizeof(pcmWaveFormat))!=(long)sizeof(pcmWaveFormat)) + { + Error=TRUE; + + break; + } + + if (pcmWaveFormat.wf.wFormatTag==WAVE_FORMAT_PCM) + { + cbExtraAlloc=0; + } + else + { + if (mmioRead(hmmioIn,(LPSTR)&cbExtraAlloc, + (long)sizeof(cbExtraAlloc))!=(long)sizeof(cbExtraAlloc)) + { + Error=TRUE; + + break; + } + } + + *cbHead=sizeof(WAVEFORMATEX)+cbExtraAlloc; + + if ((*ppwfxInfo=(WAVEFORMATEX*)GlobalAlloc(GMEM_FIXED, + sizeof(WAVEFORMATEX)+cbExtraAlloc))==NULL) + { + Error=TRUE; + + break; + } + + memcpy(*ppwfxInfo,&pcmWaveFormat,sizeof(pcmWaveFormat)); + (*ppwfxInfo)->cbSize=cbExtraAlloc; + + if (cbExtraAlloc!=0) + { + if (mmioRead(hmmioIn,(LPSTR)(((BYTE*)&((*ppwfxInfo)->cbSize))+ + sizeof(cbExtraAlloc)),(long)(cbExtraAlloc))!= + (long)(cbExtraAlloc)) + { + Error=TRUE; + + break; + } + } + + if ((Error=mmioAscend(hmmioIn,&ckIn,0))!=0) + { + Error=TRUE; + + break; + } + + break; + } + + if (Error) + { + if (*ppwfxInfo!=NULL) + { + GlobalFree(*ppwfxInfo); + *ppwfxInfo=NULL; + } + + if (hmmioIn!=NULL) + { + mmioClose(hmmioIn,0); + hmmioIn=NULL; + } + } + + if (!Error) + { + while (TRUE) + { + mmioSeek(hmmioIn,ckInRiff.dwDataOffset+sizeof(FOURCC),SEEK_SET); + + ckIn.ckid=mmioFOURCC('d','a','t','a'); + + if ((int)mmioDescend(hmmioIn,&ckIn,&ckInRiff,MMIO_FINDCHUNK)!=0) + { + Error=TRUE; + + break; + } + + break; + } + } + + if (!Error) + { + if ((*ppbData=(BYTE*)GlobalAlloc(GMEM_FIXED,ckIn.cksize))==NULL) + { + Error=TRUE; + } + } + + if (!Error) + { + while (TRUE) + { + if (mmioGetInfo(hmmioIn,&mmioinfoIn,0)!=0) + { + Error=TRUE; + + break; + } + + cbDataIn=ckIn.cksize; + + if (cbDataIn>ckIn.cksize) cbDataIn=ckIn.cksize; + + ckIn.cksize-=cbDataIn; + + for (cT=0;cTStop(); + DSBuff2[i][j]->Release(); + DSBuff2[i][j]=NULL; + } + } + } + } + + // 転送レートの変換 + switch (Rate) + { + case 8: Rate=8000; break; + case 11: Rate=11025; break; + case 22: Rate=22050; break; + case 44: Rate=44100; break; + } + + // 再生フォーマットの変更 + memset(&wf,0x00,sizeof(WAVEFORMATEX)); + + wf.wFormatTag=WAVE_FORMAT_PCM; + wf.nChannels=(WORD)Channel; + wf.nSamplesPerSec=(DWORD)Rate; + wf.wBitsPerSample=(WORD)Bit; + wf.nBlockAlign=wf.nChannels*(wf.wBitsPerSample/8); + wf.nAvgBytesPerSec=wf.nSamplesPerSec*wf.nBlockAlign; + wf.cbSize=sizeof(WAVEFORMATEX); + + ret=DSBuff1->SetFormat(&wf); + + if (ret!=DS_OK) + { + return elDraw::Error("elSound::SelectFormat", + "再生フォーマットを変更できません",ret); + } + + // WAVEの再読み込み + Reload=TRUE; + + for (ListNo=0;ListNo0) + { + elSound::SetPack(SoundStream[ListNo].PackName); + + elSound::LoadStream(ListName[ListNo], + SoundStream[ListNo].LoopPos- + SoundStream[ListNo].StartPos); + } + else if (ListPack[ListNo]) + { + elSound::LoadPack(ListName[ListNo],ListMix[ListNo]); + } + else + { + elSound::LoadObject(ListName[ListNo],ListMix[ListNo]); + } + } + } + + Reload=FALSE; + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 再生位置の取得 -*/ +/*- -*/ +/*- DSOBJ ObjDS : サウンド情報 -*/ +/*- -*/ +/*- 戻り値 : 再生位置 ( DWORD型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +DWORD elSound::GetPos(DSOBJ ObjDS) +{ + static DWORD PlayPos; + + DSBuff2[ObjDS][0]->GetCurrentPosition(&PlayPos,NULL); + + return PlayPos; +} + +/*==============================================================================*/ +/*= =*/ +/*= ミュージッククラス定義 ( elMusic ) =*/ +/*= =*/ +/*==============================================================================*/ + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ミュージッククラスの初期化 ※ 内部で使用 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elMusic::Init(void) +{ + BOOL Auto=TRUE; + + PlayMusic=FALSE; + LoopMusic=FALSE; + LoopMode=TRUE; + + #ifdef DIRECTMUSIC + + int i; + int Next; + GUID DefPort; + HRESULT ret; + BOOL Error; + + UseDirectMusic=FALSE; + MaxPort=-1; + DirectMusicPort=-1; + + for (i=0;iInit(&DMMusic,DSObject,hwnd))) break; + + if (FAILED(CoCreateInstance(CLSID_DirectMusicLoader,NULL,CLSCTX_INPROC, + IID_IDirectMusicLoader,(void**)&DMLoader))) + { + break; + } + + if (!DMLoader) break; + + DMMusic->GetDefaultPort(&DefPort); + + MaxPort=0; + Next=0; + ret=S_OK; + + while (ret==S_OK) + { + if ((Port[MaxPort]=(DMUS_PORTCAPS*) + LocalAlloc(LPTR,sizeof(DMUS_PORTCAPS)))==NULL) + { + return elDraw::Error("elMusic::Init", + "MIDI出力ポート検索ができません"); + } + + Port[MaxPort]->dwSize=sizeof(DMUS_PORTCAPS); + ret=DMMusic->EnumPort(Next++,Port[MaxPort]); + + if (ret==S_OK) + { + if (Port[MaxPort]->dwClass==DMUS_PC_OUTPUTCLASS) + { + WideCharToMultiByte(CP_ACP,0,Port[MaxPort]->wszDescription, + -1,Buffer, + sizeof(Buffer)/sizeof(Buffer[0]),0,0); + + if (strlen(Buffer)<32) + { + strcpy(PortName[MaxPort],Buffer); + } + else + { + for (i=0;i<31;i++) + { + PortName[MaxPort][i]=Buffer[i]; + } + + PortName[MaxPort][31]=NULL; + } + + if (IsEqualGUID(Port[MaxPort]->guidPort,DefPort)) + { + DirectMusicPort=MaxPort; + } + + if (++MaxPort==PORT_MAX) break; + } + else + { + LocalFree((HLOCAL)Port[MaxPort]); + } + } + else + { + LocalFree((HLOCAL)Port[MaxPort]); + } + } + + if (FAILED(DMPerformance->SetGlobalParam(GUID_PerfAutoDownload, + &Auto,sizeof(Auto)))) + { + break; + } + + // DirectMusicの初期化完了 + InitDirectMusic=TRUE; + + Error=FALSE; + + break; + } + + if (Error) + { + return elDraw::Error("elMusic::Init", + "DirectMusicが使用できません"); + } + + elMusic::SelectPort(DIRECTMUSIC_PORT,2,22,8,FALSE); + + #endif + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 全オブジェクトの破棄 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::DestroyObject(void) +{ + #ifndef DIRECTMUSIC + + mciSendString("stop midi",NULL,0,NULL); + mciSendString("close midi",NULL,0,NULL); + + #else + + int i; + + if (!InitDirectMusic) + { + mciSendString("stop midi",NULL,0,NULL); + mciSendString("close midi",NULL,0,NULL); + } + + for (i=0;iClearCache(GUID_DirectMusicAllTypes); + DMLoader->Release(); + DMLoader=NULL; + } + + if (DMSegment) + { + DMSegment->SetParam(GUID_Unload,-1,0,0,(void*)DMPerformance); + DMSegment->Release(); + DMSegment=NULL; + } + + for (i=0;iSetParam(GUID_Unload,-1,0,0, + (void*)Music[i].Performance); + Music[i].Segment->Release(); + Music[i].Segment=NULL; + + Music[i].Performance->Stop(NULL,NULL,0,0); + Music[i].Performance->CloseDown(); + Music[i].Performance->Release(); + Music[i].Performance=NULL; + } + } + + if (DMPerformance) + { + DMPerformance->Stop(NULL,NULL,0,0); + DMPerformance->CloseDown(); + DMPerformance->Release(); + DMPerformance=NULL; + } + + if (DMPort) + { + DMPort->Release(); + DMPort=NULL; + } + + if (DMMusic) + { + DMMusic->Release(); + DMMusic=NULL; + } + + CoUninitialize(); + + #endif +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 音楽の再生 -*/ +/*- -*/ +/*- char* FileName : MIDIファイル名 -*/ +/*- BOOL Loop : ループフラグ -*/ +/*- 省略/TRUE = ループあり -*/ +/*- FALSE = ループなし -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::Play(char* FileName,BOOL Loop=TRUE) +{ + char Buffer[256]; + + #ifndef DIRECTMUSIC + + sprintf(Buffer,"open \"%s%s\" type sequencer alias midi", + elSystem::Directory(),FileName); + + if (PlayMusic) elMusic::Stop(); + + mciSendString(Buffer,NULL,0,NULL); + mciSendString("seek midi to start",NULL,0,NULL); + mciSendString("play midi notify",NULL,0,hwnd); + + #else + + char Current[256]; +// WCHAR BufferW[256]; + DMUS_OBJECTDESC od; + + if (!InitDirectMusic) + { + sprintf(Buffer,"open \"%s%s\" type sequencer alias midi", + elSystem::Directory(),FileName); + + if (PlayMusic) elMusic::Stop(); + + mciSendString(Buffer,NULL,0,NULL); + mciSendString("seek midi to start",NULL,0,NULL); + mciSendString("play midi notify",NULL,0,hwnd); + } + else + { + DMPerformance->Stop(NULL,NULL,0,0); + + if (DMSegment) + { + DMSegment->Release(); + DMSegment=NULL; + } + + GetCurrentDirectory(254,Current); + SetCurrentDirectory(elSystem::Directory()); + +/* + strcpy(Buffer,elSystem::Directory()); + Buffer[strlen(Buffer)-1]=NULL; + + mbstowcs(BufferW,Buffer,256); + + DMLoader->SetSearchDirectory(GUID_DirectMusicAllTypes,BufferW,FALSE); +*/ + + od.guidClass=CLSID_DirectMusicSegment; + od.dwSize=sizeof(DMUS_OBJECTDESC); + od.dwValidData=DMUS_OBJ_CLASS|DMUS_OBJ_FILENAME; + + mbstowcs(od.wszFileName,FileName,256); + + DMLoader->GetObject(&od,IID_IDirectMusicSegment,(void**)&DMSegment); + + SetCurrentDirectory(Current); + + if (DMSegment) + { + DMSegment->SetParam(GUID_StandardMIDIFile,-1,0,0, + (void*)DMPerformance); + + if (Loop) + { + DMSegment->SetRepeats(-1); + } + else + { + DMSegment->SetRepeats(0); + } + + DMPerformance->PlaySegment(DMSegment,0,0,&DMState); + + _MusicLoopTime=timeGetTime()+3000UL; + } + } + + #endif + + PlayMusic=TRUE; + LoopMusic=FALSE; + LoopMode=Loop; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 音楽のループ再生 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::Replay(void) +{ + #ifndef DIRECTMUSIC + + if (LoopMode) + { + mciSendString("seek midi to start",NULL,0,NULL); + mciSendString("play midi notify",NULL,0,hwnd); + } + else + { + elMusic::Stop(); + } + + LoopMusic=TRUE; + + #else + + if (!InitDirectMusic) + { + if (LoopMode) + { + mciSendString("seek midi to start",NULL,0,NULL); + mciSendString("play midi notify",NULL,0,hwnd); + } + else + { + elMusic::Stop(); + } + } + + #endif +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 音楽の停止 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::Stop(void) +{ + if (PlayMusic) + { + #ifndef DIRECTMUSIC + + mciSendString("stop midi",NULL,0,NULL); + mciSendString("close midi",NULL,0,NULL); + + #else + + if (!InitDirectMusic) + { + mciSendString("stop midi",NULL,0,NULL); + mciSendString("close midi",NULL,0,NULL); + } + else + { + DMPerformance->Stop(NULL,NULL,0,0); + + if (DMSegment) + { + DMSegment->Release(); + DMSegment=NULL; + } + } + + #endif + + PlayMusic=FALSE; + } + + #ifdef DIRECTMUSIC + + int i; + + if (InitDirectMusic) + { + for (i=0;iStop(Music[i].Segment,NULL,0,0); + } + } + } + + #endif +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ループ再生の無効化 ( elMusic::Play関数の後に使用 ) -*/ +/*- -*/ +/*- ※ DirectMusicを使用する場合、この関数は機能しません -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::NoLoop(void) +{ + #ifndef DIRECTMUSIC + + LoopMode=FALSE; + + #endif +} + +#ifdef DIRECTMUSIC + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ピッチの変調 ( 相対値 ) -*/ +/*- -*/ +/*- int Value : 加減値 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::Pitch(int Value) +{ + if (UseDirectMusic) elSound::Pitch(DIRECT_MUSIC,Value,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ピッチの初期化 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::InitPitch(void) +{ + if (UseDirectMusic) elSound::InitPitch(DIRECT_MUSIC,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ピッチの変調 ( 絶対値 ) -*/ +/*- -*/ +/*- int Value : 加減値 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::SetPitch(int Value) +{ + if (UseDirectMusic) elSound::SetPitch(DIRECT_MUSIC,Value,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- パンの振り分け ( 相対値 ) -*/ +/*- -*/ +/*- int Value : 振り分け値 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::Pan(int Value) +{ + if (UseDirectMusic) elSound::Pan(DIRECT_MUSIC,Value,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- パンの初期化 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::InitPan(void) +{ + if (UseDirectMusic) elSound::InitPan(DIRECT_MUSIC,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- パンの振り分け ( 絶対値 ) -*/ +/*- -*/ +/*- int Value : 振り分け値 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::SetPan(int Value) +{ + if (UseDirectMusic) elSound::SetPan(DIRECT_MUSIC,Value,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- パンを左に振り分け -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::LeftPan(void) +{ + if (UseDirectMusic) elSound::LeftPan(DIRECT_MUSIC,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- パンを右に振り分け -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::RightPan(void) +{ + if (UseDirectMusic) elSound::RightPan(DIRECT_MUSIC,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ボリュームの調整 ( 相対値 ) -*/ +/*- -*/ +/*- int Value : 加減値 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::Volume(int Value) +{ + if (UseDirectMusic) elSound::Volume(DIRECT_MUSIC,Value,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ボリュームの初期化 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::InitVolume(void) +{ + if (UseDirectMusic) elSound::InitVolume(DIRECT_MUSIC,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ボリュームの調整 ( 絶対値 ) -*/ +/*- -*/ +/*- int Value : 加減値 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::SetVolume(int Value) +{ + if (UseDirectMusic) elSound::SetVolume(DIRECT_MUSIC,Value,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 出力MIDIポートの指定 -*/ +/*- -*/ +/*- int PortNo : 出力ポートNo -*/ +/*- 省略/DIRECTMUSIC_PORT = DirectMusic -*/ +/*- 0〜 = 任意のポート -*/ +/*- int Channel : チャンネル数 -*/ +/*- 省略/2 = ステレオ -*/ +/*- 1 = モノラル -*/ +/*- int Rate : 転送レート -*/ +/*- 省略/22 = 22.05KHz -*/ +/*- 8 = 8KHz -*/ +/*- 11 = 11.025KHz -*/ +/*- 44 = 44.1KHz -*/ +/*- int Bit : 転送ビット -*/ +/*- 省略/8 = 8ビット -*/ +/*- 16 = 16ビット -*/ +/*- BOOL Reverb : リバーブ -*/ +/*- TRUE = ON -*/ +/*- FALSE = OFF -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elMusic::SelectPort(int PortNo=DIRECTMUSIC_PORT,int Channel=2, + int Rate=22,int Bit=8,BOOL Reverb=FALSE) +{ + static BOOL error; + static DMUS_PORTPARAMS dmp; + static DSBUFFERDESC dsbd; + static WAVEFORMATEX wf; + static DWORD wfs; + + if (!InitDirectMusic) return FALSE; + + if (DMPort) + { + DMPerformance->RemovePort(DMPort); + DMPort->Release(); + DMPort=NULL; + } + + // DirectMusicが指定された場合 + if (PortNo==DIRECTMUSIC_PORT) PortNo=DirectMusicPort; + + memset(&dmp,0x00,sizeof(DMUS_PORTPARAMS)); + dmp.dwSize=sizeof(DMUS_PORTPARAMS); + dmp.dwChannelGroups=Port[PortNo]->dwMaxChannelGroups; + dmp.dwValidParams=DMUS_PORTPARAMS_CHANNELGROUPS|DMUS_PORTPARAMS_EFFECTS; + + if (Reverb) + { + dmp.dwEffectFlags=DMUS_EFFECT_REVERB; + } + else + { + dmp.dwEffectFlags=DMUS_EFFECT_NONE; + } + + while (TRUE) + { + error=TRUE; + + // ポートの生成 + if (FAILED(DMMusic->CreatePort(Port[PortNo]->guidPort, + &dmp,&DMPort,NULL))) break; + + // MIDI出力ポートにDirectMusicを要求された場合 + if (PortNo==DirectMusicPort) + { + // すでにDirectSoundバッファを確保中の場合 + if (DSBuff2[DIRECT_MUSIC][0]!=NULL) + { + DSBuff2[DIRECT_MUSIC][0]->Release(); + DSBuff2[DIRECT_MUSIC][0]=NULL; + } + + // DirectSoundに再生用バッファを生成 + memset(&wf,0x00,sizeof(WAVEFORMATEX)); + memset(&dsbd,0x00,sizeof(DSBUFFERDESC)); + + dsbd.dwSize=sizeof(DSBUFFERDESC); + dsbd.dwFlags=DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME; + dsbd.lpwfxFormat=&wf; + + switch (Rate) + { + case 8: Rate=8000; break; + case 11: Rate=11025; break; + case 22: Rate=22050; break; + case 44: Rate=44100; break; + } + + wfs=sizeof(WAVEFORMATEX); + + if (DMPort->GetFormat(&wf,&wfs,&dsbd.dwBufferBytes)) + { + wf.wFormatTag=WAVE_FORMAT_PCM; + wf.nChannels=(WORD)Channel; + wf.nSamplesPerSec=(DWORD)Rate; + wf.wBitsPerSample=(WORD)Bit; + wf.nBlockAlign=wf.nChannels*(wf.wBitsPerSample/8); + wf.nAvgBytesPerSec=wf.nSamplesPerSec*wf.nBlockAlign; + wf.cbSize=sizeof(WAVEFORMATEX); + + dsbd.dwBufferBytes=wf.nAvgBytesPerSec; + } + + if (FAILED(DSObject->CreateSoundBuffer(&dsbd, + &DSBuff2[DIRECT_MUSIC][0],NULL))) break; + + // DirectMusic用に先頭のDirectSoundバッファを確保 + elSound::ListUse[DIRECT_MUSIC]=TRUE; + elSound::ListMix[DIRECT_MUSIC]=1; + elSound::ListEffectCount[DIRECT_MUSIC]=-1; + elSound::ListUseMix[DIRECT_MUSIC]=0; + + DSBuff2[DIRECT_MUSIC][0]->GetFrequency( + &elSound::ListPitch[DIRECT_MUSIC][0]); + elSound::ListPitchDef[DIRECT_MUSIC]=elSound::ListPitch + [DIRECT_MUSIC][0]; + elSound::ListVolume[DIRECT_MUSIC][0]=0L; + elSound::ListPan[DIRECT_MUSIC][0]=0L; + + strcpy(elSound::ListName[DIRECT_MUSIC],"DirectMusic"); + + // DirectSoundに接続 + if (FAILED(DMPort->SetDirectSound(DSObject, + DSBuff2[DIRECT_MUSIC][0]))) break; + + // チャンネルグループ数の取得 + ChannelGroup=Port[PortNo]->dwMaxChannelGroups; + + // DirectMusicの使用 + UseDirectMusic=TRUE; + } + else + { + // 仮にDirectSoundバッファを1つだけ確保 + elSound::ListUse[DIRECT_MUSIC]=TRUE; + + // チャンネルグループ数の初期化 + ChannelGroup=1; + + // DirectMusicは未使用 + UseDirectMusic=FALSE; + } + + // ポートに接続して使用可能に設定 + if (FAILED(DMPort->Activate(TRUE))) break; + + if (FAILED(DMPerformance->AddPort(DMPort))) break; + + if (FAILED(DMPerformance->AssignPChannelBlock(0,DMPort,1))) break; + + error=FALSE; + + break; + } + + if (error) + { + return elDraw::Error("elMusic::Port", + "MIDIポートが使えません"); + } + + // パラメーターの退避 + elMusic::PortNo=PortNo; + elMusic::Channel=Channel; + elMusic::Rate=Rate; + elMusic::Bit=Bit; + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- リバーブの設定 -*/ +/*- -*/ +/*- BOOL Mode : TRUE = リバーブON -*/ +/*- FALSE = リバーブOFF -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::Reverb(BOOL Mode) +{ + elMusic::SelectPort(elMusic::PortNo,elMusic::Channel,elMusic::Rate, + elMusic::Bit,Mode); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 音楽の読み込み -*/ +/*- -*/ +/*- char* FileName : MIDIファイル名 -*/ +/*- -*/ +/*- 戻り値 : ミュージック情報 ( DMOBJ型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +DMOBJ elMusic::LoadObject(char* FileName) +{ + int i; + char Buffer[256]; + char Current[256]; +// WCHAR BufferW[256]; + DMUS_OBJECTDESC od; + DMOBJ ObjDM=-1; + BOOL Auto=TRUE; + BOOL Error=TRUE; + HRESULT Ret; + + if (!InitDirectMusic) + { + return (DMOBJ)elDraw::Error("elMusic::LoadObject", + "DirectMusicが無効になっています"); + } + else + { + for (i=0;i=ChannelGroup) + { + return (DMOBJ)elDraw::Error("elMusic::LoadObject", + "チャンネルグループ数を超えています", + ChannelGroup); + } + + while (TRUE) + { + GetCurrentDirectory(254,Current); + SetCurrentDirectory(elSystem::Directory()); + +/* + strcpy(Buffer,elSystem::Directory()); + Buffer[strlen(Buffer)-1]=NULL; + + mbstowcs(BufferW,Buffer,256); + + Ret=DMLoader->SetSearchDirectory(GUID_DirectMusicAllTypes,BufferW, + FALSE); + + if (Ret!=S_OK && Ret!=S_FALSE) + { + strcpy(Buffer,"パスが無効です"); + + break; + } +*/ + + od.guidClass=CLSID_DirectMusicSegment; + od.dwSize=sizeof(DMUS_OBJECTDESC); + od.dwValidData=DMUS_OBJ_CLASS|DMUS_OBJ_FILENAME; + + mbstowcs(od.wszFileName,FileName,256); + + Ret=DMLoader->GetObject(&od,IID_IDirectMusicSegment, + (void**)&Music[ObjDM].Segment); + + if (Ret!=S_OK || !Music[ObjDM].Segment) + { + strcpy(Buffer,"MIDIファイルを読み込みできません"); + + break; + } + + SetCurrentDirectory(Current); + + #define PERFORMANCE Music[ObjDM].Performance + + if (FAILED(CoCreateInstance(CLSID_DirectMusicPerformance, + NULL,CLSCTX_INPROC, + IID_IDirectMusicPerformance, + (void**)&PERFORMANCE))) + { + strcpy(Buffer,"Performanceが無効です"); + + break; + } + + if (!PERFORMANCE) + { + strcpy(Buffer,"Performanceが無効です"); + + break; + } + + Ret=PERFORMANCE->Init(&DMMusic,DSObject,hwnd); + + if (Ret!=S_OK) + { + strcpy(Buffer,"Performanceを初期化できません"); + + break; + } + + Ret=PERFORMANCE->AddPort(DMPort); + + if (Ret!=S_OK) + { + strcpy(Buffer,"ポートを割り当てできません"); + + break; + } + + Ret=PERFORMANCE->AssignPChannelBlock(0,DMPort,1+ObjDM); + + if (Ret!=S_OK) + { + strcpy(Buffer,"チャンネルを割り当てできません"); + + break; + } + + Music[ObjDM].Segment->SetParam(GUID_StandardMIDIFile,-1,0,0, + (void*)PERFORMANCE); + + Music[ObjDM].Segment->SetParam(GUID_Download,-1,0,0, + (void*)PERFORMANCE); + + Error=FALSE; + + break; + + #undef PERFORMANCE + } + + if (Error) + { + return (DMOBJ)elDraw::Error("elMusic::LoadObject",Buffer,Ret); + } + } + + return ObjDM; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 音楽を削除してメモリから開放 -*/ +/*- -*/ +/*- DMOBJ ObjDM : ミュージック情報 -*/ +/*- 省略 = 全て -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::FreeObject(DMOBJ ObjDM=-1) +{ + int i; + + if (ObjDM==-1) + { + for (i=0;iSetParam(GUID_Unload,-1,0,0, + (void*)Music[i].Performance); + Music[i].Segment->Release(); + Music[i].Segment=NULL; + + Music[i].Performance->Stop(NULL,NULL,0,0); + Music[i].Performance->CloseDown(); + Music[i].Performance->Release(); + Music[i].Performance=NULL; + } + } + } + else + { + if (Music[ObjDM].Performance) + { + Music[ObjDM].Segment->SetParam(GUID_Unload,-1,0,0, + (void*)Music[ObjDM].Performance); + Music[ObjDM].Segment->Release(); + Music[ObjDM].Segment=NULL; + + Music[ObjDM].Performance->Stop(NULL,NULL,0,0); + Music[ObjDM].Performance->CloseDown(); + Music[ObjDM].Performance->Release(); + Music[ObjDM].Performance=NULL; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 音楽の再生 -*/ +/*- -*/ +/*- DMOBJ ObjDM : ミュージック情報 -*/ +/*- BOOL Loop : ループフラグ -*/ +/*- 省略/TRUE = ループあり -*/ +/*- FALSE = ループなし -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::Play(DMOBJ ObjDM,BOOL Loop=TRUE) +{ + if (InitDirectMusic && Music[ObjDM].Performance) + { + Music[ObjDM].Performance->Stop(Music[ObjDM].Segment,NULL,0,0); + + if (Loop) + { + Music[ObjDM].Segment->SetRepeats(-1); + } + else + { + Music[ObjDM].Segment->SetRepeats(0); + } + + Music[ObjDM].Performance->PlaySegment(Music[ObjDM].Segment,0,0,NULL); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 音楽の停止 -*/ +/*- -*/ +/*- DMOBJ ObjDM : ミュージック情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMusic::Stop(DMOBJ ObjDM) +{ + if (InitDirectMusic && Music[ObjDM].Performance) + { + Music[ObjDM].Performance->Stop(Music[ObjDM].Segment,NULL,0,0); + } +} + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= CDクラス定義 ( elCD ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef CDDA + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- CDクラスの初期化 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elCD::Init(void) +{ + int i; + + for (i=0;iCDInfo[0].Time.m || + PauseM==CDInfo[0].Time.m && PauseS>CDInfo[0].Time.s || + PauseM==CDInfo[0].Time.m && PauseS==CDInfo[0].Time.s && + PauseF>CDInfo[0].Time.m) + { + elCD::Play(StartSongNo,EndSongNo); + } + else + { + // 時間指定で再生 + if (EndSongNo==SongMax) + { + elCD::Play(PauseM,PauseS,PauseF, + CDInfo[0].Time.m,CDInfo[0].Time.s, + CDInfo[0].Time.f); + } + else + { + elCD::Play(PauseM,PauseS,PauseF, + CDInfo[EndSongNo+1].Start.m, + CDInfo[EndSongNo+1].Start.s, + CDInfo[EndSongNo+1].Start.f); + } + } + + PauseM=-1; + PauseS=-1; + PauseF=-1; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 曲のスキップ -*/ +/*- -*/ +/*- int Count : スキップ数 -*/ +/*- 1 = 次の曲 -*/ +/*- -1 = 前の曲 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elCD::Skip(int Count) +{ + int Now; + + Now=elCD::NowSong()+Count; + + if (Now=60) + { + PauseS-=60; + + if (++PauseM>CDInfo[0].Time.m || + PauseM==CDInfo[0].Time.m && PauseS>CDInfo[0].Time.s || + PauseM==CDInfo[0].Time.m && PauseS==CDInfo[0].Time.s && + PauseF>CDInfo[0].Time.f) + { + PauseM=CDInfo[0].Time.m; + PauseS=CDInfo[0].Time.s; + PauseF=CDInfo[0].Time.f; + } + } + + elCD::Pause(FALSE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 曲の巻戻し -*/ +/*- -*/ +/*- int Time : 巻戻し時間 ( 秒 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elCD::Backward(int Time) +{ + elCD::Pause(TRUE); + + PauseS-=Time; + + if (PauseS<0) + { + PauseS+=60; + + if (--PauseM<0) + { + PauseM=0; + PauseS=0; + PauseF=0; + } + } + + elCD::Pause(FALSE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- CD挿入状態の取得 -*/ +/*- -*/ +/*- 戻り値 : TRUE = CDあり -*/ +/*- FALSE = CDなし -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elCD::Ready(void) +{ + mciSendString("status cdaudio media present",MciBuffer,32,NULL); + + if (MciBuffer[0]=='t') + { + mciSendString("status cdaudio ready",MciBuffer,32,NULL); + + if (MciBuffer[0]=='t') + { + return TRUE; + } + else + { + return FALSE; + } + } + else + { + return FALSE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- CDドライブのオープン -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elCD::Open(void) +{ + mciSendString("set cdaudio door open",NULL,0,NULL); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- CDドライブのクローズ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elCD::Close(void) +{ + mciSendString("set cdaudio door closed",NULL,0,NULL); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ループ再生の無効化 ( elCD::Play関数の後に使用 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elCD::NoLoop(void) +{ + LoopMode=FALSE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- CDの曲数の取得 -*/ +/*- -*/ +/*- 戻り値 : 曲数 ( int型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elCD::MaxSong(void) +{ + return SongMax; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 再生中の曲番号の取得 -*/ +/*- -*/ +/*- 戻り値 : 曲番号 ( int型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elCD::NowSong(void) +{ + mciSendString("status cdaudio current track",MciBuffer,32,NULL); + + if (PlayCD) + { + return atoi(MciBuffer); + } + else + { + return 0; + } +} + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= 3Dクラス定義 ( el3D ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef DIRECT3D + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 3D環境の取得 ※ 内部で使用 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL el3D::GetConfig(void) +{ + DDObject->QueryInterface(IID_IDirect3D,(void**)&D3); + + if (!HEL) + { + DriverType=D3DCOLOR_RGB; + UseDriver=NULL; + + D3->EnumDevices(SearchDriver,NULL); + } + + if (!Search3DVideoCard) + { + DriverType=D3DCOLOR_MONO; + UseDriver=NULL; + + D3->EnumDevices(SearchDriver,NULL); + } + + if (UseDriver==NULL) + { + return elDraw::Error("el3D::Config", + "Direct3D RMが使用できません"); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 3Dクラスの初期化 ※ 内部で使用 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL el3D::Init(void) +{ + int i; + + #ifdef REPORT + + REP_IN + "Direct3D = " + REP_OUT + + #endif + + if (el3D::Mode&DRAW_BACKLAYER) + { + DDBack->QueryInterface(*UseDriver,(LPVOID*)&D3Device); + } + + Direct3DRMCreate(&D3RM); + + if (el3D::Mode&DRAW_BACKLAYER) + { + D3RM->CreateDeviceFromD3D(D3,D3Device,&D3RMDevice); + } + else + { + if ((HRESULT)D3RM->CreateDeviceFromSurface(UseDriver,DDObject,DD3D, + &D3RMDevice)<0) + { + Search3DVideoCard=FALSE; + + if ((HRESULT)D3RM->CreateDeviceFromSurface(NULL,DDObject,DD3D, + &D3RMDevice)<0) + { + return elDraw::Error("el3D::Init", + "Direct3D RMが使用できません"); + } + } + } + + #ifdef REPORT + + if (Search3DVideoCard) + { + REP_IN + "HAL\n" + REP_OUT + } + else + { + REP_IN + "HEL\n" + REP_OUT + } + + memset(&RepHal,0x00,sizeof(DDCAPS)); + RepHal.dwSize=sizeof(DDCAPS); + memset(&RepHel,0x00,sizeof(DDCAPS)); + RepHel.dwSize=sizeof(DDCAPS); + DDObject->GetCaps(&RepHal,&RepHel); + + REP_IN + "Direct3D初期化後のVRAM空き = %2.3f MB\n\n", + F(RepHal.dwVidMemFree)/F(1024)/F(1024) + REP_OUT + + #endif + + D3RM->SetDefaultTextureColors(256); + D3RM->SetDefaultTextureShades(16); + D3RMDevice->SetBufferCount(2); + D3RMDevice->SetShades(16); + D3RMDevice->SetQuality(D3DRMRENDER_GOURAUD); + D3RMDevice->SetDither(FALSE); + + if (el3D::Mode&TEXTURE_QUALITY) + { + D3RMDevice->SetTextureQuality(D3DRMTEXTURE_LINEAR); + } + else + { + D3RMDevice->SetTextureQuality(D3DRMTEXTURE_NEAREST); + } + + ModelNo=0; + CameraNo=0; + + StopAllModel(); + + for (i=0;idcmColorModel?lpHWDesc:lpHELDesc; + + if (lpDesc->dcmColorModel!=DriverType) return D3DENUMRET_OK; + + if (!(lpDesc->dwDeviceRenderBitDepth&DDBD_16) && + !(lpDesc->dwDeviceRenderBitDepth&DDBD_24) && + !(lpDesc->dwDeviceRenderBitDepth&DDBD_32)) + { + return D3DENUMRET_OK; + } + + if (lpDesc->dwDeviceZBufferBitDepth&DDBD_16) + { + ZBufferSize=16; + } + else + { + if (lpDesc->dwDeviceZBufferBitDepth&DDBD_24) + { + ZBufferSize=24; + } + else + { + if (lpDesc->dwDeviceZBufferBitDepth&DDBD_32) + { + ZBufferSize=32; + } + else + { + return D3DENUMRET_OK; + } + } + } + + if (lpDesc==lpHWDesc) + { + UseDriver=lpGuid; + + memset(&Hal,0x00,sizeof(DDCAPS)); + Hal.dwSize=sizeof(DDCAPS); + memset(&Hel,0x00,sizeof(DDCAPS)); + Hel.dwSize=sizeof(DDCAPS); + DDObject->GetCaps(&Hal,&Hel); + + if (Hal.dwVidMemFree> + (UINT)(ZBufferSize/8*elDraw::Width*elDraw::Height)) + { + ZBufferMemory=DDSCAPS_VIDEOMEMORY; + } + else + { + ZBufferMemory=DDSCAPS_SYSTEMMEMORY; + } + + Search3DVideoCard=TRUE; + } + else + { + UseDriver=lpGuid; + + ZBufferMemory=DDSCAPS_SYSTEMMEMORY; + ZBufferSize=16; + + Search3DVideoCard=FALSE; + } + + return D3DENUMRET_OK; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルの読み込み -*/ +/*- -*/ +/*- char* FileName : Xファイル名 -*/ +/*- int Count : 省略/0 = 1つだけ読み込み -*/ +/*- 1〜 = 同じモデルを複数読み込み -*/ +/*- D3OBJ* ObjD3s : 省略/NULL = 1つだけ読み込み(戻り値を使用) -*/ +/*- 任意のD3OBJ型変数 = 同じモデルを複数読み込み -*/ +/*- -*/ +/*- 戻り値 : 1つだけ読み込む場合 = モデル情報 ( D3OBJ型 ) -*/ +/*- 複数読み込む場合 = NULL -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D3OBJ el3D::LoadObject(char* FileName,int Count=0,D3OBJ* ObjD3s=NULL) +{ + int i; + D3OBJ ObjD3; + D3DRMBOX Box; + D3DVALUE MinX,MaxX,MinY,MaxY; + D3DVALUE Width,Height; + char Buffer[256]; + + strcpy(Buffer,elSystem::Directory()); + strcat(Buffer,FileName); + + if (!Count) + { + if (DefaultLink) + { + D3RM->CreateFrame(DefaultLink,&ObjD3); + } + else + { + D3RM->CreateFrame(D3RMScene,&ObjD3); + } + } + else + { + for (i=0;iCreateFrame(DefaultLink,&ObjD3s[i]); + } + else + { + D3RM->CreateFrame(D3RMScene,&ObjD3s[i]); + } + } + } + + D3RM->CreateMeshBuilder(&D3RMBuilder); + + if (D3RMBuilder->Load(Buffer,NULL,D3DRMLOAD_FROMFILE,NULL,NULL)!=D3DRM_OK) + { + return (D3OBJ)elDraw::Error("el3D::LoadObject", + "Xファイルを読み込めません"); + } + + D3RM->CreateMaterial(F(5),&D3RMMaterial); + + D3RMBuilder->SetMaterial(D3RMMaterial); + + if (DefaultWireShade) + { + D3RMBuilder->SetQuality(D3DRMRENDER_WIREFRAME); + } + else + { + if (DefaultFlatShade) + { + D3RMBuilder->SetQuality(D3DRMRENDER_FLAT); + } + else + { + if (DefaultNoLightShade) + { + D3RMBuilder->SetQuality(D3DRMRENDER_UNLITFLAT); + } + else + { + D3RMBuilder->SetQuality(D3DRMRENDER_GOURAUD); + } + } + } + + if (DefaultScale!=F(-999)) + { + D3RMBuilder->Scale(DefaultScale,DefaultScale,DefaultScale); + } + + D3RMBuilder->SetPerspective(TRUE); + + if (!DefaultChange) + { + if (DefaultColor) + { + D3RMBuilder->SetColorRGB(DefaultColorRed, + DefaultColorGreen, + DefaultColorBlue); + } + + if (DefaultTexture) + { + D3RMBuilder->SetTexture(DefaultTexture); + } + } + + if (DefaultTexture) + { + if (DefaultTextureQuality) + { + D3RMBuilder->SetPerspective(TRUE); + } + else + { + D3RMBuilder->SetPerspective(FALSE); + } + } + + D3RMBuilder->CreateMesh(&D3RMMesh); + + if (DefaultShadow) + { + D3RM->CreateShadow((LPDIRECT3DRMVISUAL)D3RMMesh, + D3RMLightType[DefaultShadow], + F(0),F(0),F(0),F(0),F(1),F(0), + &D3RMShadow); + } + + if (DefaultTexture) + { + D3RMMesh->GetBox(&Box); + + MaxX=Box.max.x; + MinX=Box.min.x; + MaxY=Box.max.y; + MinY=Box.min.y; + + Width=MaxX-MinX; + Height=MaxY-MinY; + + if (DefaultTextureBall) + { + D3RM->CreateWrap(D3DRMWRAP_CYLINDER,NULL, + F(0),F(0),F(0),F(0),F(1),F(0),F(0),F(0),F(1), + F(0),MinY/Height,F(1),F(1)/Height, + &D3RMWrap); + } + else + { + D3RM->CreateWrap(D3DRMWRAP_FLAT,NULL, + F(0),F(0),F(0),F(0),F(0),F(1),F(0),F(1),F(0), + MinX/Width*F(DefaultTextureCountX), + MinY/Height*F(DefaultTextureCountY), + F(1)/Width*F(DefaultTextureCountX), + F(1)/Height*F(DefaultTextureCountY), + &D3RMWrap); + } + + D3RMWrap->Apply((LPDIRECT3DRMOBJECT)D3RMMesh); + } + + if (!Count) + { + ObjD3->AddVisual((LPDIRECT3DRMVISUAL)D3RMMesh); + if (DefaultShadow) ObjD3->AddVisual(D3RMShadow); + ObjD3->SetZbufferMode(D3DRMZBUFFER_ENABLE); + } + else + { + for (i=0;iAddVisual((LPDIRECT3DRMVISUAL)D3RMMesh); + if (DefaultShadow) ObjD3s[i]->AddVisual(D3RMShadow); + ObjD3s[i]->SetZbufferMode(D3DRMZBUFFER_ENABLE); + } + } + + if (DefaultTexture) D3RMWrap->Release(); + if (DefaultShadow) D3RMShadow->Release(); + D3RMMesh->Release(); + D3RMMaterial->Release(); + D3RMBuilder->Release(); + + if (DefaultChange) + { + if (!Count) + { + ObjD3->SetMaterialMode(D3DRMMATERIAL_FROMFRAME); + + if (DefaultColor) + { + el3D::ChangeColor(ObjD3, + DefaultColorRed, + DefaultColorGreen, + DefaultColorBlue); + } + + if (DefaultTexture) + { + el3D::ChangeTexture(ObjD3,DefaultTexture); + } + } + else + { + for (i=0;iSetMaterialMode(D3DRMMATERIAL_FROMFRAME); + + if (DefaultColor) + { + el3D::ChangeColor(ObjD3s[i], + DefaultColorRed, + DefaultColorGreen, + DefaultColorBlue); + } + + if (DefaultTexture) + { + el3D::ChangeTexture(ObjD3s[i],DefaultTexture); + } + } + } + } + + DefaultWireShade=FALSE; + DefaultFlatShade=FALSE; + DefaultNoLightShade=FALSE; + DefaultColor=FALSE; + DefaultScale=F(-999); + DefaultTexture=NULL; + DefaultShadow=0; + DefaultLink=NULL; + DefaultChange=FALSE; + + if (!Count) + { + return ObjD3; + } + else + { + return (D3OBJ)NULL; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 空モデルの生成 -*/ +/*- -*/ +/*- 戻り値 : モデル情報 ( D3OBJ型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D3OBJ el3D::CreateObject(void) +{ + D3OBJ ObjD3; + + D3RM->CreateFrame(D3RMScene,&ObjD3); + D3RM->CreateMeshBuilder(&D3RMBuilder); + D3RM->CreateMaterial(F(5),&D3RMMaterial); + + D3RMBuilder->SetMaterial(D3RMMaterial); + + ObjD3->SetZbufferMode(D3DRMZBUFFER_ENABLE); + + D3RMMaterial->Release(); + D3RMBuilder->Release(); + + return ObjD3; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルを削除してメモリから解放 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::FreeObject(D3OBJ* ObjD3) +{ + if (*ObjD3!=NULL) + { + D3RMScene->DeleteChild(*ObjD3); + + (*ObjD3)->Release(); + *ObjD3=NULL; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 全オブジェクトの破棄 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DestroyObject(void) +{ + if (D3Device!=NULL) + { + D3Device->Release(); + D3Device=NULL; + } + + if (D3RMDevice!=NULL) + { + D3RMDevice->Release(); + D3RMDevice=NULL; + } + + if (D3RM!=NULL) + { + D3RM->Release(); + D3RM=NULL; + } + + if (D3!=NULL) + { + D3->Release(); + D3=NULL; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャーの読み込み -*/ +/*- -*/ +/*- char* FileName : BMPファイル名 -*/ +/*- -*/ +/*- 戻り値 : テクスチャー情報 ( D3TXR型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D3TXR el3D::LoadTexture(char* FileName) +{ + D3TXR TxrD3; + char Buffer[256]; + + strcpy(Buffer,elSystem::Directory()); + strcat(Buffer,FileName); + + if (D3RM->LoadTexture(Buffer,&TxrD3)!=D3DRM_OK) + { + return (D3TXR)elDraw::Error("el3D::LoadTexture", + "テクスチャーを読み込めません"); + } + + return TxrD3; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャーを削除してメモリから解放 -*/ +/*- -*/ +/*- D3TXR* TxrD3 : テクスチャー情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::FreeTexture(D3TXR* TxrD3) +{ + if (*TxrD3!=NULL) + { + (*TxrD3)->Release(); + *TxrD3=NULL; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャーの交換 -*/ +/*- -*/ +/*- char* FileName : BMPファイル名 -*/ +/*- D3TXR* TxrD3 : テクスチャー情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SwapTexture(char* FileName,D3TXR* TxrD3) +{ + char Buffer[256]; + + if (*TxrD3!=NULL) + { + (*TxrD3)->Release(); + *TxrD3=NULL; + } + + strcpy(Buffer,elSystem::Directory()); + strcat(Buffer,FileName); + + D3RM->LoadTexture(Buffer,TxrD3); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ワイヤーフレームの指定 ( el3D::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SetWireShade(void) +{ + DefaultWireShade=TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラットシェーディングの指定 ( el3D::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SetFlatShade(void) +{ + DefaultFlatShade=TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 光源なしフラットシェーディングの指定 ( el3D::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SetNoLightShade(void) +{ + DefaultNoLightShade=TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 色の指定 ( el3D::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*- float Red : 赤の強さ -*/ +/*- float Green : 緑の強さ -*/ +/*- float Blue : 青の強さ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SetColor(float Red,float Green,float Blue) +{ + DefaultColor=TRUE; + + DefaultColorRed=Red; + DefaultColorGreen=Green; + DefaultColorBlue=Blue; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 大きさの指定 ( el3D::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*- float Size : 大きさ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SetScale(float Size) +{ + DefaultScale=Size; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャーの指定 ( el3D::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*- D3TXR TxrD3 : テクスチャー情報 -*/ +/*- BOOL Quality : TRUE = 遠近感あり -*/ +/*- FALSE = 遠近感なし -*/ +/*- BOOL BallType : TRUE = 球面テクスチャー -*/ +/*- FALSE = 平面テクスチャー -*/ +/*- int CountX : 平面テクスチャーのX方向枚数 ( 省略時 : 1枚 ) -*/ +/*- int CountY : 平面テクスチャーのY方向枚数 ( 省略時 : 1枚 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SetTexture(D3TXR TxrD3,BOOL Quality,BOOL BallType, + int CountX=1,int CountY=1) +{ + DefaultTexture=TxrD3; + DefaultTextureQuality=Quality; + DefaultTextureBall=BallType; + DefaultTextureCountX=CountX; + DefaultTextureCountY=CountY; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャーの透明色の指定 ( el3D::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*- D3TXR TxrD3 : テクスチャー情報 -*/ +/*- D3DCOLOR Color : 透明色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SetTransparentTexture(D3TXR TxrD3,D3DCOLOR Color) +{ + TxrD3->SetDecalTransparency(TRUE); + TxrD3->SetDecalTransparentColor(Color); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャーの透明色の無効化 ( el3D::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*- D3TXR TxrD3 : テクスチャー情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SetTransparentTexture(D3TXR TxrD3) +{ + TxrD3->SetDecalTransparency(FALSE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 影の指定 ( el3D::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*- int Light : ライトNo -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SetShadow(int Light) +{ + DefaultShadow=Light; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデル間のリンク先の指定 ( el3D::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SetLink(D3OBJ ObjD3) +{ + DefaultLink=ObjD3; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 色とテクスチャーの変更可の指定 ( el3D::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SetChange(void) +{ + DefaultChange=TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 色の変更 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Red : 赤の強さ -*/ +/*- float Green : 緑の強さ -*/ +/*- float Blue : 青の強さ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::ChangeColor(D3OBJ ObjD3,float Red,float Green,float Blue) +{ + ObjD3->SetColorRGB(Red,Green,Blue); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャーの変更 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- D3TXR TxrD3 : テクスチャー情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::ChangeTexture(D3OBJ ObjD3,D3TXR TxrD3) +{ + ObjD3->SetColorRGB(F(1),F(1),F(1)); + ObjD3->SetTexture(TxrD3); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャーの明るさ変更 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Bright : 明るさ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::ChangeTextureBright(D3OBJ ObjD3,float Bright) +{ + ObjD3->SetColorRGB(Bright,Bright,Bright); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのテクスチャーを消去 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::ClearTexture(D3OBJ ObjD3) +{ + ObjD3->SetTexture(NULL); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- レンダリング -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::Rendering(void) +{ + static int i; + + for (i=0;iForceUpdate(CameraX1[i],CameraY1[i], + CameraX2[i],CameraY2[i]); + } + } + + ModelNo=0; + CameraNo=0; + + D3RM->Tick(FPS60); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ppfの描画 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::ShowPPF(void) +{ + static char Buffer[64]; + + DrawPolygon=D3RMDevice->GetTrianglesDrawn(); + + sprintf(Buffer,"%ld ppf ( %ld pps )", + DrawPolygon-LastDrawPolygon, + (long)((float)(DrawPolygon-LastDrawPolygon)*elDraw::FpsData)); + + LastDrawPolygon=DrawPolygon; + + elFont::Begin(GOTHIC,12,0,FALSE,FALSE,FALSE); + elFont::Color(RGB(255,255,255),RGB(0,0,128),FALSE); + elFont::Draw(0,15,Buffer); + elFont::Before(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- レンダリングされたポリゴン数の取得 -*/ +/*- -*/ +/*- 戻り値 : ポリゴン数 ( long型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +long el3D::CountPolygon(void) +{ + static long FrameCount,LastFrameCount=0L; + + FrameCount=D3RMDevice->GetTrianglesDrawn()-LastFrameCount; + + LastFrameCount=D3RMDevice->GetTrianglesDrawn(); + + return FrameCount; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- シーンの生成 ( el3Dクラスを使用する場合、一番最初に使用 ) -*/ +/*- -*/ +/*- float Red : 背景の赤の強さ -*/ +/*- float Green : 背景の緑の強さ -*/ +/*- float Blue : 背景の青の強さ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::CreateScene(float Red,float Green,float Blue) +{ + // シーンが生成されていない場合 + if (D3RMScene==NULL) + { + // シーンの生成 + D3RM->CreateFrame(NULL,&D3RMScene); + } + + // シーン背景色の設定 + D3RMScene->SetSceneBackgroundRGB(Red,Green,Blue); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 環境光の生成 -*/ +/*- -*/ +/*- float Bright : 明るさ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::CreateAmbient(float Bright) +{ + // ライトが使用中の場合 + if (D3RMLight[0]!=NULL) + { + // ライトの解放 + D3RMLight[0]->Release(); + D3RMLightType[0]->Release(); + } + + D3RM->CreateLightRGB(D3DRMLIGHT_AMBIENT,Bright,Bright,Bright, + &D3RMLightType[0]); + D3RM->CreateFrame(D3RMScene,&D3RMLight[0]); + D3RMLight[0]->AddLight(D3RMLightType[0]); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライトの生成 -*/ +/*- -*/ +/*- int No : ライトNo -*/ +/*- float Bright : 明るさ -*/ +/*- int Type : ライト方向 ( テンキーの値と同様 ) -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL el3D::CreateLight(int No,float Bright,int Type) +{ + static _lightdata LightData[10]= + { + 0, 0, 0, + -100, 100, 0, + 0, 100, 0, + 100, 100, 0, + -100, 0, 0, + 0, 0, 100, + 100, 0, 0, + -100,-100, 0, + 0,-100, 0, + 100,-100, 0 + }; + + // 異常なライトNoが指定された場合 + if (No<1 || No>LIGHT_MAX-1) + { + return elDraw::Error("el3D::CreateLight", + "ライトNoが範囲外です"); + } + + // 異常なライト方向が指定された場合 + if (Type<0 || Type>9) + { + return elDraw::Error("el3D::CreateLight", + "ライト方向が異常です"); + } + + // ライトが使用中の場合 + if (D3RMLight[No]!=NULL) + { + // ライトの解放 + D3RMLight[No]->Release(); + D3RMLightType[No]->Release(); + } + + LightMx[No]=(float)LightData[Type].x; + LightMy[No]=(float)LightData[Type].y; + LightMz[No]=(float)LightData[Type].z; + + if (Type==0) + { + // 点光源の場合 + D3RM->CreateLightRGB(D3DRMLIGHT_POINT,Bright,Bright,Bright, + &D3RMLightType[No]); + } + else + { + // 方位光源の場合 + D3RM->CreateLightRGB(D3DRMLIGHT_PARALLELPOINT,Bright,Bright,Bright, + &D3RMLightType[No]); + } + + D3RM->CreateFrame(D3RMScene,&D3RMLight[No]); + D3RMLight[No]->AddLight(D3RMLightType[No]); + D3RMLight[No]->SetPosition(D3RMScene, + LightMx[No],-LightMy[No],-LightMz[No]); + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラの生成 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- int X1 : 描画左上X座標 -*/ +/*- int Y1 : 描画左上Y座標 -*/ +/*- int X2 : 描画右下X座標 -*/ +/*- int Y2 : 描画右下Y座標 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL el3D::CreateCamera(int No,int X1,int Y1,int X2,int Y2) +{ + // 異常なカメラNoが指定された場合 + if (No<1 || No>CAMERA_MAX) + { + return elDraw::Error("el3D::CreateCamera", + "カメラNoが範囲外です"); + } + + // カメラが使用中の場合 + if (UseCamera[No-1]) + { + // カメラの解放 + D3RMViewport[No-1]->Release(); + D3RMCamera[No-1]->Release(); + } + + UseCamera[No-1]=TRUE; + + CameraX1[No-1]=X1; + CameraX2[No-1]=X2; + CameraY1[No-1]=Y1; + CameraY2[No-1]=Y2; + + D3RM->CreateFrame(D3RMScene,&D3RMCamera[No-1]); + D3RMCamera[No-1]->SetPosition(D3RMScene,F(0),F(0),F(0)); + D3RM->CreateViewport(D3RMDevice,D3RMCamera[No-1], + CameraX1[No-1],CameraY1[No-1], + CameraX2[No-1]-CameraX1[No-1], + CameraY2[No-1]-CameraY1[No-1], + &D3RMViewport[No-1]); + + el3D::ClipCamera(No,F(1),F(2000)); + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラのクリップ範囲の設定 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- float Front : レンダリング対象となる手前側の距離 ( 初期値=1.0 ) -*/ +/*- float Back : レンダリング対象となる奥側の距離 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::ClipCamera(int No,float Front,float Back) +{ + D3RMViewport[No-1]->SetFront(Front); + D3RMViewport[No-1]->SetBack(Back); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラの描画位置とサイズの変更 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- int X1 : 描画左上X座標 -*/ +/*- int Y1 : 描画左上Y座標 -*/ +/*- int X2 : 描画右下X座標 -*/ +/*- int Y2 : 描画右下Y座標 -*/ +/*- BOOL Clear : 初期化フラグ -*/ +/*- 省略/TRUE = 3Dスプライトを黒で初期化する -*/ +/*- FALSE = 3Dスプライトを黒で初期化しない -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::ResizeCamera(int No,int X1,int Y1,int X2,int Y2,BOOL Clear=TRUE) +{ + CameraX1[No-1]=X1; + CameraX2[No-1]=X2; + CameraY1[No-1]=Y1; + CameraY2[No-1]=Y2; + + D3RMViewport[No-1]->Configure(CameraX1[No-1],CameraY1[No-1], + CameraX2[No-1]-CameraX1[No-1], + CameraY2[No-1]-CameraY1[No-1]); + + if (Clear) elDraw::Clear3D(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラの描画順の切り換え -*/ +/*- -*/ +/*- int No1 : 上に描画される側のカメラNo -*/ +/*- int No2 : 下に描画される側のカメラNo -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SwapDrawCamera(int No1,int No2) +{ + D3RMViewport[No1-1]->Release(); + D3RMViewport[No2-1]->Release(); + + D3RM->CreateViewport(D3RMDevice,D3RMCamera[No2-1], + CameraX1[No2-1],CameraY1[No2-1], + CameraX2[No2-1]-CameraX1[No2-1], + CameraY2[No2-1]-CameraY1[No2-1], + &D3RMViewport[No2-1]); + + D3RM->CreateViewport(D3RMDevice,D3RMCamera[No1-1], + CameraX1[No1-1],CameraY1[No1-1], + CameraX2[No1-1]-CameraX1[No1-1], + CameraY2[No1-1]-CameraY1[No1-1], + &D3RMViewport[No1-1]); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラの初期化 -*/ +/*- -*/ +/*- float MoveSpeed : 移動速度 -*/ +/*- float RotateSpeed : 回転速度 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::InitCamera(float MoveSpeed,float RotateSpeed) +{ + CameraMoveSpeed[CameraNo]=MoveSpeed/F(1000)*FPS60; + CameraRotateSpeed[CameraNo]=RotateSpeed/F(1000)*FPS60; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラの更新 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL el3D::UpdateCamera(void) +{ + if (++CameraNo>CAMERA_MAX) + { + CameraNo=CAMERA_MAX-1; + + return elDraw::Error("el3D::UpdateCamera", + "オブジェクト数が多過ぎます"); + } + + D3RMCamera[CameraNo-1]->AddTranslation(D3DRMCOMBINE_BEFORE, + CameraMx[CameraNo-1]*FPS60, + -CameraMy[CameraNo-1]*FPS60, + -CameraMz[CameraNo-1]*FPS60); + D3RMCamera[CameraNo-1]->AddRotation(D3DRMCOMBINE_BEFORE, + F(0),CameraRx[CameraNo-1],F(0), + CameraRxs[CameraNo-1]*FPS60); + D3RMCamera[CameraNo-1]->AddRotation(D3DRMCOMBINE_BEFORE, + CameraRy[CameraNo-1],F(0),F(0), + CameraRys[CameraNo-1]*FPS60); + D3RMCamera[CameraNo-1]->AddRotation(D3DRMCOMBINE_BEFORE, + F(0),F(0),CameraRz[CameraNo-1], + CameraRzs[CameraNo-1]*FPS60); + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラの更新 ( 値のみ ) -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL el3D::ThroughCamera(void) +{ + if (++CameraNo>CAMERA_MAX) + { + CameraNo=CAMERA_MAX-1; + + return elDraw::Error("el3D::ThroughCamera", + "オブジェクト数が多過ぎます"); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラの停止 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::StopCamera(void) +{ + StopMoveCamera(); + StopRotateCamera(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラの停止 ( 移動情報のみ ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::StopMoveCamera(void) +{ + CameraMx[CameraNo]=F(0); + CameraMy[CameraNo]=F(0); + CameraMz[CameraNo]=F(0); + + CameraMxs[CameraNo]=F(0); + CameraMys[CameraNo]=F(0); + CameraMzs[CameraNo]=F(0); + + CameraMxf[CameraNo]=0; + CameraMyf[CameraNo]=0; + CameraMzf[CameraNo]=0; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラの停止 ( 回転情報のみ ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::StopRotateCamera(void) +{ + CameraRx[CameraNo]=F(0); + CameraRy[CameraNo]=F(0); + CameraRz[CameraNo]=F(0); + + CameraRxs[CameraNo]=F(0); + CameraRys[CameraNo]=F(0); + CameraRzs[CameraNo]=F(0); + + CameraRxf[CameraNo]=0; + CameraRyf[CameraNo]=0; + CameraRzf[CameraNo]=0; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラのX方向移動 -*/ +/*- -*/ +/*- int MoveFlag : 移動方向 ( -:左 / +:右 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::MoveCameraX(int MoveFlag) +{ + if (MoveFlag==CameraMxf[CameraNo] || CameraMxf[CameraNo]==0) + { + CameraMxs[CameraNo]+=CameraMoveSpeed[CameraNo]; + CameraMx[CameraNo]=(float)MoveFlag*CameraMxs[CameraNo]; + CameraMxf[CameraNo]=MoveFlag; + } + else + { + CameraMxs[CameraNo]-=CameraMoveSpeed[CameraNo]; + + if (CameraMxs[CameraNo]<=F(0)) + { + CameraMx[CameraNo]=F(0); + CameraMxs[CameraNo]=F(0); + CameraMxf[CameraNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラのY方向移動 -*/ +/*- -*/ +/*- int MoveFlag : 移動方向 ( -:上 / +:下 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::MoveCameraY(int MoveFlag) +{ + if (MoveFlag==CameraMyf[CameraNo] || CameraMyf[CameraNo]==0) + { + CameraMys[CameraNo]+=CameraMoveSpeed[CameraNo]; + CameraMy[CameraNo]=(float)MoveFlag*CameraMys[CameraNo]; + CameraMyf[CameraNo]=MoveFlag; + } + else + { + CameraMys[CameraNo]-=CameraMoveSpeed[CameraNo]; + + if (CameraMys[CameraNo]<=F(0)) + { + CameraMy[CameraNo]=F(0); + CameraMys[CameraNo]=F(0); + CameraMyf[CameraNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラのZ方向移動 -*/ +/*- -*/ +/*- int MoveFlag : 移動方向 ( -:後 / +:前 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::MoveCameraZ(int MoveFlag) +{ + if (MoveFlag==CameraMzf[CameraNo] || CameraMzf[CameraNo]==0) + { + CameraMzs[CameraNo]+=CameraMoveSpeed[CameraNo]; + CameraMz[CameraNo]=(float)MoveFlag*CameraMzs[CameraNo]; + CameraMzf[CameraNo]=MoveFlag; + } + else + { + CameraMzs[CameraNo]-=CameraMoveSpeed[CameraNo]; + + if (CameraMzs[CameraNo]<=F(0)) + { + CameraMz[CameraNo]=F(0); + CameraMzs[CameraNo]=F(0); + CameraMzf[CameraNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラのX方向回転 -*/ +/*- -*/ +/*- int RotateFlag : 回転方向 ( -:左 / +:右 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::RotateCameraX(int RotateFlag) +{ + if (RotateFlag==CameraRxf[CameraNo] || CameraRxf[CameraNo]==0) + { + CameraRx[CameraNo]=(float)RotateFlag; + CameraRxs[CameraNo]+=CameraRotateSpeed[CameraNo]; + CameraRxf[CameraNo]=RotateFlag; + } + else + { + CameraRxs[CameraNo]-=CameraRotateSpeed[CameraNo]; + + if (CameraRxs[CameraNo]<=F(0)) + { + CameraRx[CameraNo]=F(0); + CameraRxs[CameraNo]=F(0); + CameraRxf[CameraNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラのY方向回転 -*/ +/*- -*/ +/*- int RotateFlag : 回転方向 ( -:下 / +:上 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::RotateCameraY(int RotateFlag) +{ + if (RotateFlag==CameraRyf[CameraNo] || CameraRyf[CameraNo]==0) + { + CameraRy[CameraNo]=(float)RotateFlag; + CameraRys[CameraNo]+=CameraRotateSpeed[CameraNo]; + CameraRyf[CameraNo]=RotateFlag; + } + else + { + CameraRys[CameraNo]-=CameraRotateSpeed[CameraNo]; + + if (CameraRys[CameraNo]<=F(0)) + { + CameraRy[CameraNo]=F(0); + CameraRys[CameraNo]=F(0); + CameraRyf[CameraNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラのZ方向回転 -*/ +/*- -*/ +/*- int RotateFlag : 回転方向 ( -:左傾斜 / +:右傾斜 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::RotateCameraZ(int RotateFlag) +{ + if (RotateFlag==CameraRzf[CameraNo] || CameraRzf[CameraNo]==0) + { + CameraRz[CameraNo]=(float)RotateFlag; + CameraRzs[CameraNo]+=CameraRotateSpeed[CameraNo]; + CameraRzf[CameraNo]=RotateFlag; + } + else + { + CameraRzs[CameraNo]-=CameraRotateSpeed[CameraNo]; + + if (CameraRzs[CameraNo]<=F(0)) + { + CameraRz[CameraNo]=F(0); + CameraRzs[CameraNo]=F(0); + CameraRzf[CameraNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラのX方向ブレーキ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::BrakeMoveCameraX(void) +{ + if (CameraMxs[CameraNo]>F(0)) + { + CameraMxs[CameraNo]-=CameraMoveSpeed[CameraNo]; + CameraMx[CameraNo]=(float)CameraMxf[CameraNo]*CameraMxs[CameraNo]; + + if (CameraMxs[CameraNo]<=F(0)) + { + CameraMx[CameraNo]=F(0); + CameraMxs[CameraNo]=F(0); + CameraMxf[CameraNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラのY方向ブレーキ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::BrakeMoveCameraY(void) +{ + if (CameraMys[CameraNo]>F(0)) + { + CameraMys[CameraNo]-=CameraMoveSpeed[CameraNo]; + CameraMy[CameraNo]=(float)CameraMyf[CameraNo]*CameraMys[CameraNo]; + + if (CameraMys[CameraNo]<=F(0)) + { + CameraMy[CameraNo]=F(0); + CameraMys[CameraNo]=F(0); + CameraMyf[CameraNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラのZ方向ブレーキ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::BrakeMoveCameraZ(void) +{ + if (CameraMzs[CameraNo]>F(0)) + { + CameraMzs[CameraNo]-=CameraMoveSpeed[CameraNo]; + CameraMz[CameraNo]=(float)CameraMzf[CameraNo]*CameraMzs[CameraNo]; + + if (CameraMzs[CameraNo]<=F(0)) + { + CameraMz[CameraNo]=F(0); + CameraMzs[CameraNo]=F(0); + CameraMzf[CameraNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラのX方向への回転ブレーキ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::BrakeRotateCameraX(void) +{ + if (CameraRxs[CameraNo]>F(0)) + { + CameraRxs[CameraNo]-=CameraRotateSpeed[CameraNo]; + + if (CameraRxs[CameraNo]<=F(0)) + { + CameraRx[CameraNo]=F(0); + CameraRxs[CameraNo]=F(0); + CameraRxf[CameraNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラのY方向への回転ブレーキ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::BrakeRotateCameraY(void) +{ + if (CameraRys[CameraNo]>F(0)) + { + CameraRys[CameraNo]-=CameraRotateSpeed[CameraNo]; + + if (CameraRys[CameraNo]<=F(0)) + { + CameraRy[CameraNo]=F(0); + CameraRys[CameraNo]=F(0); + CameraRyf[CameraNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラのZ方向への回転ブレーキ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::BrakeRotateCameraZ(void) +{ + if (CameraRzs[CameraNo]>F(0)) + { + CameraRzs[CameraNo]-=CameraRotateSpeed[CameraNo]; + + if (CameraRzs[CameraNo]<=F(0)) + { + CameraRz[CameraNo]=F(0); + CameraRzs[CameraNo]=F(0); + CameraRzf[CameraNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定位置へカメラの移動 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- float Px : X座標 -*/ +/*- float Py : Y座標 -*/ +/*- float Pz : Z座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectMoveCamera(int No,float Px,float Py,float Pz) +{ + D3RMCamera[No-1]->SetPosition(D3RMScene,Px,-Py,-Pz); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定位置へカメラのX方向移動 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- float Pos : 座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectMoveCameraX(int No,float Pos) +{ + D3RMCamera[No-1]->SetPosition(D3RMScene,Pos,F(0),F(0)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定位置へカメラのY方向移動 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- float Pos : 座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectMoveCameraY(int No,float Pos) +{ + D3RMCamera[No-1]->SetPosition(D3RMScene,F(0),-Pos,F(0)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定位置へカメラのZ方向移動 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- float Pos : 座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectMoveCameraZ(int No,float Pos) +{ + D3RMCamera[No-1]->SetPosition(D3RMScene,F(0),F(0),Pos); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定角度へカメラの回転 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- float Px : X方向 -*/ +/*- float Py : Y方向 -*/ +/*- float Pz : Z方向 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectRotateCamera(int No,float Px,float Py,float Pz) +{ + D3RMCamera[No-1]->AddRotation(D3DRMCOMBINE_BEFORE, + F((Py!=0)),F((Px!=0)),F((Pz!=0)), + (Px+Py+Pz)*FrameTime); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 360度指定によるカメラの回転 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- float Px : X方向 -*/ +/*- float Py : Y方向 -*/ +/*- float Pz : Z方向 -*/ +/*- float Pr : 角度 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectRotate360Camera(int No,float Px,float Py,float Pz,float Pr) +{ + if (Px!=F(0) || Py!=F(0) || Pz!=F(0)) + { + D3RMCamera[No-1]->AddRotation(D3DRMCOMBINE_BEFORE, + F((Py!=0)),F((Px!=0)),F((Pz!=0)), + F(PAI)/F(180)*F(Pr)); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 360度指定によるカメラのX方向回転 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- float Pr : 角度 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectRotate360CameraX(int No,float Pr) +{ + D3RMCamera[No-1]->AddRotation(D3DRMCOMBINE_BEFORE,F(0),F(1),F(0), + F(PAI)/F(180)*F(Pr)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 360度指定によるカメラのY方向回転 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- float Pr : 角度 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectRotate360CameraY(int No,float Pr) +{ + D3RMCamera[No-1]->AddRotation(D3DRMCOMBINE_BEFORE,F(1),F(0),F(0), + F(PAI)/F(180)*F(Pr)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 360度指定によるカメラのZ方向回転 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- float Pr : 角度 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectRotate360CameraZ(int No,float Pr) +{ + D3RMCamera[No-1]->AddRotation(D3DRMCOMBINE_BEFORE,F(0),F(0),F(1), + F(PAI)/F(180)*F(Pr)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 視点をモデルに設定 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::LookAtCamera(D3OBJ ObjD3) +{ + D3RMCamera[CameraNo]->LookAt(ObjD3,D3RMScene,D3DRMCONSTRAIN_Z); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定されたカメラ視点をモデルに設定 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectLookAtCamera(int No,D3OBJ ObjD3) +{ + D3RMCamera[No-1]->LookAt(ObjD3,D3RMScene,D3DRMCONSTRAIN_Z); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラの表示 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::ShowCamera(int No) +{ + D3RMViewport[No-1]->Configure(CameraX1[No-1],CameraY1[No-1], + CameraX2[No-1]-CameraX1[No-1], + CameraY2[No-1]-CameraY1[No-1]); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラの消去 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- BOOL Clear : 初期化フラグ -*/ +/*- 省略/TRUE = 3Dスプライトを黒で初期化する -*/ +/*- FALSE = 3Dスプライトを黒で初期化しない -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::HideCamera(int No,BOOL Clear=TRUE) +{ + D3RMViewport[No-1]->Configure(0,0,0,0); + + if (Clear) elDraw::Clear3D(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ視点をモデル追尾に設定 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Px : モデル後方を0とするX座標 -*/ +/*- float Py : モデル後方を0とするY座標 -*/ +/*- float Distance : モデルとカメラの距離 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SearchCamera(D3OBJ ObjD3,float Px,float Py,float Distance) +{ + static D3DVECTOR Para1,Para2; + + ObjD3->GetOrientation(D3RMScene,&Para1,&Para2); + + D3RMCamera[CameraNo]->SetOrientation(D3RMScene, + Para1.x,Para1.y,Para1.z, + Para2.x,Para2.y,Para2.z); + D3RMCamera[CameraNo]->SetPosition(ObjD3,Px,Py,F(0)); + D3RMCamera[CameraNo]->AddTranslation(D3DRMCOMBINE_BEFORE, + F(0),F(0),-Distance); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定されたカメラ視点をモデル追尾に設定 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Px : モデル後方を0とするX座標 -*/ +/*- float Py : モデル後方を0とするY座標 -*/ +/*- float Distance : モデルとカメラの距離 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectSearchCamera(int No,D3OBJ ObjD3,float Px,float Py,float Distance) +{ + static D3DVECTOR Para1,Para2; + + ObjD3->GetOrientation(D3RMScene,&Para1,&Para2); + + D3RMCamera[No-1]->SetOrientation(D3RMScene, + Para1.x,Para1.y,Para1.z, + Para2.x,Para2.y,Para2.z); + D3RMCamera[No-1]->SetPosition(ObjD3,Px,Py,F(0)); + D3RMCamera[No-1]->AddTranslation(D3DRMCOMBINE_BEFORE, + F(0),F(0),-Distance); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ視点を指定角度でモデル追尾に設定 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Rx : モデルを0度とするX方向の角度 -*/ +/*- float Ry : モデルを0度とするY方向の角度 -*/ +/*- float Distance : モデルとカメラの距離 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::Search360Camera(D3OBJ ObjD3,float Rx,float Ry,float Distance) +{ + static D3DVECTOR Para1,Para2; + + ObjD3->GetOrientation(D3RMScene,&Para1,&Para2); + + D3RMCamera[CameraNo]->SetOrientation(D3RMScene, + Para1.x,Para1.y,Para1.z, + Para2.x,Para2.y,Para2.z); + D3RMCamera[CameraNo]->SetPosition(ObjD3,F(0),F(0),F(0)); + D3RMCamera[CameraNo]->AddRotation(D3DRMCOMBINE_BEFORE, + F(0),F(1),F(0),F(PAI)/F(180)*F(Rx)); + D3RMCamera[CameraNo]->AddRotation(D3DRMCOMBINE_BEFORE, + F(1),F(0),F(0),F(PAI)/F(180)*F(Ry)); + D3RMCamera[CameraNo]->AddTranslation(D3DRMCOMBINE_BEFORE, + F(0),F(0),-Distance); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定されたカメラ視点を指定角度でモデル追尾に設定 -*/ +/*- -*/ +/*- int No : カメラNo -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Rx : モデルを0度とするX方向の角度 -*/ +/*- float Ry : モデルを0度とするY方向の角度 -*/ +/*- float Distance : モデルとカメラの距離 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectSearch360Camera(int No,D3OBJ ObjD3,float Rx,float Ry, + float Distance) +{ + static D3DVECTOR Para1,Para2; + + ObjD3->GetOrientation(D3RMScene,&Para1,&Para2); + + D3RMCamera[No-1]->SetOrientation(D3RMScene, + Para1.x,Para1.y,Para1.z, + Para2.x,Para2.y,Para2.z); + D3RMCamera[No-1]->SetPosition(ObjD3,F(0),F(0),F(0)); + D3RMCamera[No-1]->AddRotation(D3DRMCOMBINE_BEFORE, + F(0),F(1),F(0),F(PAI)/F(180)*F(Rx)); + D3RMCamera[No-1]->AddRotation(D3DRMCOMBINE_BEFORE, + F(1),F(0),F(0),F(PAI)/F(180)*F(Ry)); + D3RMCamera[No-1]->AddTranslation(D3DRMCOMBINE_BEFORE, + F(0),F(0),-Distance); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルの初期化 -*/ +/*- -*/ +/*- float MoveSpeed : 移動速度 -*/ +/*- float RotateSpeed : 回転速度 -*/ +/*- float MoveMaxSpeed : 移動速度の上限値 -*/ +/*- float RotateMaxSpeed : 回転速度の上限値 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::InitModel(float MoveSpeed,float RotateSpeed, + float MoveMaxSpeed,float RotateMaxSpeed) +{ + ModelMoveSpeed[ModelNo]=MoveSpeed/F(1000)*FPS60; + ModelRotateSpeed[ModelNo]=RotateSpeed/F(1000)*FPS60; + ModelMoveMaxSpeed[ModelNo]=MoveMaxSpeed/F(1000); + ModelRotateMaxSpeed[ModelNo]=RotateMaxSpeed/F(1000); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルの更新 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL el3D::UpdateModel(D3OBJ ObjD3) +{ + if (++ModelNo>MODEL_MAX) + { + ModelNo=MODEL_MAX-1; + + return elDraw::Error("el3D::UpdateModel", + "オブジェクト数が多過ぎます"); + } + + ObjD3->AddTranslation(D3DRMCOMBINE_BEFORE, + ModelMx[ModelNo-1]*FPS60, + -ModelMy[ModelNo-1]*FPS60, + -ModelMz[ModelNo-1]*FPS60); + ObjD3->AddRotation(D3DRMCOMBINE_BEFORE, + F(0),ModelRx[ModelNo-1],F(0), + ModelRxs[ModelNo-1]*FPS60); + ObjD3->AddRotation(D3DRMCOMBINE_BEFORE, + ModelRy[ModelNo-1],F(0),F(0), + ModelRys[ModelNo-1]*FPS60); + ObjD3->AddRotation(D3DRMCOMBINE_BEFORE, + F(0),F(0),ModelRz[ModelNo-1], + ModelRzs[ModelNo-1]*FPS60); + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルの更新 ( 値のみ ) -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL el3D::ThroughModel(void) +{ + if (++ModelNo>MODEL_MAX) + { + ModelNo=MODEL_MAX-1; + + return elDraw::Error("el3D::ThroughModel", + "オブジェクト数が多過ぎます"); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルの停止 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::StopModel(void) +{ + StopMoveModel(); + StopRotateModel(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 全モデルの停止 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::StopAllModel(void) +{ + for (ModelNo=0;ModelNoModelMoveMaxSpeed[ModelNo]) + { + ModelMxs[ModelNo]=ModelMoveMaxSpeed[ModelNo]; + } + + ModelMx[ModelNo]=(float)MoveFlag*ModelMxs[ModelNo]; + ModelMxf[ModelNo]=MoveFlag; + } + else + { + ModelMxs[ModelNo]-=ModelMoveSpeed[ModelNo]; + + if (ModelMxs[ModelNo]<=F(0)) + { + ModelMx[ModelNo]=F(0); + ModelMxs[ModelNo]=F(0); + ModelMxf[ModelNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのY方向移動 -*/ +/*- -*/ +/*- int MoveFlag : 移動方向 ( -:上 / +:下 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::MoveModelY(int MoveFlag) +{ + if (MoveFlag==ModelMyf[ModelNo] || ModelMyf[ModelNo]==0) + { + ModelMys[ModelNo]+=ModelMoveSpeed[ModelNo]; + + if (ModelMys[ModelNo]>ModelMoveMaxSpeed[ModelNo]) + { + ModelMys[ModelNo]=ModelMoveMaxSpeed[ModelNo]; + } + + ModelMy[ModelNo]=(float)MoveFlag*ModelMys[ModelNo]; + ModelMyf[ModelNo]=MoveFlag; + } + else + { + ModelMys[ModelNo]-=ModelMoveSpeed[ModelNo]; + + if (ModelMys[ModelNo]<=F(0)) + { + ModelMy[ModelNo]=F(0); + ModelMys[ModelNo]=F(0); + ModelMyf[ModelNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのZ方向移動 -*/ +/*- -*/ +/*- int MoveFlag : 移動方向 ( -:後 / +:前 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::MoveModelZ(int MoveFlag) +{ + if (MoveFlag==ModelMzf[ModelNo] || ModelMzf[ModelNo]==0) + { + ModelMzs[ModelNo]+=ModelMoveSpeed[ModelNo]; + + if (ModelMzs[ModelNo]>ModelMoveMaxSpeed[ModelNo]) + { + ModelMzs[ModelNo]=ModelMoveMaxSpeed[ModelNo]; + } + + ModelMz[ModelNo]=(float)MoveFlag*ModelMzs[ModelNo]; + ModelMzf[ModelNo]=MoveFlag; + } + else + { + ModelMzs[ModelNo]-=ModelMoveSpeed[ModelNo]; + + if (ModelMzs[ModelNo]<=F(0)) + { + ModelMz[ModelNo]=F(0); + ModelMzs[ModelNo]=F(0); + ModelMzf[ModelNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのX方向回転 -*/ +/*- -*/ +/*- int RotateFlag : 回転方向 ( -:左 / +:右 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::RotateModelX(int RotateFlag) +{ + if (RotateFlag==ModelRxf[ModelNo] || ModelRxf[ModelNo]==0) + { + ModelRx[ModelNo]=(float)RotateFlag; + ModelRxs[ModelNo]+=ModelRotateSpeed[ModelNo]; + + if (ModelRxs[ModelNo]>ModelRotateMaxSpeed[ModelNo]) + { + ModelRxs[ModelNo]=ModelRotateMaxSpeed[ModelNo]; + } + + ModelRxf[ModelNo]=RotateFlag; + } + else + { + ModelRxs[ModelNo]-=ModelRotateSpeed[ModelNo]; + + if (ModelRxs[ModelNo]<=F(0)) + { + ModelRx[ModelNo]=F(0); + ModelRxs[ModelNo]=F(0); + ModelRxf[ModelNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのY方向回転 -*/ +/*- -*/ +/*- int RotateFlag : 回転方向 ( -:下 / +:上 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::RotateModelY(int RotateFlag) +{ + if (RotateFlag==ModelRyf[ModelNo] || ModelRyf[ModelNo]==0) + { + ModelRy[ModelNo]=(float)RotateFlag; + ModelRys[ModelNo]+=ModelRotateSpeed[ModelNo]; + + if (ModelRys[ModelNo]>ModelRotateMaxSpeed[ModelNo]) + { + ModelRys[ModelNo]=ModelRotateMaxSpeed[ModelNo]; + } + + ModelRyf[ModelNo]=RotateFlag; + } + else + { + ModelRys[ModelNo]-=ModelRotateSpeed[ModelNo]; + + if (ModelRys[ModelNo]<=F(0)) + { + ModelRy[ModelNo]=F(0); + ModelRys[ModelNo]=F(0); + ModelRyf[ModelNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのZ方向回転 -*/ +/*- -*/ +/*- int RotateFlag : 回転方向 ( -:左傾斜 / +:右傾斜 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::RotateModelZ(int RotateFlag) +{ + if (RotateFlag==ModelRzf[ModelNo] || ModelRzf[ModelNo]==0) + { + ModelRz[ModelNo]=(float)RotateFlag; + ModelRzs[ModelNo]+=ModelRotateSpeed[ModelNo]; + + if (ModelRzs[ModelNo]>ModelRotateMaxSpeed[ModelNo]) + { + ModelRzs[ModelNo]=ModelRotateMaxSpeed[ModelNo]; + } + + ModelRzf[ModelNo]=RotateFlag; + } + else + { + ModelRzs[ModelNo]-=ModelRotateSpeed[ModelNo]; + + if (ModelRzs[ModelNo]<=F(0)) + { + ModelRz[ModelNo]=F(0); + ModelRzs[ModelNo]=F(0); + ModelRzf[ModelNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのX方向ブレーキ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::BrakeMoveModelX(void) +{ + if (ModelMxs[ModelNo]>F(0)) + { + ModelMxs[ModelNo]-=ModelMoveSpeed[ModelNo]; + ModelMx[ModelNo]=(float)ModelMxf[ModelNo]*ModelMxs[ModelNo]; + + if (ModelMxs[ModelNo]<=F(0)) + { + ModelMx[ModelNo]=F(0); + ModelMxs[ModelNo]=F(0); + ModelMxf[ModelNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのY方向ブレーキ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::BrakeMoveModelY(void) +{ + if (ModelMys[ModelNo]>F(0)) + { + ModelMys[ModelNo]-=ModelMoveSpeed[ModelNo]; + ModelMy[ModelNo]=(float)ModelMyf[ModelNo]*ModelMys[ModelNo]; + + if (ModelMys[ModelNo]<=F(0)) + { + ModelMy[ModelNo]=F(0); + ModelMys[ModelNo]=F(0); + ModelMyf[ModelNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのZ方向ブレーキ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::BrakeMoveModelZ(void) +{ + if (ModelMzs[ModelNo]>F(0)) + { + ModelMzs[ModelNo]-=ModelMoveSpeed[ModelNo]; + ModelMz[ModelNo]=(float)ModelMzf[ModelNo]*ModelMzs[ModelNo]; + + if (ModelMzs[ModelNo]<=F(0)) + { + ModelMz[ModelNo]=F(0); + ModelMzs[ModelNo]=F(0); + ModelMzf[ModelNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのX方向への回転ブレーキ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::BrakeRotateModelX(void) +{ + if (ModelRxs[ModelNo]>F(0)) + { + ModelRxs[ModelNo]-=ModelRotateSpeed[ModelNo]; + + if (ModelRxs[ModelNo]<=F(0)) + { + ModelRx[ModelNo]=F(0); + ModelRxs[ModelNo]=F(0); + ModelRxf[ModelNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのY方向への回転ブレーキ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::BrakeRotateModelY(void) +{ + if (ModelRys[ModelNo]>F(0)) + { + ModelRys[ModelNo]-=ModelRotateSpeed[ModelNo]; + + if (ModelRys[ModelNo]<=F(0)) + { + ModelRy[ModelNo]=F(0); + ModelRys[ModelNo]=F(0); + ModelRyf[ModelNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのZ方向への回転ブレーキ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::BrakeRotateModelZ(void) +{ + if (ModelRzs[ModelNo]>F(0)) + { + ModelRzs[ModelNo]-=ModelRotateSpeed[ModelNo]; + + if (ModelRzs[ModelNo]<=F(0)) + { + ModelRz[ModelNo]=F(0); + ModelRzs[ModelNo]=F(0); + ModelRzf[ModelNo]=0; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルの移動情報のコピー -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::CopyMoveModel(void) +{ + CopyModelMx=ModelMx[ModelNo]; + CopyModelMxs=ModelMxs[ModelNo]; + CopyModelMxf=ModelMxf[ModelNo]; + + CopyModelMy=ModelMy[ModelNo]; + CopyModelMys=ModelMys[ModelNo]; + CopyModelMyf=ModelMyf[ModelNo]; + + CopyModelMz=ModelMz[ModelNo]; + CopyModelMzs=ModelMzs[ModelNo]; + CopyModelMzf=ModelMzf[ModelNo]; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルの移動情報をペースト -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::PasteMoveModel(void) +{ + ModelMx[ModelNo]=CopyModelMx; + ModelMxs[ModelNo]=CopyModelMxs; + ModelMxf[ModelNo]=CopyModelMxf; + + ModelMy[ModelNo]=CopyModelMy; + ModelMys[ModelNo]=CopyModelMys; + ModelMyf[ModelNo]=CopyModelMyf; + + ModelMz[ModelNo]=CopyModelMz; + ModelMzs[ModelNo]=CopyModelMzs; + ModelMzf[ModelNo]=CopyModelMzf; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルの移動&回転情報をランダム設定 -*/ +/*- -*/ +/*- int Size : ランダム値の大きさ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::RandomMoveModel(int Size) +{ + el3D::ModelMzs[ModelNo]=F(rand()%Size)/F(100); + el3D::ModelMzf[ModelNo]=(rand()%2+1)*2-3; + el3D::ModelMz[ModelNo]=el3D::ModelMzs[ModelNo]* + (float)el3D::ModelMzf[ModelNo]; + + el3D::ModelRxf[ModelNo]=(rand()%2+1)*2-3; + el3D::ModelRx[ModelNo]=(float)el3D::ModelRxf[ModelNo]; + el3D::ModelRxs[ModelNo]=F(rand()%Size)/F(100); + + el3D::ModelRyf[ModelNo]=(rand()%2+1)*2-3; + el3D::ModelRy[ModelNo]=(float)el3D::ModelRyf[ModelNo]; + el3D::ModelRys[ModelNo]=F(rand()%Size)/F(100); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルの移動&回転情報を反転 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::ReverseMoveModel(void) +{ + el3D::ModelMz[ModelNo]=-el3D::ModelMz[ModelNo]; + el3D::ModelMzf[ModelNo]=-el3D::ModelMzf[ModelNo]; + + el3D::ModelRx[ModelNo]=-el3D::ModelRx[ModelNo]; + el3D::ModelRxf[ModelNo]=-el3D::ModelRxf[ModelNo]; + + el3D::ModelRy[ModelNo]=-el3D::ModelRy[ModelNo]; + el3D::ModelRyf[ModelNo]=-el3D::ModelRyf[ModelNo]; + + el3D::ModelRz[ModelNo]=-el3D::ModelRz[ModelNo]; + el3D::ModelRzf[ModelNo]=-el3D::ModelRzf[ModelNo]; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定位置へモデルの移動 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Px : X座標 -*/ +/*- float Py : Y座標 -*/ +/*- float Pz : Z座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectMoveModel(D3OBJ ObjD3,float Px,float Py,float Pz) +{ + ObjD3->AddTranslation(D3DRMCOMBINE_REPLACE,Px,-Py,-Pz); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 移動量指定によるモデルのX方向移動 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Move : 移動量 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectMoveModelX(D3OBJ ObjD3,float Move) +{ + ObjD3->AddTranslation(D3DRMCOMBINE_BEFORE,Move,F(0),F(0)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 移動量指定によるモデルのY方向移動 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Move : 移動量 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectMoveModelY(D3OBJ ObjD3,float Move) +{ + ObjD3->AddTranslation(D3DRMCOMBINE_BEFORE,F(0),-Move,F(0)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 移動量指定によるモデルのZ方向移動 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Move : 移動量 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectMoveModelZ(D3OBJ ObjD3,float Move) +{ + ObjD3->AddTranslation(D3DRMCOMBINE_BEFORE,F(0),F(0),-Move); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定角度へモデルの回転 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Px : X方向 -*/ +/*- float Py : Y方向 -*/ +/*- float Pz : Z方向 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectRotateModel(D3OBJ ObjD3,float Px,float Py,float Pz) +{ + ObjD3->AddRotation(D3DRMCOMBINE_BEFORE, + F((Py!=0)),F((Px!=0)),F((Pz!=0)), + (Px+Py+Pz)*FrameTime); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 360度指定によるモデルの回転 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Px : X方向 -*/ +/*- float Py : Y方向 -*/ +/*- float Pz : Z方向 -*/ +/*- float Pr : 角度 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectRotate360Model(D3OBJ ObjD3,float Px,float Py,float Pz,float Pr) +{ + if (Px!=F(0) || Py!=F(0) || Pz!=F(0)) + { + ObjD3->AddRotation(D3DRMCOMBINE_BEFORE,F((Py!=0)),F((Px!=0)),F((Pz!=0)), + F(PAI)/F(180)*F(Pr)); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 360度指定によるモデルのX方向回転 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Pr : 角度 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectRotate360ModelX(D3OBJ ObjD3,float Pr) +{ + ObjD3->AddRotation(D3DRMCOMBINE_BEFORE,F(0),F(1),F(0),F(PAI)/F(180)*F(Pr)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 360度指定によるモデルのY方向回転 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Pr : 角度 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectRotate360ModelY(D3OBJ ObjD3,float Pr) +{ + ObjD3->AddRotation(D3DRMCOMBINE_BEFORE,F(1),F(0),F(0),F(PAI)/F(180)*F(Pr)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 360度指定によるモデルのZ方向回転 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- float Pr : 角度 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectRotate360ModelZ(D3OBJ ObjD3,float Pr) +{ + ObjD3->AddRotation(D3DRMCOMBINE_BEFORE,F(0),F(0),F(1),F(PAI)/F(180)*F(Pr)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 視点を別なモデルに設定 -*/ +/*- -*/ +/*- D3OBJ ObjD3A : モデル情報 ( 視点が変わる側 ) -*/ +/*- D3OBJ ObjD3B : モデル情報 ( 視点となる側 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::LookAtModel(D3OBJ ObjD3A,D3OBJ ObjD3B) +{ + ObjD3A->LookAt(ObjD3B,D3RMScene,D3DRMCONSTRAIN_Z); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルの表示 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::ShowModel(D3OBJ ObjD3) +{ + D3RMScene->AddChild(ObjD3); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- リンクしたモデルの表示 -*/ +/*- -*/ +/*- D3OBJ ObjD3A : モデル情報 -*/ +/*- D3OBJ ObjD3B : モデル情報 ( 表示される側 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::ShowLinkModel(D3OBJ ObjD3A,D3OBJ ObjD3B) +{ + ObjD3A->AddChild(ObjD3B); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルの消去 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::HideModel(D3OBJ ObjD3) +{ + D3RMScene->DeleteChild(ObjD3); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- リンクしたモデルの消去 -*/ +/*- -*/ +/*- D3OBJ ObjD3A : モデル情報 -*/ +/*- D3OBJ ObjD3B : モデル情報 ( 消去される側 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::HideLinkModel(D3OBJ ObjD3A,D3OBJ ObjD3B) +{ + ObjD3A->DeleteChild(ObjD3B); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 座標(0,0,0)からの距離の取得 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- -*/ +/*- 戻り値 : 距離 ( float型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +float el3D::DistanceZeroModel(D3OBJ ObjD3) +{ + static D3DVECTOR Pos; + + D3RMScene->GetPosition(ObjD3,&Pos); + + return (float)sqrt(Pos.x*Pos.x+Pos.y*Pos.y+Pos.z*Pos.z); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルからモデルへの距離の取得 -*/ +/*- -*/ +/*- D3OBJ ObjD3A : モデル情報 -*/ +/*- D3OBJ ObjD3B : モデル情報 -*/ +/*- -*/ +/*- 戻り値 : 距離 ( float型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +float el3D::DistanceModel(D3OBJ ObjD3A,D3OBJ ObjD3B) +{ + static D3DVECTOR Pos; + + ObjD3A->GetPosition(ObjD3B,&Pos); + + return (float)sqrt(Pos.x*Pos.x+Pos.y*Pos.y+Pos.z*Pos.z); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 別なモデルと同じ位置に移動 -*/ +/*- -*/ +/*- D3OBJ ObjD3A : モデル情報 ( 移動先となる側 ) -*/ +/*- D3OBJ ObjD3B : モデル情報 ( 移動する側 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::FollowModel(D3OBJ ObjD3A,D3OBJ ObjD3B) +{ + static D3DVECTOR Para1,Para2; + + ObjD3A->GetOrientation(D3RMScene,&Para1,&Para2); + ObjD3B->SetOrientation(D3RMScene,Para1.x,Para1.y,Para1.z, + Para2.x,Para2.y,Para2.z); + ObjD3B->SetPosition(ObjD3A,F(0),F(0),F(0)); + ObjD3B->AddTranslation(D3DRMCOMBINE_BEFORE,F(0),F(0),F(0)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのX方向移動状態の取得 -*/ +/*- -*/ +/*- float* Speed : 速度 ( 戻り値 ) -*/ +/*- int* Flag : 移動方向 ( 戻り値 / -:左 / +:右 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::GetMoveModelX(float* Speed,int* Flag) +{ + *Speed=el3D::ModelMxs[el3D::ModelNo]; + *Flag=(int)el3D::ModelMxf[el3D::ModelNo]; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのY方向移動状態の取得 -*/ +/*- -*/ +/*- float* Speed : 速度 ( 戻り値 ) -*/ +/*- int* Flag : 移動方向 ( 戻り値 / -:上 / +:下 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::GetMoveModelY(float* Speed,int* Flag) +{ + *Speed=el3D::ModelMys[el3D::ModelNo]; + *Flag=(int)el3D::ModelMyf[el3D::ModelNo]; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルのZ方向移動状態の取得 -*/ +/*- -*/ +/*- float* Speed : 速度 ( 戻り値 ) -*/ +/*- int* Flag : 移動方向 ( 戻り値 / -:後 / +:前 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::GetMoveModelZ(float* Speed,int* Flag) +{ + *Speed=el3D::ModelMzs[el3D::ModelNo]; + *Flag=(int)el3D::ModelMzf[el3D::ModelNo]; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルの画面座標の取得 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- int CameraNo : カメラNo -*/ +/*- int* Sx : 画面のX座標 ( 戻り値 ) -*/ +/*- int* Sy : 画面のY座標 ( 戻り値 ) -*/ +/*- float* Sz : 省略 = 未使用 -*/ +/*- 任意のfloat*型変数 = 3D画面のZ座標 ( 戻り値 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +static float _DefaultSz; + +void el3D::GetScreenPositionModel(D3OBJ ObjD3,int CameraNo, + int* Sx,int* Sy,float* Sz=&_DefaultSz) +{ + static D3DVECTOR Pos; + static D3DRMVECTOR4D Scr; + + // 3D座標から2D座標に変換 + ObjD3->GetPosition(D3RMScene,&Pos); + D3RMViewport[CameraNo-1]->Transform(&Scr,&Pos); + + if (Scr.z>=F(0) && Scr.zGetParent(&LinkD3); + + return LinkD3; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 画面座標でのリンク先モデルの検索 -*/ +/*- -*/ +/*- int Sx : 画面のX座標 -*/ +/*- int Sy : 画面のY座標 -*/ +/*- int CameraNo : カメラNo -*/ +/*- D3OBJ LinkD3A : リンク先1モデル情報 -*/ +/*- D3OBJ LinkD3B : リンク先2モデル情報 ( 省略可能 ) -*/ +/*- -*/ +/*- 戻り値 : リンク先1モデルだけ指定した場合 -*/ +/*- TRUE = モデルが見つかった -*/ +/*- FALSE = モデルが見つからなかった -*/ +/*- : リンク先1と2のモデルを指定した場合 -*/ +/*- 0 = モデルが見つからなかった -*/ +/*- 1 = リンク先1モデルが手前に見つかった -*/ +/*- 2 = リンク先2モデルが手前に見つかった -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int el3D::SearchLinkModel(int Sx,int Sy,int CameraNo, + D3OBJ LinkD3A,D3OBJ LinkD3B=NULL) +{ + static int i,j; + static int Flag; + static LPDIRECT3DRMPICKEDARRAY Array; + static LPDIRECT3DRMVISUAL Visual; + static LPDIRECT3DRMFRAMEARRAY Frame; + static LPD3DRMPICKDESC pd; + static LPDIRECT3DRMFRAME Model,Link; + + Flag=0; + + // 2D座標で3Dオブジェクトを取得できる場合 + if (D3RMViewport[CameraNo-1]->Pick(Sx,Sy,&Array)==D3DRM_OK) + { + // モデルの検索 + for (i=0;i<(int)Array->GetSize();i++) + { + Array->GetPick(i,&Visual,&Frame,pd); + + for (j=0;j<(int)Frame->GetSize();j++) + { + Frame->GetElement(j,&Model); + Model->GetParent(&Link); + Model->Release(); + + // リンク先1と同じ場合 + if (LinkD3A==Link) + { + Flag=1; + + break; + } + + // リンク先2と同じ場合 + if (LinkD3B==Link && LinkD3B) + { + Flag=2; + + break; + } + } + + Frame->Release(); + Visual->Release(); + + if (Flag) break; + } + + Array->Release(); + } + + return Flag; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定位置へライトの移動 -*/ +/*- -*/ +/*- int No : ライトNo -*/ +/*- float Px : X座標 -*/ +/*- float Py : Y座標 -*/ +/*- float Pz : Z座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::DirectMoveLight(int No,float Px,float Py,float Pz) +{ + LightMx[No]=Px; + LightMy[No]=Py; + LightMz[No]=Pz; + + D3RMLight[No]->SetPosition(D3RMScene,Px,-Py,-Pz); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライトの表示 -*/ +/*- -*/ +/*- int No : ライトNo -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::ShowLight(int No) +{ + D3RMScene->AddChild(D3RMLight[No]); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライトの消去 -*/ +/*- -*/ +/*- int No : ライトNo -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::HideLight(int No) +{ + D3RMScene->DeleteChild(D3RMLight[No]); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 自動移動ライトの設定 -*/ +/*- -*/ +/*- int No : ライトNo -*/ +/*- float Px : X方向 -*/ +/*- float Py : Y方向 -*/ +/*- float Pz : Z方向 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::SetAutoLight(int No,float Px,float Py,float Pz) +{ + LightMxp[No]=Px; + LightMyp[No]=Py; + LightMzp[No]=Pz; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 自動移動ライトの実行 -*/ +/*- -*/ +/*- int No : ライトNo -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::AutoLight(int No) +{ + LightMx[No]+=LightMxp[No]; + if (LightMx[No]<-100 || LightMx[No]>100) LightMxp[No]=-LightMxp[No]; + + LightMy[No]+=LightMyp[No]; + if (LightMy[No]<-100 || LightMy[No]>100) LightMyp[No]=-LightMyp[No]; + + LightMz[No]+=LightMzp[No]; + if (LightMz[No]<-100 || LightMz[No]>100) LightMzp[No]=-LightMzp[No]; + + D3RMLight[No]->SetPosition(D3RMScene, + LightMx[No]*FPS60, + -LightMy[No]*FPS60, + -LightMz[No]*FPS60); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モデルと同じ位置に移動 -*/ +/*- -*/ +/*- D3OBJ ObjD3 : モデル情報 -*/ +/*- int No : ライトNo -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el3D::FollowLight(D3OBJ ObjD3,int No) +{ + static D3DVECTOR Pos; + + ObjD3->GetPosition(D3RMScene,&Pos); + D3RMLight[No]->SetPosition(D3RMScene,Pos.x,Pos.y,Pos.z); +} + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= 4Dクラス定義 ( el4D ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef DIRECT3D_IM + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 4Dクラスの初期化 ※ 内部で使用 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL el4D::Init(void) +{ + int i,j; + HRESULT ddret; + DDSURFACEDESC2 ddsd; + + // Direct3D IMの取得 + if (FAILED(DDObject->QueryInterface(IID_IDirect3D7,(void**)&D3))) + { + return elDraw::Error("el4D::Init", + "Direct3D IMが取得できません"); + } + + while (TRUE) + { + // 頂点バッファタイプを自動に設定 + el4D::Config::VertexBuffer=MEM_AUTO; + + // TnLを使わないHALを要求していた場合 + if (el4D::Config::User&DC4D_NOTNL) + { + // Direct3Dドライバーの検索 + D3->EnumDevices(SearchDriver,(LPVOID)FALSE); + } + else + { + // Direct3D TnLドライバーの検索 + D3->EnumDevices(SearchDriver,(LPVOID)TRUE); + + // 見つからなかった場合 + if (!(el4D::Config::Driver&DC4D_OK)) + { + // Direct3Dドライバーの検索 + D3->EnumDevices(SearchDriver,(LPVOID)FALSE); + } + // TnLドライバーが見つかった場合 + else + { + // 頂点バッファタイプをレンダリング速度優先に設定 + el4D::Config::VertexBuffer=MEM_RENDER; + } + } + + // 要求されたDirect3Dドライバーが見つかった場合 + if (el4D::Config::Driver&DC4D_OK) break; + + // カラーとZに同じビット数を要求していた場合 + if (el4D::Config::User&DC4D_BITEQUAL) + { + // この要求を無効にして再検索 + el4D::Config::User^=DC4D_BITEQUAL; + + continue; + } + + // HELを要求していない場合 + if (!(el4D::Config::User&DC4D_USEHEL)) + { + // HELにして再検索 + if (el4D::Config::User&DC4D_USERR) el4D::Config::User^=DC4D_USERR; + el4D::Config::User|=DC4D_USEHEL; + + D3->EnumDevices(SearchDriver,FALSE); + if (el4D::Config::Driver&DC4D_OK) break; + } + + // ドライバーが見つからなかった場合 + return elDraw::Error("el4D::Init", + "Direct3D IMが見つかりません"); + } + + // Zバッファを検索 + el4D::Config::ZBuffer.dwSize=0; + D3->EnumZBufferFormats(el4D::Config::DriverGUID,SearchZBuffer, + (void*)&el4D::Config::ZBuffer); + + // 要求されたZバッファが見つからなかった場合 + if (sizeof(DDPIXELFORMAT)!=el4D::Config::ZBuffer.dwSize) + { + // カラーとZに同じビット数を要求していた場合 + if (el4D::Config::User&DC4D_BITEQUAL) + { + // この要求を無効にして再検索 + el4D::Config::User^=DC4D_BITEQUAL; + + el4D::Config::ZBuffer.dwSize=0; + D3->EnumZBufferFormats(el4D::Config::DriverGUID,SearchZBuffer, + (void*)&el4D::Config::ZBuffer); + } + + // Zバッファが見つからなかった場合 + if (sizeof(DDPIXELFORMAT)!=el4D::Config::ZBuffer.dwSize) + { + return elDraw::Error("el4D::Init", + "Z Bufferが無効です"); + } + } + + // Zバッファの生成 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC2)); + ddsd.dwSize=sizeof(DDSURFACEDESC2); + ddsd.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT; + ddsd.ddsCaps.dwCaps=DDSCAPS_ZBUFFER; + ddsd.dwWidth=elDraw::Width; + ddsd.dwHeight=elDraw::Height; + + memcpy(&ddsd.ddpfPixelFormat,&el4D::Config::ZBuffer,sizeof(DDPIXELFORMAT)); + + if (el4D::Config::Driver&DC4D_HAL) + { + // HALの場合はVRAMに生成 + ddsd.ddsCaps.dwCaps|=DDSCAPS_VIDEOMEMORY; + } + else + { + // HELの場合はRAMに生成 + ddsd.ddsCaps.dwCaps|=DDSCAPS_SYSTEMMEMORY; + } + + ddret=DDObject->CreateSurface(&ddsd,&D3ZBuffer,NULL); + + if (ddret!=DD_OK) + { + return elDraw::Error("el4D::Init", + "Z Bufferが生成できません",ddret); + } + + // Zバッファの接続 + ddret=DDBack->AddAttachedSurface(D3ZBuffer); + + if (ddret!=DD_OK) + { + return elDraw::Error("el4D::Init", + "Z Bufferが接続できません",ddret); + } + + // Direct3D IMの生成 + ddret=D3->CreateDevice(el4D::Config::DriverGUID,DDBack,&D3Device); + + // 生成に失敗した場合 + if (ddret!=D3D_OK) + { + return elDraw::Error("el4D::Init", + "Direct3D IMが使用できません",ddret); + } + + // テクスチャーフォーマットの検索 + Texture::MaxTextureFormat=0; + + D3Device->EnumTextureFormats(SearchTexture,NULL); + + // アルファ付きテクスチャーの検索 + Texture::AlphaTexture=-1; + + for (i=0;i<3;i++) + { + for (j=0;jSetRenderState(D3DRENDERSTATE_FOGVERTEXMODE,D3DFOG_LINEAR); + + // ステートの初期化 + D3Device->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); + D3Device->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE); + D3Device->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE); + + // 画面サイズの初期化 + Width=F(elDraw::Width); + Height=F(elDraw::Height); + + // PPFの初期化 + Ppf=0; + + // 3D環境の初期化 + State::Z(TRUE); + State::Dither(TRUE); + State::Specular(TRUE); + State::Shade(SHADE_GOURAUD); + State::Antialias(FALSE); + State::UseAlpha(USE_MATERIAL); + + Texture::Perspective(TRUE); + Texture::Filter(FILTER_LINEAR,FILTER_LINEAR); + Texture::Transparent(FALSE); + Texture::Atm(TRUE); + + el4D::Clear::View(TRUE); + el4D::Clear::Z(TRUE); + el4D::Clear::Area(); + el4D::Clear::Color(F(0),F(0),F(0)); + + Light::Ambient(F(0.5),F(0.5),F(0.5)); + + #ifdef REPORT + + memset(&RepHal,0x00,sizeof(DDCAPS)); + RepHal.dwSize=sizeof(DDCAPS); + memset(&RepHel,0x00,sizeof(DDCAPS)); + RepHel.dwSize=sizeof(DDCAPS); + DDObject->GetCaps(&RepHal,&RepHel); + + REP_IN + "3D初期化後のVRAM空き = %2.3f MB\n\n",F(RepHal.dwVidMemFree)/F(1024)/F(1024) + REP_OUT + + #endif + + // d3dxof.libへの明示的な参照 + LPDIRECTXFILE XFile=NULL; + if (DirectXFileCreate(&XFile)==DXFILE_OK) XFile->Release(); + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 4Dクラスの環境設定 -*/ +/*- -*/ +/*- ( elDraw::Screen関数の前に使用 ) -*/ +/*- -*/ +/*- WORD Para : 設定内容 -*/ +/*- DC4D_USEHEL = HELを要求 -*/ +/*- DC4D_USERR = リファレンスラスタライザーを要求 -*/ +/*- DC4D_BITEQUAL = カラーとZに同じビット数を要求 -*/ +/*- DC4D_NOTNL = TnLを使わないHALを要求 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::Config(WORD Para) +{ + // HELとリファレンスラスタライザーが同時に要求された場合 + if (Para&DC4D_USEHEL && Para&DC4D_USERR) + { + // HELを無効に設定 + Para^=DC4D_USEHEL; + } + + el4D::Config::User=Para; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 全オブジェクトの破棄 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::DestroyObject(void) +{ + int i; + + // ポリゴンオブジェクトの開放 + for (i=0;iEvictManagedTextures(); + + // Zバッファの開放 + if (D3ZBuffer!=NULL) + { + DDBack->DeleteAttachedSurface(0,D3ZBuffer); + D3ZBuffer->Release(); + D3ZBuffer=NULL; + } + + // Direct3Dの開放 + if (D3Device!=NULL) + { + D3Device->Release(); + D3Device=NULL; + } + + if (D3!=NULL) + { + D3->Release(); + D3=NULL; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ドライバーの検索 ※ 内部で使用 -*/ +/*- -*/ +/*- パラメーター省略 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +CLBKH el4D::SearchDriver(LPSTR Desc,LPSTR Name,D3DDEVICEDESC7* Dev,void* TnL) +{ + DWORD bits; // カラービット + + // 環境データの初期化 + el4D::Config::Driver=0x0000; + el4D::Config::Texture=0x0000; + + // 要求しているドライバー(HAL/HEL)以外の場合 + if (!(el4D::Config::User&DC4D_USEHEL) && !(el4D::Config::User&DC4D_USERR) && + !(Dev->dwDevCaps&D3DDEVCAPS_HWRASTERIZATION) || + el4D::Config::User&DC4D_USEHEL && + Dev->dwDevCaps&D3DDEVCAPS_HWRASTERIZATION || + el4D::Config::User&DC4D_USERR && + Dev->deviceGUID!=IID_IDirect3DRefDevice) + { + // 次のドライバーを検索 + return D3DENUMRET_OK; + } + + // カラービット数の取得 + switch (elDraw::ColorBit) + { + case 16: bits=DDBD_16; break; + case 24: bits=DDBD_24; break; + case 32: bits=DDBD_32; break; + } + + // カラーとZバッファに同じビット数を要求する場合 + if (el4D::Config::User&DC4D_BITEQUAL) + { + // カラービット数とZバッファビット数が一致しない場合、選択しない + if (!(Dev->dwDeviceRenderBitDepth&bits && + Dev->dwDeviceZBufferBitDepth&bits)) + { + return D3DENUMRET_OK; + } + } + + // TnLが使える場合 + if (Dev->dwDevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT) + { + el4D::Config::Driver|=DC4D_TNL; + } + // TnLが要求されている場合 + else if (TnL) + { + // 次のドライバーを検索 + return D3DENUMRET_OK; + } + + // ハードウェアドライバーの場合 + if (Dev->dwDevCaps&D3DDEVCAPS_HWRASTERIZATION) + { + el4D::Config::Driver|=DC4D_HAL; + } + + // 幅と高さに2の累乗を要求する場合 + if (Dev->dpcTriCaps.dwTextureCaps&D3DPTEXTURECAPS_POW2) + { + el4D::Config::Texture|=DC4D_2POWERS; + } + + // 正方形を要求する場合 + if (Dev->dpcTriCaps.dwTextureCaps&D3DPTEXTURECAPS_SQUAREONLY) + { + el4D::Config::Texture|=DC4D_SQUAREONLY; + } + + // アンチエイリアスモードの初期化 + el4D::Config::Antialias=D3DANTIALIAS_NONE; + + // ソート順に依存しないアンチエイリアスが使える場合 + if (Dev->dpcTriCaps.dwRasterCaps&D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT) + { + el4D::Config::Antialias=D3DANTIALIAS_SORTINDEPENDENT; + } + // ソート順に依存するアンチエイリアスが使える場合 + else if (Dev->dpcTriCaps.dwRasterCaps&D3DPRASTERCAPS_ANTIALIASSORTDEPENDENT) + { + el4D::Config::Antialias=D3DANTIALIAS_SORTINDEPENDENT; + } + + // Wバッファが使える場合 + if (Dev->dpcTriCaps.dwRasterCaps&D3DPRASTERCAPS_WBUFFER) + { + el4D::Config::WBuffer=D3DZB_USEW; + } + else + { + el4D::Config::WBuffer=D3DZB_TRUE; + } + + // アルファブレンドモードの初期化 + el4D::Config::AlphaBlendNormal=FALSE; + el4D::Config::AlphaBlendAdd=FALSE; + el4D::Config::AlphaBlendDelete=FALSE; + el4D::Config::AlphaBlendReverse=FALSE; + el4D::Config::AlphaBlendBright=FALSE; + + // 通常のアルファブレンドが使える場合 + if (Dev->dpcTriCaps.dwSrcBlendCaps&D3DPBLENDCAPS_SRCALPHA && + Dev->dpcTriCaps.dwDestBlendCaps&D3DPBLENDCAPS_INVSRCALPHA) + { + el4D::Config::AlphaBlendNormal=TRUE; + } + + // 加算アルファブレンドが使える場合 + if (Dev->dpcTriCaps.dwSrcBlendCaps&D3DPBLENDCAPS_SRCALPHA && + Dev->dpcTriCaps.dwDestBlendCaps&D3DPBLENDCAPS_ONE) + { + el4D::Config::AlphaBlendAdd=TRUE; + } + + // 減算アルファブレンドが使える場合 + if (Dev->dpcTriCaps.dwSrcBlendCaps&D3DPBLENDCAPS_ZERO && + Dev->dpcTriCaps.dwDestBlendCaps&D3DPBLENDCAPS_INVSRCALPHA) + { + el4D::Config::AlphaBlendDelete=TRUE; + } + + // 反転アルファブレンドが使える場合 + if (Dev->dpcTriCaps.dwSrcBlendCaps&D3DPBLENDCAPS_INVDESTCOLOR && + Dev->dpcTriCaps.dwDestBlendCaps&D3DPBLENDCAPS_ZERO) + { + el4D::Config::AlphaBlendReverse=TRUE; + } + + // 明度アルファブレンドが使える場合 + if (Dev->dpcTriCaps.dwSrcBlendCaps&D3DPBLENDCAPS_DESTCOLOR && + Dev->dpcTriCaps.dwDestBlendCaps&D3DPBLENDCAPS_SRCALPHA) + { + el4D::Config::AlphaBlendBright=TRUE; + } + + // テクスチャーのサイズの範囲を取得 + Texture::MinWidth=Dev->dwMinTextureWidth; + Texture::MinHeight=Dev->dwMinTextureHeight; + Texture::MaxWidth=Dev->dwMaxTextureWidth; + Texture::MaxHeight=Dev->dwMaxTextureHeight; + + #ifdef REPORT + + if (el4D::Config::Texture&(DC4D_2POWERS|DC4D_SQUAREONLY)) + { + REP_IN + "テクスチャーの制限 = " + REP_OUT + + if (el4D::Config::Texture&DC4D_2POWERS) + { + REP_IN + "幅と高さは2の累乗" + REP_OUT + } + + if (el4D::Config::Texture&DC4D_SQUAREONLY) + { + if (el4D::Config::Texture&DC4D_2POWERS) + { + REP_IN + "、" + REP_OUT + } + + REP_IN + "正方形" + REP_OUT + } + + REP_IN + "\n" + REP_OUT + } + + REP_IN + "テクスチャーサイズの範囲 = %d,%d 〜 %d,%d\n", + Texture::MinWidth,Texture::MinHeight,Texture::MaxWidth,Texture::MaxHeight + REP_OUT + + if (el4D::Config::AlphaBlendNormal || el4D::Config::AlphaBlendAdd || + el4D::Config::AlphaBlendDelete || el4D::Config::AlphaBlendReverse || + el4D::Config::AlphaBlendBright) + { + REP_IN + "アルファブレンド =" + REP_OUT + + if (el4D::Config::AlphaBlendNormal) { REP_IN " 通常" REP_OUT }; + if (el4D::Config::AlphaBlendAdd) { REP_IN " 加算" REP_OUT }; + if (el4D::Config::AlphaBlendDelete) { REP_IN " 減算" REP_OUT }; + if (el4D::Config::AlphaBlendReverse) { REP_IN " 反転" REP_OUT }; + if (el4D::Config::AlphaBlendBright) { REP_IN " 明度" REP_OUT }; + + REP_IN + "\n" + REP_OUT + } + + #endif + + // ドライバーの決定 + el4D::Config::DriverGUID=Dev->deviceGUID; + el4D::Config::Driver|=DC4D_OK; + + return D3DENUMRET_CANCEL; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- Zバッファの検索 ※ 内部で使用 -*/ +/*- -*/ +/*- パラメーター省略 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +CLBKH el4D::SearchZBuffer(DDPIXELFORMAT* Pf,void* PfData) +{ + if (Pf->dwFlags==DDPF_ZBUFFER) + { + // 要求されたZバッファの場合 + if (!(el4D::Config::User&DC4D_BITEQUAL) || + el4D::Config::User&DC4D_BITEQUAL && + (int)Pf->dwZBufferBitDepth==elDraw::ColorBit) + { + // このZバッファを使用 + memcpy(PfData,Pf,sizeof(DDPIXELFORMAT)); + + // Zバッファビット数に保存 + el4D::Config::ZBit=Pf->dwZBufferBitDepth; + + #ifdef REPORT + + REP_IN + "Zバッファ = %dビット",el4D::Config::ZBit + REP_OUT + + if (el4D::Config::WBuffer==D3DZB_USEW) + { + REP_IN + " / WバッファOK\n" + REP_OUT + } + else + { + REP_IN + "\n" + REP_OUT + } + + #endif + + return D3DENUMRET_CANCEL; + } + } + + return D3DENUMRET_OK; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャーフォーマットの検索 ※ 内部で使用 -*/ +/*- -*/ +/*- パラメーター省略 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +CLBKH el4D::SearchTexture(DDPIXELFORMAT* pf,void*) +{ + // 16ビット未満のフォーマットや特殊フォーマットは未使用 + if (pf->dwRGBBitCount<16 || pf->dwFourCC || pf->dwFlags& + (DDPF_LUMINANCE|DDPF_BUMPLUMINANCE|DDPF_BUMPDUDV|DDPF_PALETTEINDEXED8)) + { + return DDENUMRET_OK; + } + + // テクスチャーフォーマット一覧に保存 + memcpy(&Texture::Format[Texture::MaxTextureFormat],pf,sizeof(DDPIXELFORMAT)); + + if (++Texture::MaxTextureFormat==TEXTURE_MAX) + { + return DDENUMRET_CANCEL; + } + + return DDENUMRET_OK; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 3D処理の開始 ※ el4D::End関数とペアで使用 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常 -*/ +/*- FALSE = 処理不可能 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline BOOL el4D::Start(void) +{ + Texture::LastTexture=0xFFFF; + + el4D::Render::XFileNo=0; + + return D3Device->BeginScene()==D3D_OK; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 3D処理の終了 ※ el4D::Start関数とペアで使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::End(void) +{ + D3Device->EndScene(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ポリゴンオブジェクトのロック -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- DWORD Mode : ロックモード ( DirectXのパラメーターを使用 ) -*/ +/*- 省略 = DDLOCK_WAIT -*/ +/*- -*/ +/*- 戻り値 : TRUE = ロック成功またはロック済 -*/ +/*- FALSE = ロック失敗 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline BOOL el4D::Lock(D4OBJ ObjD4,DWORD Mode=DDLOCK_WAIT) +{ + // まだロックさていない場合 + if (!(++PolyObj[ObjD4].Lock)) + { + // ロックして頂点データを取得 + if (PolyObj[ObjD4].VertexType==D3DFVF_VERTEX) + { + return SUCCEEDED(PolyObj[ObjD4].VertexBuffer->Lock(Mode, + (void**)&PolyObj[ObjD4].Vertex,NULL)); + } + else if (PolyObj[ObjD4].VertexType==D3DFVF_LVERTEX) + { + return SUCCEEDED(PolyObj[ObjD4].VertexBuffer->Lock(Mode, + (void**)&PolyObj[ObjD4].VertexL,NULL)); + } + else if (PolyObj[ObjD4].VertexType==D3DFVF_TLVERTEX) + { + return SUCCEEDED(PolyObj[ObjD4].VertexBuffer->Lock(Mode, + (void**)&PolyObj[ObjD4].VertexTL,NULL)); + } + + return FALSE; + } + // すでにロック済みの場合 + else + { + return TRUE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ポリゴンオブジェクトのロック解除 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Unlock(D4OBJ ObjD4) +{ + // ロックされている場合 + if (!PolyObj[ObjD4].Lock) + { + // ロック解除 + PolyObj[ObjD4].VertexBuffer->Unlock(); + } + + PolyObj[ObjD4].Lock--; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マトリクスの初期化 ( ポリゴンオブジェクト内のマトリクス ) -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::InitMatrix(D4OBJ ObjD4) +{ + PolyObj[ObjD4].Matrix._11=F(1); + PolyObj[ObjD4].Matrix._12=F(0); + PolyObj[ObjD4].Matrix._13=F(0); + PolyObj[ObjD4].Matrix._14=F(0); + PolyObj[ObjD4].Matrix._21=F(0); + PolyObj[ObjD4].Matrix._22=F(1); + PolyObj[ObjD4].Matrix._23=F(0); + PolyObj[ObjD4].Matrix._24=F(0); + PolyObj[ObjD4].Matrix._31=F(0); + PolyObj[ObjD4].Matrix._32=F(0); + PolyObj[ObjD4].Matrix._33=F(1); + PolyObj[ObjD4].Matrix._34=F(0); + PolyObj[ObjD4].Matrix._41=F(0); + PolyObj[ObjD4].Matrix._42=F(0); + PolyObj[ObjD4].Matrix._43=F(0); + PolyObj[ObjD4].Matrix._44=F(1); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マトリクスの初期化 ( 任意のマトリクス ) -*/ +/*- -*/ +/*- D4MTX& MtxD4 : マトリクス情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::InitMatrix(D4MTX& MtxD4) +{ + MtxD4._11=F(1); + MtxD4._12=F(0); + MtxD4._13=F(0); + MtxD4._14=F(0); + MtxD4._21=F(0); + MtxD4._22=F(1); + MtxD4._23=F(0); + MtxD4._24=F(0); + MtxD4._31=F(0); + MtxD4._32=F(0); + MtxD4._33=F(1); + MtxD4._34=F(0); + MtxD4._41=F(0); + MtxD4._42=F(0); + MtxD4._43=F(0); + MtxD4._44=F(1); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- PPF/PPSの表示 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::ShowPPF(void) +{ + static char Buffer[64]; + + if (Ppf>0) Ppf/=3; + + sprintf(Buffer,"%ld ppf ( %ld pps )",Ppf,(long)((float)Ppf*elDraw::FpsData)); + + Ppf=0; + + elFont::Begin(GOTHIC,12,0,FALSE,FALSE,FALSE); + elFont::Color(RGB(255,255,255),RGB(0,0,128),FALSE); + elFont::Draw(0,15,Buffer); + elFont::Before(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- Z値の取得 -*/ +/*- -*/ +/*- int Px : ZバッファX座標 -*/ +/*- int Py : ZバッファY座標 -*/ +/*- -*/ +/*- 戻り値 : Z値 ( DWORD型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline DWORD el4D::GetZ(int Px,int Py) +{ + DDSURFACEDESC ddsd; + LPDWORD data; + + // 構造体の初期化 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + + // Zバッファのロック + if (D3ZBuffer->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL)!=DD_OK) return 0; + + // Z値の取得 + if (el4D::Config::ZBit==16) + { + data=(LPDWORD)((LPWORD)ddsd.lpSurface+Px+Py*(ddsd.lPitch>>1)); + } + else + { + data=(LPDWORD)ddsd.lpSurface+(Px>>1)+Py*(ddsd.lPitch>>2); + } + + // Zバッファのロック解除 + DD_UNLOCK(D3ZBuffer,ddsd.lpSurface); + + return *data; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 3D画面のクリアー -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Clear(void) +{ + D3Device->Clear(el4D::Clear::ClearAreaCount,el4D::Clear::ClearAreaPtr, + el4D::Clear::ClearType,el4D::Clear::ClearColor,F(1),0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 単一オブジェクトをレンダリング -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Render(D4OBJ ObjD4) +{ + // 新たなテクスチャーを必要とする場合 + if (PolyObj[ObjD4].Texture!=el4D::Texture::LastTexture) + { + // テクスチャーの取得 + el4D::Texture::LastTexture=PolyObj[ObjD4].Texture; + + // テクスチャーが存在する場合 + if (el4D::Texture::LastTexture!=-1) + { + // テクスチャー設定 + el4D::Render::SetTexture(el4D::Texture::LastTexture); + } + else + { + // テクスチャーを消去 + el4D::Render::NoTexture(); + } + } + + // マテリアルの設定 + el4D::Render::SetMaterial(ObjD4); + + // レンダリング + el4D::Render::Polygon(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- Xファイルオブジェクトをレンダリング -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// el4D::RenderX関数用のプロトタイプ +void FrameRender(D4OBJ,D4OBJ*,BOOL); + +inline void el4D::RenderX(D4OBJ ObjD4) +{ + D4OBJ NextObjD4; // 次に処理するポリゴンオブジェクト + + // アルファを含まないオブジェクトをレンダリング + NextObjD4=-2; + FrameRender(ObjD4,&NextObjD4,FALSE); + + // アルファを含むオブジェクトをレンダリング + el4D::State::Alpha(ALPHA_NORMAL); + el4D::State::WriteZ(FALSE); + + NextObjD4=-2; + FrameRender(ObjD4,&NextObjD4,TRUE); + + el4D::State::WriteZ(TRUE); + el4D::State::Alpha(ALPHA_NONE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- el4D::RenderX関数用 ( フレーム階層ごとにレンダリング ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void FrameRender(D4OBJ ObjD4,D4OBJ* NextObjD4,BOOL Alpha) +{ + int i; // 汎用カウンター + D4MTX OldMatrix,NewMatrix; // フレーム階層マトリクス + + // ポリゴンデータの場合 + if (PolyObj[ObjD4].VertexType!=POLYOBJ_FRAME) + { + // アルファの有無が一致している場合 + if (PolyObj[ObjD4].Alpha==Alpha) + { + // サブポリゴンが存在しない場合 + if (PolyObj[ObjD4].SubCount==0) + { + // 新たなテクスチャーを必要とする場合 + if (PolyObj[ObjD4].Texture!=el4D::Texture::LastTexture) + { + // テクスチャーの取得 + el4D::Texture::LastTexture=PolyObj[ObjD4].Texture; + + // テクスチャーが存在する場合 + if (el4D::Texture::LastTexture!=-1) + { + // テクスチャー設定 + el4D::Render::SetTexture(el4D::Texture::LastTexture); + } + else + { + // テクスチャーを消去 + el4D::Render::NoTexture(); + } + } + + // マテリアルの設定 + el4D::Render::SetMaterial(ObjD4); + + // レンダリング + el4D::Render::Polygon(ObjD4); + } + // サブポリゴンが存在する場合 + else + { + // 順番にレンダリング + for (i=0;iGetTransform(D3DTRANSFORMSTATE_WORLD,&OldMatrix); + NewMatrix=PolyObj[ObjD4].XFileMatrix*OldMatrix; + if (*NextObjD4!=-2) NewMatrix=PolyObj[ObjD4].ObjectMatrix*NewMatrix; + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD,&NewMatrix); + + // 1つ下の階層をレンダリング + FrameRender(PolyObj[ObjD4].Next,NextObjD4,Alpha); + + // 元のマトリクスを復元 + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD,&OldMatrix); + } + + // 次の階層を処理する場合 + if (PolyObj[*NextObjD4].Parent==PolyObj[ObjD4].Parent) + { + // 処理対象を更新 + ObjD4=*NextObjD4; + + // 次のオブジェクトをレンダリング + FrameRender(ObjD4,NextObjD4,Alpha); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- Xファイルオブジェクトをレンダリング ( アルファなしオブジェクトのみ ) -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// el4D::RenderXList関数用のプロトタイプ +void FrameRender2(D4OBJ,D4OBJ*); + +inline void el4D::RenderXList(D4OBJ ObjD4) +{ + D4OBJ NextObjD4=-2; // 次に処理するポリゴンオブジェクト + + // アルファありオブジェクトをリストに保存しながらレンダリング + FrameRender2(ObjD4,&NextObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- Xファイルオブジェクトをレンダリング ( アルファありオブジェクトのみ ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::RenderXList(void) +{ + int i; // 汎用カウンター + D4OBJ ObjD4; // ポリゴンオブジェクト + + // リストにオブジェクトが存在している場合 + if (el4D::Render::XFileNo>0) + { + el4D::State::Alpha(ALPHA_NORMAL); + el4D::State::WriteZ(FALSE); + + // リストにあるオブジェクトを順番に処理 + for (i=0;iSetTransform(D3DTRANSFORMSTATE_WORLD,&XFile[i].Matrix); + + // 新たなテクスチャーを必要とする場合 + if (PolyObj[ObjD4].Texture!=el4D::Texture::LastTexture) + { + // テクスチャーの取得 + el4D::Texture::LastTexture=PolyObj[ObjD4].Texture; + + // テクスチャーが存在する場合 + if (el4D::Texture::LastTexture!=-1) + { + // テクスチャー設定 + el4D::Render::SetTexture(el4D::Texture::LastTexture); + } + else + { + // テクスチャーを消去 + el4D::Render::NoTexture(); + } + } + + // マテリアルの設定 + el4D::Render::SetMaterial(ObjD4); + + // レンダリング + el4D::Render::Polygon(ObjD4); + } + + el4D::State::WriteZ(TRUE); + el4D::State::Alpha(ALPHA_NONE); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- el4D::RenderXList関数用 ( フレーム階層ごとにレンダリング ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void FrameRender2(D4OBJ ObjD4,D4OBJ* NextObjD4) +{ + int i; // 汎用カウンター + D4MTX OldMatrix,NewMatrix; // フレーム階層マトリクス + + // ポリゴンデータの場合 + if (PolyObj[ObjD4].VertexType!=POLYOBJ_FRAME) + { + // アルファなしの場合 + if (!PolyObj[ObjD4].Alpha) + { + // サブポリゴンが存在しない場合 + if (PolyObj[ObjD4].SubCount==0) + { + // 新たなテクスチャーを必要とする場合 + if (PolyObj[ObjD4].Texture!=el4D::Texture::LastTexture) + { + // テクスチャーの取得 + el4D::Texture::LastTexture=PolyObj[ObjD4].Texture; + + // テクスチャーが存在する場合 + if (el4D::Texture::LastTexture!=-1) + { + // テクスチャー設定 + el4D::Render::SetTexture(el4D::Texture::LastTexture); + } + else + { + // テクスチャーを消去 + el4D::Render::NoTexture(); + } + } + + // マテリアルの設定 + el4D::Render::SetMaterial(ObjD4); + + // レンダリング + el4D::Render::Polygon(ObjD4); + } + // サブポリゴンが存在する場合 + else + { + // 順番にレンダリング + for (i=0;iGetTransform(D3DTRANSFORMSTATE_WORLD, + &XFile[el4D::Render::XFileNo].Matrix); + + el4D::Render::XFileNo++; + } + else + { + elDraw::Error("el4D::RenderXList", + "レンダリングリストが多過ぎます",XFILE_MAX); + } + } + + // 次に処理するポリゴンオブジェクトを更新 + *NextObjD4=PolyObj[ObjD4].Next; + } + // フレームデータの場合 + else + { + // フレーム階層になるようにマトリクスを更新 + D3Device->GetTransform(D3DTRANSFORMSTATE_WORLD,&OldMatrix); + NewMatrix=PolyObj[ObjD4].XFileMatrix*OldMatrix; + if (*NextObjD4!=-2) NewMatrix=PolyObj[ObjD4].ObjectMatrix*NewMatrix; + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD,&NewMatrix); + + // 1つ下の階層をレンダリング + FrameRender2(PolyObj[ObjD4].Next,NextObjD4); + + // 元のマトリクスを復元 + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD,&OldMatrix); + } + + // 次の階層を処理する場合 + if (PolyObj[*NextObjD4].Parent==PolyObj[ObjD4].Parent) + { + // 処理対象を更新 + ObjD4=*NextObjD4; + + // 次のオブジェクトをレンダリング + FrameRender2(ObjD4,NextObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ターゲットの切り換え -*/ +/*- -*/ +/*- D4TXR TxrD4 : テクスチャー情報 -*/ +/*- float Fov : FOV -*/ +/*- 省略 = 変更しない -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Target(D4TXR TxrD4,float Fov=Camera::Fov) +{ + D3DVIEWPORT7 vp; + D4MTX Projection; + + // 指定されたスプライトをレンダリング先に設定 + D3Device->SetRenderTarget(Sprite[TxrD4].Object,0); + + // ビューポートを更新 + memset(&vp,0x00,sizeof(D3DVIEWPORT7)); + + vp.dwX=0; + vp.dwY=0; + vp.dwWidth=Sprite[TxrD4].SizeX; + vp.dwHeight=Sprite[TxrD4].SizeY; + vp.dvMinZ=F(0); + vp.dvMaxZ=F(1); + + D3Device->SetViewport(&vp); + + // 投影を更新 + Projection._12=F(0); + Projection._13=F(0); + Projection._14=F(0); + Projection._21=F(0); + Projection._23=F(0); + Projection._24=F(0); + Projection._31=F(0); + Projection._32=F(0); + Projection._41=F(0); + Projection._42=F(0); + Projection._44=F(0); + + Projection._11=Camera::Aspect*(F(cos(Fov/F(2)))/F(sin(Fov/F(2)))); + Projection._22=F(1)*(F(cos(Fov/F(2)))/F(sin(Fov/F(2)))); + Projection._33=Camera::Far/(Camera::Far-Camera::Near); + Projection._34=F(1); + Projection._43=-(Camera::Far/(Camera::Far-Camera::Near))*Camera::Near; + + D3Device->SetTransform(D3DTRANSFORMSTATE_PROJECTION,&Projection); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ターゲットの復元 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Target(void) +{ + // 裏画面をレンダリング先に設定 + D3Device->SetRenderTarget(DDBack,0); + + // ビューポートと投影を復元 + Camera::Viewport(Camera::Vx1,Camera::Vy1,Camera::Vx2,Camera::Vy2); + Camera::Projection(Camera::Near,Camera::Far,Camera::Aspect,Camera::Fov); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- レンダリング:ポリゴン -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Render::Polygon(D4OBJ ObjD4) +{ + // レンダリング + D3Device->DrawIndexedPrimitiveVB(D3DPT_TRIANGLELIST, + PolyObj[ObjD4].VertexBuffer,0, + PolyObj[ObjD4].VertexCount, + PolyObj[ObjD4].Index, + PolyObj[ObjD4].IndexCount,0); + + // レンダリングポリゴン数に加算 + Ppf+=PolyObj[ObjD4].IndexCount; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- レンダリング:サブポリゴン -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : サブNo -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Render::Polygon(D4OBJ ObjD4,int No) +{ + // レンダリング + D3Device->DrawIndexedPrimitiveVB(D3DPT_TRIANGLELIST, + PolyObj[ObjD4].VertexBuffer,0, + PolyObj[ObjD4].VertexCount, + PolyObj[ObjD4].SubIndex[No], + PolyObj[ObjD4].SubIndexCount[No],0); + + // レンダリングポリゴン数に加算 + Ppf+=PolyObj[ObjD4].SubIndexCount[No]; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- レンダリング:テクスチャー設定 -*/ +/*- -*/ +/*- D4TXR TxrD4 : テクスチャー情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Render::SetTexture(D4TXR TxrD4) +{ + D3Device->SetTexture(0,Sprite[TxrD4].Object); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- レンダリング:テクスチャー消去 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Render::NoTexture(void) +{ + D3Device->SetTexture(0,NULL); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- レンダリング:マテリアル設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Render::SetMaterial(D4OBJ ObjD4) +{ + D3Device->SetMaterial(&PolyObj[ObjD4].Material); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- レンダリング:サブマテリアル設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : サブNo -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Render::SetMaterial(D4OBJ ObjD4,int No) +{ + D3Device->SetMaterial(&PolyObj[ObjD4].SubMaterial[No]); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- レンダリング:影 -*/ +/*- -*/ +/*- D4OBJ ObjD4A : ポリゴンオブジェクト情報 ( 影を生み出す側 ) -*/ +/*- D4OBJ ObjD4B : ポリゴンオブジェクト情報 ( 影になる側 ) -*/ +/*- D4LGT LgtD4 : ライトオブジェクト情報 -*/ +/*- BYTE Type : 影の方向 -*/ +/*- 省略/SHADOW_BOTTOM = 下 -*/ +/*- SHADOW_TOP = 上 -*/ +/*- SHADOW_FRONT = 前 -*/ +/*- SHADOW_BACK = 後 -*/ +/*- SHADOW_LEFT = 左 -*/ +/*- SHADOW_RIGHT = 右 -*/ +/*- SHADOW_VERTICAL = 垂直 -*/ +/*- SHADOW_HORIZONTAL = 水平 -*/ +/*- SHADOW_ALL = 前面 -*/ +/*- float Dist : 影までの距離 -*/ +/*- 省略 = 0 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// 影の方向 +const BYTE SHADOW_TOP=0x01; // 上 +const BYTE SHADOW_BOTTOM=0x02; // 下 +const BYTE SHADOW_FRONT=0x04; // 前 +const BYTE SHADOW_BACK=0x08; // 後 +const BYTE SHADOW_LEFT=0x10; // 左 +const BYTE SHADOW_RIGHT=0x20; // 右 + +const BYTE SHADOW_VERTICAL=SHADOW_FRONT|SHADOW_BACK| + SHADOW_LEFT|SHADOW_RIGHT; // 垂直 +const BYTE SHADOW_HORIZONTAL=SHADOW_TOP|SHADOW_BOTTOM; // 水平 +const BYTE SHADOW_ALL=SHADOW_VERTICAL|SHADOW_HORIZONTAL; // 全面 + +inline void el4D::Render::Shadow(D4OBJ ObjD4A,D4OBJ ObjD4B,D4LGT LgtD4, + BYTE Type=SHADOW_BOTTOM,float Dist=F(0)) +{ + static int i,j; // 汎用カウンター + static int v; // 頂点の数 + static float vx,vy,vz; // 影になる頂点の位置 + static float lx,ly,lz,llx,lly,llz; // ライトの方向 + static BYTE check,type; // 面チェック + + // 影用にステート変更 + State::WriteZ(FALSE); + State::Alpha(ALPHA_DELETE); + + // ポリゴン面との接触を防ぐ + Dist-=F(0.05); + + // 面ごとに影を生成 + for (i=0,check=0x01;i<6;i++,check<<=1) + { + type=Type✓ + if (!type) continue; + + // 点光源の場合 + if (LightObj[LgtD4].Data.dltType==D3DLIGHT_POINT) + { + // ライト位置から影を生成 + lx=LightObj[LgtD4].Data.dvPosition.x; + ly=LightObj[LgtD4].Data.dvPosition.y; + lz=LightObj[LgtD4].Data.dvPosition.z; + } + else + { + // ライト方向から影を生成 + lx=-LightObj[LgtD4].Data.dvDirection.x; + ly=-LightObj[LgtD4].Data.dvDirection.y; + lz=-LightObj[LgtD4].Data.dvDirection.z; + } + + // 方向ごとに影の位置を算出 + switch (type) + { + case SHADOW_TOP: + ly-=Dist; + break; + case SHADOW_BOTTOM: + ly+=Dist; + break; + case SHADOW_FRONT: + lz+=Dist; + break; + case SHADOW_BACK: + lz-=Dist; + break; + case SHADOW_LEFT: + lx+=Dist; + break; + case SHADOW_RIGHT: + lx-=Dist; + break; + } + + // 消去すべき頂点をカウント + v=0; + + if (el4D::Lock(ObjD4A,DDLOCK_READONLY)) + { + if (el4D::Lock(ObjD4B,DDLOCK_WRITEONLY)) + { + // 頂点単位で処理 + for (j=0;jSetTransform(D3DTRANSFORMSTATE_WORLD, + &PolyObj[ObjD4A].ObjectMatrix); + D3Device->MultiplyTransform(D3DTRANSFORMSTATE_WORLD, + &PolyObj[ObjD4B].Matrix); + D3Device->GetTransform(D3DTRANSFORMSTATE_WORLD, + &PolyObj[ObjD4B].ObjectMatrix); + + vx=PolyObj[ObjD4B].ObjectMatrix._41; + vy=PolyObj[ObjD4B].ObjectMatrix._42; + vz=PolyObj[ObjD4B].ObjectMatrix._43; + + // 頂点の移動 + switch (type) + { + case SHADOW_TOP: + { + vy-=Dist; + + if (vy>=F(0)) + { + Vertex::Move(ObjD4B,j, + PolyObj[ObjD4A].ObjectMatrix._41, + Dist, + PolyObj[ObjD4A].ObjectMatrix._43); + + continue; + } + + break; + } + + case SHADOW_BOTTOM: + { + vy+=Dist; + + if (vy<=F(0)) + { + Vertex::Move(ObjD4B,j, + PolyObj[ObjD4A].ObjectMatrix._41, + -Dist, + PolyObj[ObjD4A].ObjectMatrix._43); + + continue; + } + + break; + } + + case SHADOW_FRONT: + { + vz+=Dist; + + if (vz<=F(0)) + { + Vertex::Move(ObjD4B,j, + PolyObj[ObjD4A].ObjectMatrix._41, + PolyObj[ObjD4A].ObjectMatrix._42, + -Dist); + + continue; + } + + break; + } + + case SHADOW_BACK: + { + vz-=Dist; + + if (vz>=F(0)) + { + Vertex::Move(ObjD4B,j, + PolyObj[ObjD4A].ObjectMatrix._41, + PolyObj[ObjD4A].ObjectMatrix._42, + Dist); + + continue; + } + + break; + } + + case SHADOW_LEFT: + { + vx+=Dist; + + if (vx<=F(0)) + { + Vertex::Move(ObjD4B,j,-Dist, + PolyObj[ObjD4A].ObjectMatrix._42, + PolyObj[ObjD4A].ObjectMatrix._43); + + continue; + } + + break; + } + + case SHADOW_RIGHT: + { + vx-=Dist; + + if (vx>=F(0)) + { + Vertex::Move(ObjD4B,j,Dist, + PolyObj[ObjD4A].ObjectMatrix._42, + PolyObj[ObjD4A].ObjectMatrix._43); + + continue; + } + + break; + } + } + + // 影の位置を算出 + llx=lx-vx; + lly=ly-vy; + llz=lz-vz; + + // 影の位置へ頂点を移動 + switch (type) + { + case SHADOW_TOP: + { + if (lly>F(-0.01)) + { + lly=F(-0.01); + v++; + } + + Vertex::Move(ObjD4B,j,vx-(vy/lly)*llx,Dist, + vz-(vy/lly)*llz); + + break; + } + + case SHADOW_BOTTOM: + { + if (llyF(-0.01)) + { + llz=F(-0.01); + v++; + } + + Vertex::Move(ObjD4B,j,vx-(vz/llz)*llx,vy-(vz/llz)*lly, + Dist); + + break; + } + + case SHADOW_LEFT: + { + if (llxF(-0.01)) + { + llx=F(-0.01); + v++; + } + + Vertex::Move(ObjD4B,j,Dist,vy-(vx/llx)*lly, + vz-(vx/llx)*llz); + + break; + } + } + } + + el4D::Unlock(ObjD4B); + } + + el4D::Unlock(ObjD4A); + } + + // 処理すべき頂点がある場合 + if (v!=j) + { + // 影のレンダリング + InitMatrix(ObjD4B); + + el4D::Transform::P(ObjD4B); + el4D::Object::StaticTransform(ObjD4B); + el4D::Render(ObjD4B); + } + } + + // 影を生み出すオブジェクトの復元 + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4A].ObjectMatrix); + + // ステートの復元 + State::WriteZ(TRUE); + State::Alpha(ALPHA_NONE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- レンダリング:反射 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- BYTE Type : 反射の方向 -*/ +/*- 省略/REFLECT_BOTTOM = 下 -*/ +/*- REFLECT_TOP = 上 -*/ +/*- REFLECT_FRONT = 前 -*/ +/*- REFLECT_BACK = 後 -*/ +/*- REFLECT_LEFT = 左 -*/ +/*- REFLECT_RIGHT = 右 -*/ +/*- REFLECT_VERTICAL = 垂直 -*/ +/*- REFLECT_HORIZONTAL = 水平 -*/ +/*- REFLECT_ALL = 前面 -*/ +/*- float Dist : 反射までの距離 -*/ +/*- 省略 = 0 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// 反射の方向 +const BYTE REFLECT_TOP=0x01; // 上 +const BYTE REFLECT_BOTTOM=0x02; // 下 +const BYTE REFLECT_FRONT=0x04; // 前 +const BYTE REFLECT_BACK=0x08; // 後 +const BYTE REFLECT_LEFT=0x10; // 左 +const BYTE REFLECT_RIGHT=0x20; // 右 + +const BYTE REFLECT_VERTICAL=REFLECT_FRONT|REFLECT_BACK| + REFLECT_LEFT|REFLECT_RIGHT; // 垂直 +const BYTE REFLECT_HORIZONTAL=REFLECT_TOP|REFLECT_BOTTOM; // 水平 +const BYTE REFLECT_ALL=REFLECT_VERTICAL|REFLECT_HORIZONTAL; // 全面 + +inline void el4D::Render::Reflect(D4OBJ ObjD4,BYTE Type=REFLECT_BOTTOM, + float Dist=F(0)) +{ + static int i; // 汎用カウンター + static BYTE check,type; // 面チェック + + // 反射用にステート変更 + State::CheckZ(Z_GREATEREQUAL); + State::WriteZ(FALSE); + State::Reverse(TRUE); + State::Alpha(ALPHA_NORMAL); + + // 面ごとに反射 + for (i=0,check=0x01;i<6;i++,check<<=1) + { + type=Type✓ + if (!type) continue; + + // カメラを反転 + mat1=Camera::ViewMatrix; + + switch (type) + { + case REFLECT_TOP: + case REFLECT_BOTTOM: + { + mat1._21=-mat1._21; + mat1._22=-mat1._22; + mat1._23=-mat1._23; + + break; + } + + case REFLECT_FRONT: + case REFLECT_BACK: + { + mat1._31=-mat1._31; + mat1._32=-mat1._32; + mat1._33=-mat1._33; + + break; + } + + case REFLECT_LEFT: + case REFLECT_RIGHT: + { + mat1._11=-mat1._11; + mat1._12=-mat1._12; + mat1._13=-mat1._13; + + break; + } + } + + D3Device->SetTransform(D3DTRANSFORMSTATE_VIEW,&mat1); + + // 頂点用のマトリクスを初期化 + mat1._11=F(1); + mat1._12=F(0); + mat1._13=F(0); + mat1._14=F(0); + mat1._21=F(0); + mat1._22=F(1); + mat1._23=F(0); + mat1._24=F(0); + mat1._31=F(0); + mat1._32=F(0); + mat1._33=F(1); + mat1._34=F(0); + mat1._41=F(0); + mat1._42=F(0); + mat1._43=F(0); + mat1._44=F(1); + + // 鏡面の反対側へ反射 + switch (type) + { + case REFLECT_TOP: + { + mat1._42=Dist*F(-2); + + break; + } + + case REFLECT_BOTTOM: + { + mat1._42=Dist*F(2); + + break; + } + + case REFLECT_FRONT: + { + mat1._43=Dist*F(-2); + + break; + } + + case REFLECT_BACK: + { + mat1._43=Dist*F(2); + + break; + } + + case REFLECT_LEFT: + { + mat1._41=Dist*F(2); + + break; + } + + case REFLECT_RIGHT: + { + mat1._41=Dist*F(-2); + + break; + } + } + + D3Device->MultiplyTransform(D3DTRANSFORMSTATE_VIEW,&mat1); + + // 反射のレンダリング + el4D::Render(ObjD4); + } + + // カメラの復元 + D3Device->SetTransform(D3DTRANSFORMSTATE_VIEW,&Camera::ViewMatrix); + + // ステートの復元 + State::CheckZ(Z_DEFAULT); + State::WriteZ(TRUE); + State::Reverse(FALSE); + State::Alpha(ALPHA_NONE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- クリアー:背景色の設定 -*/ +/*- -*/ +/*- float R : 赤の強さ ( 0.0〜1.0 ) -*/ +/*- float G : 緑の強さ ( 0.0〜1.0 ) -*/ +/*- float B : 青の強さ ( 0.0〜1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Clear::Color(float R,float G,float B) +{ + ClearColor=D3DRGB(R,G,B); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- クリアー:処理対象エリアの設定 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Clear::Area(int X1,int Y1,int X2,int Y2) +{ + ClearArea.x1=X1; + ClearArea.y1=Y1; + ClearArea.x2=X2; + ClearArea.y2=Y2; + + ClearAreaPtr=&ClearArea; + ClearAreaCount=1; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- クリアー:処理対象エリアをビューポート全体に設定 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Clear::Area(void) +{ + ClearAreaPtr=NULL; + ClearAreaCount=0; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- クリアー:ビュークリアーの設定 -*/ +/*- -*/ +/*- BOOL Flag : TRUE = ビューをクリアーする -*/ +/*- FALSE = ビューをクリアーしない -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Clear::View(BOOL Flag) +{ + ClearType&=~D3DCLEAR_TARGET; + ClearType|=D3DCLEAR_TARGET*(Flag==TRUE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- クリアー:Zバッファクリアーの設定 -*/ +/*- -*/ +/*- BOOL Flag : TRUE = Zバッファをクリアーする -*/ +/*- FALSE = Zバッファをクリアーしない -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Clear::Z(BOOL Flag) +{ + ClearType&=~D3DCLEAR_ZBUFFER; + ClearType|=D3DCLEAR_ZBUFFER*(Flag==TRUE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:削除してメモリから開放 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::Object::Free(D4OBJ ObjD4) +{ + int i,j; // 汎用カウンター + D4OBJ Next; // 次に処理するポリゴンオブジェクト情報 + + while (TRUE) + { + // 次に処理するポリゴンオブジェクト情報を取得 + Next=PolyObj[ObjD4].Next; + + // 頂点関係 + if (PolyObj[ObjD4].VertexBuffer) PolyObj[ObjD4].VertexBuffer->Release(); + if (PolyObj[ObjD4].Index) GlobalFree((HGLOBAL)PolyObj[ObjD4].Index); + + PolyObj[ObjD4].VertexType=0; + PolyObj[ObjD4].VertexBuffer=NULL; + PolyObj[ObjD4].Vertex=NULL; + PolyObj[ObjD4].VertexL=NULL; + PolyObj[ObjD4].VertexTL=NULL; + PolyObj[ObjD4].Index=NULL; + PolyObj[ObjD4].VertexCount=0; + PolyObj[ObjD4].IndexCount=0; + + // 座標/サイズ/フラグ関係 + PolyObj[ObjD4].Px=F(0); + PolyObj[ObjD4].Py=F(0); + PolyObj[ObjD4].Pz=F(0); + PolyObj[ObjD4].Ax=F(0); + PolyObj[ObjD4].Ay=F(0); + PolyObj[ObjD4].Az=F(0); + PolyObj[ObjD4].Sx=F(1); + PolyObj[ObjD4].Sy=F(1); + PolyObj[ObjD4].Sz=F(1); + PolyObj[ObjD4].Texture=-1; + PolyObj[ObjD4].Lock=-1; + PolyObj[ObjD4].Parent=-1; + PolyObj[ObjD4].Next=-1; + PolyObj[ObjD4].Prev=-1; + PolyObj[ObjD4].Alpha=FALSE; + PolyObj[ObjD4].SubCount=0; + + PolyObj[ObjD4].PosX=F(0); + PolyObj[ObjD4].PosY=F(0); + PolyObj[ObjD4].PosZ=F(0); + PolyObj[ObjD4].MinX=F(0); + PolyObj[ObjD4].MinY=F(0); + PolyObj[ObjD4].MinZ=F(0); + PolyObj[ObjD4].MaxX=F(0); + PolyObj[ObjD4].MaxY=F(0); + PolyObj[ObjD4].MaxZ=F(0); + + PolyObj[ObjD4].PiPx=F(0); + PolyObj[ObjD4].PiPy=F(0); + PolyObj[ObjD4].PiSx=F(0); + PolyObj[ObjD4].PiSy=F(0); + + // マトリクス関係 + el4D::InitMatrix(ObjD4); + + PolyObj[ObjD4].ObjectMatrix=PolyObj[ObjD4].Matrix; + PolyObj[ObjD4].XFileMatrix=PolyObj[ObjD4].Matrix; + + // マテリアル関係 + memset(&PolyObj[ObjD4].Material,0x00,sizeof(D3DMATERIAL7)); + + el4D::Material::Ambient(ObjD4,F(0.5),F(0.5),F(0.5)); + el4D::Material::Color(ObjD4,F(1),F(1),F(1)); + el4D::Material::Specular(ObjD4,F(1),F(1),F(1)); + el4D::Material::Power(ObjD4,F(0.5)); + el4D::Material::Emissive(ObjD4,F(0),F(0),F(0)); + el4D::Material::Alpha(ObjD4,F(1)); + + // サブポリゴン関係 + for (i=0;iRegisterTemplates((LPVOID)D3DRM_XTEMPLATES, + D3DRM_XTEMPLATE_BYTES)!=DXFILE_OK) break; + + // ファイルからオブジェクトの検索開始 + if (XFile->CreateEnumObject((LPVOID)Buffer,DXFILELOAD_FROMFILE, + &XEnum)!=DXFILE_OK) + { + // リソースからオブジェクトの検索開始 + XRes.hModule=NULL; + XRes.lpName=(LPCTSTR)FileName; + XRes.lpType=(LPCTSTR)"XFILE"; + + if (XFile->CreateEnumObject((LPVOID)&XRes,DXFILELOAD_FROMRESOURCE, + &XEnum)!=DXFILE_OK) + { + if (XEnum) XEnum->Release(); + if (XFile) XFile->Release(); + + return (D4OBJ)elDraw::Error("el4D::Object::Load", + "Xファイルが見つかりません"); + } + } + + // ループしてオブジェクトを検索 + while (XEnum->GetNextDataObject(&XData)==DXFILE_OK) + { + // テンプレート名の取得 + if (XData->GetType(&Type)!=DXFILE_OK) break; + + // フレームデータの場合 + if (*Type==TID_D3DRMFrame) + { + RetObjD4=LoadFrame(XData,ObjD4,&PrevObjD4); + + // 先頭のポリゴンオブジェクトを保存 + if (ObjD4==-1) ObjD4=RetObjD4; + } + // メッシュデータの場合 + else if (*Type==TID_D3DRMMesh) + { + RetObjD4=LoadMesh(XData,ObjD4,&PrevObjD4); + + // 先頭のポリゴンオブジェクトを保存 + if (ObjD4==-1) ObjD4=RetObjD4; + } + + XData->Release(); + } + + break; + } + + if (XEnum) XEnum->Release(); + if (XFile) XFile->Release(); + + // 正常に読み込めなかった場合 + if (ObjD4==-1) + { + return (D4OBJ)elDraw::Error("el4D::Object::Load", + "Xファイルを読み込めません"); + } + + return ObjD4; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- el4D::Object::Load関数用 ( フレームの読み込み ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D4OBJ LoadFrame(LPDIRECTXFILEDATA XData,D4OBJ ParentObjD4,D4OBJ* PrevObjD4) +{ + int i; + D4OBJ ObjD4=-1; + LPDIRECTXFILEDATA XChildData; + LPDIRECTXFILEOBJECT XChildObject; + long Data; + DWORD Size; + const GUID *Type; + + // 使用可能なポリゴンオブジェクトの検索 + for (i=0;iGetNextObject(&XChildObject)==DXFILE_OK) + { + if (XChildObject->QueryInterface(IID_IDirectXFileData, + (void**)&XChildData)==DXFILE_OK) + { + // テンプレート名の取得 + if (XChildData->GetType(&Type)!=DXFILE_OK) break; + + // フレームデータの場合 + if (*Type==TID_D3DRMFrame) + { + LoadFrame(XChildData,ObjD4,PrevObjD4); + } + + // メッシュデータの場合 + if (*Type==TID_D3DRMMesh) + { + LoadMesh(XChildData,ObjD4,PrevObjD4); + } + + // マトリクスデータの場合 + if (*Type==TID_D3DRMFrameTransformMatrix) + { + // データの読み込み + if (XChildData->GetData(NULL,&Size,(void**)&Data)!=DXFILE_OK) + { + break; + } + + // マトリクスの読み込み + if (Size==sizeof(D3DMATRIX)) + { + PolyObj[ObjD4].XFileMatrix=*((D4MTX*)Data); + + PolyObj[ObjD4].XFileMatrix._13*=F(-1); + PolyObj[ObjD4].XFileMatrix._31*=F(-1); + PolyObj[ObjD4].XFileMatrix._23*=F(-1); + PolyObj[ObjD4].XFileMatrix._32*=F(-1); + PolyObj[ObjD4].XFileMatrix._43*=F(-1); + } + } + + XChildData->Release(); + } + + XChildObject->Release(); + } + + return ObjD4; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- el4D::Object::Load関数用 ( メッシュの読み込み ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D4OBJ LoadMesh(LPDIRECTXFILEDATA XData,D4OBJ ParentObjD4,D4OBJ* PrevObjD4) +{ + int i,j,k; + D4OBJ ObjD4=-1; + LPDIRECTXFILEDATA XChildData,XChildData2; + LPDIRECTXFILEOBJECT XChildObject,XChildObject2; + LPDIRECTXFILEDATAREFERENCE XRef; + D3DVECTOR* Vertex; + DWORD FaceCount,FaceCount2; + DWORD *Face,*Face2; + D3DVECTOR *Normal,*Normal2; + DWORD NormalCount; + DWORD CoordCount; + float* Coord; + DWORD MaterialCount,MaterialFace; + DWORD* FaceData; + DWORD Mc,Mf; + int MaterialNo; + int IndexNo; + D3DVECTOR *v1,*v2,*v3,n; + WORD a,b,c; + long Data; + DWORD Size; + const GUID *Type,*Type2; + + // 使用可能なポリゴンオブジェクトの検索 + for (i=0;iGetData(NULL,&Size,(void**)&Data)!=DXFILE_OK) return FALSE; + + // ポリゴンオブジェクト情報の取得 + PolyObj[ObjD4].VertexType=D3DFVF_VERTEX; + + PolyObj[ObjD4].VertexCount=*((DWORD*)Data); + Data+=4; + + Vertex=((D3DVECTOR*)Data); + Data+=PolyObj[ObjD4].VertexCount*12; + + FaceCount=*((DWORD*)Data); + FaceCount2=FaceCount; + Data+=4; + + Face=(DWORD*)Data; + + PolyObj[ObjD4].IndexCount=0; + + while (FaceCount-->0) + { + PolyObj[ObjD4].IndexCount+=(*Face-2)*3; + Face+=*Face+1; + } + + // 頂点バッファの生成 + el4D::Object::CreateVertexBuffer(ObjD4); + + // 頂点の読み込み + if (el4D::Lock(ObjD4)) + { + for (i=0;ix=(Vertex+i)->x; + (PolyObj[ObjD4].Vertex+i)->y=(Vertex+i)->y; + (PolyObj[ObjD4].Vertex+i)->z=(Vertex+i)->z; + } + + el4D::Unlock(ObjD4); + } + + // インデックスの読み込み + Face=(DWORD*)Data; + + i=0; + + while (FaceCount2--) + { + j=*Face++; + + for (k=2;kGetNextObject(&XChildObject)==DXFILE_OK) + { + if (XChildObject->QueryInterface(IID_IDirectXFileData,(void**)&XChildData) + ==DXFILE_OK) + { + // テンプレート名の取得 + if (XChildData->GetType(&Type)!=DXFILE_OK) break; + + // データの読み込み + if (XChildData->GetData(NULL,&Size,(void**)&Data)!=DXFILE_OK) break; + + // マテリアルリストの場合 + if (*Type==TID_D3DRMMeshMaterialList) + { + // マテリアル情報の取得 + MaterialCount=*((DWORD*)Data); + Data+=4; + MaterialFace=*((DWORD*)Data); + Data+=4; + FaceData=(DWORD*)Data; + + // 1つのメッシュに複数のマテリアルが存在する場合 + if (MaterialCount>1) + { + // サブインデックス数をカウント開始 + IndexNo=0; + + // 各マテリアルごとに保存 + for (Mc=0;Mc0)*1; + + // ループしてオブジェクトを検索 + while (XChildData->GetNextObject(&XChildObject2)==DXFILE_OK) + { + // メッシュ1つ当たりのマテリアル数が多過ぎる場合 + if (++MaterialNo==SUBPOLY_MAX) + { + XChildObject2->Release(); + XChildData->Release(); + XChildObject->Release(); + + return (D4OBJ)elDraw::Error("el4D::Object::Load", + "マテリアル数が多過ぎます"); + } + + // データ参照オブジェクトが見つかった場合 + if (XChildObject2->QueryInterface( + IID_IDirectXFileDataReference,(void**)&XRef)==DXFILE_OK) + { + // データ参照できた場合 + if (XRef->Resolve(&XChildData2)==DXFILE_OK) + { + // テンプレート名の取得 + if (XChildData2->GetType(&Type2)!=DXFILE_OK) break; + + // マテリアルデータの場合 + if (*Type2==TID_D3DRMMaterial) + { + LoadMaterial(XChildData2,ObjD4,MaterialNo); + } + + XChildData2->Release(); + } + + XRef->Release(); + } + + // データオブジェクトが見つかった場合 + if (XChildObject2->QueryInterface(IID_IDirectXFileData, + (void**)&XChildData2)==DXFILE_OK) + { + // テンプレート名の取得 + if (XChildData2->GetType(&Type2)!=DXFILE_OK) break; + + // マテリアルデータの場合 + if (*Type2==TID_D3DRMMaterial) + { + LoadMaterial(XChildData2,ObjD4,MaterialNo); + } + + XChildData2->Release(); + } + + XChildObject2->Release(); + } + } + + // 法線データの場合 + if (*Type==TID_D3DRMMeshNormals) + { + // 法線の読み込み + NormalCount=*((DWORD*)Data); + Normal=(D3DVECTOR*)(Data+4); + + if (NormalCount==(DWORD)PolyObj[ObjD4].VertexCount) + { + if (el4D::Lock(ObjD4)) + { + for (i=0;inx=Normal[i].x; + (PolyObj[ObjD4].Vertex+i)->ny=Normal[i].y; + (PolyObj[ObjD4].Vertex+i)->nz=Normal[i].z; + } + + el4D::Unlock(ObjD4); + } + } + + Normal2=(D3DVECTOR*)GlobalAlloc(GMEM_FIXED,sizeof(D3DVERTEX)* + PolyObj[ObjD4].VertexCount); + + if (Normal2) + { + memset(Normal2,0x00, + sizeof(D3DVECTOR)*PolyObj[ObjD4].VertexCount); + + if (el4D::Lock(ObjD4)) + { + for (i=0;inx=Normal2[i].x; + (PolyObj[ObjD4].Vertex+i)->ny=Normal2[i].y; + (PolyObj[ObjD4].Vertex+i)->nz=Normal2[i].z; + } + + el4D::Unlock(ObjD4); + } + + GlobalFree((HGLOBAL)Normal2); + } + } + + // テクスチャー座標データの場合 + if (*Type==TID_D3DRMMeshTextureCoords) + { + // テクスチャー座標の読み込み + CoordCount=*((DWORD*)Data); + Coord=(float*)(Data+4); + + if (el4D::Lock(ObjD4)) + { + for (i=0;itu=Coord[2*i+0]; + (PolyObj[ObjD4].Vertex+i)->tv=Coord[2*i+1]; + + for (j=0;jRelease(); + } + + XChildObject->Release(); + } + + return ObjD4; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- el4D::Object::Load関数用 ( マテリアルの読み込み ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void LoadMaterial(LPDIRECTXFILEDATA XData,D4OBJ ObjD4,int No) +{ + int i; + D4TXR TxrD4; + long Data; + DWORD Size; + LPDIRECTXFILEDATA XChildData; + LPDIRECTXFILEOBJECT XChildObject; + D3DMATERIAL7 Material; + TCHAR** Name; + const GUID *Type; + char Buffer[256]; + + // データの読み込み + if (XData->GetData(NULL,&Size,(void**)&Data)!=DXFILE_OK) return; + + // マテリアルの初期化 + memset(&Material,0x00,sizeof(D3DMATERIAL7)); + + // マテリアルの読み込み + memcpy(&Material.diffuse,(void*)(Data+0),sizeof(float)*4); + memcpy(&Material.ambient,(void*)(Data+0),sizeof(float)*4); + memcpy(&Material.power,(void*)(Data+16),sizeof(float)*1); + memcpy(&Material.specular,(void*)(Data+20),sizeof(float)*3); + memcpy(&Material.emissive,(void*)(Data+32),sizeof(float)*3); + + // アルファが存在する場合 + if (Material.diffuse.aGetNextObject(&XChildObject)==DXFILE_OK) + { + if (XChildObject->QueryInterface(IID_IDirectXFileData,(void**)&XChildData) + ==DXFILE_OK) + { + // テンプレート名の取得 + if (XChildData->GetType(&Type)!=DXFILE_OK) + { + XChildData->Release(); + XChildObject->Release(); + + return; + } + + // テクスチャーファイル名の場合 + if (*Type==TID_D3DRMTextureFilename) + { + // データの読み込み + if (XChildData->GetData(NULL,&Size,(void**)&Name)!=DXFILE_OK) + { + XChildData->Release(); + XChildObject->Release(); + + return; + } + + // テクスチャーの読み込み + lstrcpyn(Buffer,*Name,256); + TxrD4=el4D::Texture::Load(Buffer,0); + + // テクスチャーの貼り付け + if (No==-1) + { + // メインテクスチャー + el4D::Texture::Set(ObjD4,TxrD4); + + // マルチマテリアルに保存 + for (i=0;iRelease(); + } + + XChildObject->Release(); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:頂点バッファを生成 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL el4D::Object::CreateVertexBuffer(D4OBJ ObjD4) +{ + int i; // 汎用カウンター + + // まだ頂点バッファを生成していない場合 + if (!PolyObj[ObjD4].VertexBuffer) + { + HRESULT ret; + D3DVERTEXBUFFERDESC vbd; + + memset(&vbd,0x00,sizeof(D3DVERTEXBUFFERDESC)); + vbd.dwSize=sizeof(D3DVERTEXBUFFERDESC); + vbd.dwFVF=PolyObj[ObjD4].VertexType; + vbd.dwNumVertices=PolyObj[ObjD4].VertexCount; + + // RAMが指定されたかTnL以外の場合 + if (el4D::Config::VertexBuffer&MEM_RAM || + !(el4D::Config::Driver&DC4D_TNL)) + { + // RAMに生成 + vbd.dwCaps|=D3DVBCAPS_SYSTEMMEMORY; + } + + // レンダリング速度優先の場合 + if (el4D::Config::VertexBuffer&MEM_RENDER) + { + // レンダリングと書き込みに最適化されたメモリに生成 + vbd.dwCaps|=D3DVBCAPS_WRITEONLY; + } + + // レンダリング用に頂点バッファの生成 + ret=D3->CreateVertexBuffer(&vbd,&PolyObj[ObjD4].VertexBuffer,0); + + if (FAILED(ret)) + { + return elDraw::Error("el4D::CreateVertexBuffer", + "頂点バッファを生成できません",ret); + } + + PolyObj[ObjD4].Index=(WORD*)GlobalAlloc(GMEM_FIXED,sizeof(WORD)* + PolyObj[ObjD4].IndexCount); + + // マルチマテリアル用のUVエリアを生成 + for (i=0;iSetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].Matrix); + D3Device->GetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].ObjectMatrix); + + InitMatrix(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:マトリクス変換 ( 動的 ) -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Object::DynamicTransform(D4OBJ ObjD4) +{ + D3Device->MultiplyTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].Matrix); + D3Device->GetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].ObjectMatrix); + + InitMatrix(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:すでに変換されたマトリクスを読み込み -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Object::LoadMatrix(D4OBJ ObjD4) +{ + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].ObjectMatrix); + + InitMatrix(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:任意のマトリクス情報を設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- D4MTX& MtxD4 : マトリクス情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Object::SetMatrix(D4OBJ ObjD4,D4MTX& MtxD4) +{ + PolyObj[ObjD4].ObjectMatrix=MtxD4; + + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].ObjectMatrix); + + InitMatrix(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:変換されたマトリクス情報の取得 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*- 戻り値 : マトリクス情報 ( D4MTX型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline D4MTX& el4D::Object::GetMatrix(D4OBJ ObjD4) +{ + return PolyObj[ObjD4].ObjectMatrix; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:物理的に頂点を移動 -*/ +/*- -*/ +/*- ※ el4D::Object::StaticTransform関数、DynamicTransform関数の後に使用 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Object::ForceVertex(D4OBJ ObjD4) +{ + static int i; + + // 頂点用のマトリクスを初期化 + mat1._11=F(1); + mat1._12=F(0); + mat1._13=F(0); + mat1._14=F(0); + mat1._21=F(0); + mat1._22=F(1); + mat1._23=F(0); + mat1._24=F(0); + mat1._31=F(0); + mat1._32=F(0); + mat1._33=F(1); + mat1._34=F(0); + mat1._44=F(1); + + // 頂点単位で処理 + for (i=0;iSetTransform(D3DTRANSFORMSTATE_WORLD, + &PolyObj[ObjD4].ObjectMatrix); + D3Device->MultiplyTransform(D3DTRANSFORMSTATE_WORLD,&mat1); + D3Device->GetTransform(D3DTRANSFORMSTATE_WORLD,&mat1); + + // 新しい位置へ頂点を移動 + Vertex::Move(ObjD4,i,mat1._41,mat1._42,mat1._43); + } + + // オブジェクト情報の初期化 + PolyObj[ObjD4].Px=F(0); + PolyObj[ObjD4].Py=F(0); + PolyObj[ObjD4].Pz=F(0); + PolyObj[ObjD4].Ax=F(0); + PolyObj[ObjD4].Ay=F(0); + PolyObj[ObjD4].Az=F(0); + PolyObj[ObjD4].Sx=F(1); + PolyObj[ObjD4].Sy=F(1); + PolyObj[ObjD4].Sz=F(1); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:UV値加算 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float Tu : テクスチャーのU座標 -*/ +/*- float Tv : テクスチャーのV座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Object::AddUV(D4OBJ ObjD4,float Tu,float Tv) +{ + static int i; + + if (el4D::Lock(ObjD4)) + { + for (i=0;i=F(0) && sz=F(0) && szx*PolyObj[ObjD4].Sx< + PolyObj[ObjD4].MinX) + { + PolyObj[ObjD4].MinX=(PolyObj[ObjD4].Vertex+i)->x* + PolyObj[ObjD4].Sx; + } + + if ((PolyObj[ObjD4].Vertex+i)->y*PolyObj[ObjD4].Sy< + PolyObj[ObjD4].MinY) + { + PolyObj[ObjD4].MinY=(PolyObj[ObjD4].Vertex+i)->y* + PolyObj[ObjD4].Sy; + } + + if ((PolyObj[ObjD4].Vertex+i)->z*PolyObj[ObjD4].Sz< + PolyObj[ObjD4].MinZ) + { + PolyObj[ObjD4].MinZ=(PolyObj[ObjD4].Vertex+i)->z* + PolyObj[ObjD4].Sz; + } + + // 最大値の検索 + if ((PolyObj[ObjD4].Vertex+i)->x*PolyObj[ObjD4].Sx> + PolyObj[ObjD4].MaxX) + { + PolyObj[ObjD4].MaxX=(PolyObj[ObjD4].Vertex+i)->x* + PolyObj[ObjD4].Sx; + } + + if ((PolyObj[ObjD4].Vertex+i)->y*PolyObj[ObjD4].Sy> + PolyObj[ObjD4].MaxY) + { + PolyObj[ObjD4].MaxY=(PolyObj[ObjD4].Vertex+i)->y* + PolyObj[ObjD4].Sy; + } + + if ((PolyObj[ObjD4].Vertex+i)->z*PolyObj[ObjD4].Sz> + PolyObj[ObjD4].MaxZ) + { + PolyObj[ObjD4].MaxZ=(PolyObj[ObjD4].Vertex+i)->z* + PolyObj[ObjD4].Sz; + } + } + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:指定された位置を注視 -*/ +/*- -*/ +/*- ※ el4D::Object::StaticTransform関数、DynamicTransform関数の後に使用 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float Lx : 注視点のX座標 -*/ +/*- float Ly : 注視点のY座標 -*/ +/*- float Lz : 注視点のZ座標 -*/ +/*- float Ux : アップXベクトル -*/ +/*- 省略 = 0 -*/ +/*- float Uy : アップYベクトル -*/ +/*- 省略 = 1 -*/ +/*- float Uz : アップZベクトル -*/ +/*- 省略 = 0 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline BOOL el4D::Object::LookAt(D4OBJ ObjD4,float Lx,float Ly,float Lz, + float Ux=F(0),float Uy=F(1),float Uz=F(0)) +{ + static D3DVECTOR from,at,view,up,right; + static float length; + + // 見る側の位置を取得 + Object::GetPosition(ObjD4); + + from=D3DVECTOR(PolyObj[ObjD4].PosX,PolyObj[ObjD4].PosY,PolyObj[ObjD4].PosZ); + + // 見られる側の位置を取得 + at=D3DVECTOR(Lx,Ly,Lz); + + // 視点のZベクトルを取得 + view=at-from; + length=Magnitude(view); + if (length<1e-6f) return FALSE; + view/=length; + up=D3DVECTOR(Ux,Uy,Uz)-DotProduct(D3DVECTOR(Ux,Uy,Uz),view)*view; + length=Magnitude(up); + + // 正しいアップベクトルの検索 + if (length<1e-6f) + { + up=D3DVECTOR(F(0),F(1),F(0))-view.y*view; + length=Magnitude(up); + + if (length<1e-6f) + { + up=D3DVECTOR(F(0),F(0),F(1))-view.z*view; + length=Magnitude(up); + + if (length<1e-6f) return FALSE; + } + } + + // Y及びXベクトルを取得 + up/=length; + right=CrossProduct(up,view); + + // オブジェクトを注視 + mat1._14=F(0); + mat1._24=F(0); + mat1._34=F(0); + mat1._44=F(1); + + mat1._11=right.x; + mat1._12=right.y; + mat1._13=right.z; + mat1._21=up.x; + mat1._22=up.y; + mat1._23=up.z; + mat1._31=view.x; + mat1._32=view.y; + mat1._33=view.z; + mat1._41=PolyObj[ObjD4].ObjectMatrix._41; + mat1._42=PolyObj[ObjD4].ObjectMatrix._42; + mat1._43=PolyObj[ObjD4].ObjectMatrix._43; + + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD,&mat1); + D3Device->GetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].ObjectMatrix); + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:オブジェクトを注視 -*/ +/*- -*/ +/*- ※ el4D::Object::StaticTransform関数、DynamicTransform関数の後に使用 -*/ +/*- -*/ +/*- D4OBJ ObjD4A : ポリゴンオブジェクト情報 ( 見る側 ) -*/ +/*- D4OBJ ObjD4B : ポリゴンオブジェクト情報 ( 見られる側 ) -*/ +/*- float Ux : アップXベクトル -*/ +/*- 省略 = 0 -*/ +/*- float Uy : アップYベクトル -*/ +/*- 省略 = 1 -*/ +/*- float Uz : アップZベクトル -*/ +/*- 省略 = 0 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline BOOL el4D::Object::LookAtObject(D4OBJ ObjD4A,D4OBJ ObjD4B,float Ux=F(0), + float Uy=F(1),float Uz=F(0)) +{ + static D3DVECTOR from,at,view,up,right; + static float length; + + // 見る側の位置を取得 + Object::GetPosition(ObjD4A); + + from=D3DVECTOR(PolyObj[ObjD4A].PosX,PolyObj[ObjD4A].PosY, + PolyObj[ObjD4A].PosZ); + + // 見られる側の位置を取得 + Object::GetPosition(ObjD4B); + + at=D3DVECTOR(PolyObj[ObjD4B].PosX,PolyObj[ObjD4B].PosY,PolyObj[ObjD4B].PosZ); + + // 視点のZベクトルを取得 + view=at-from; + length=Magnitude(view); + if (length<1e-6f) return FALSE; + view/=length; + up=D3DVECTOR(Ux,Uy,Uz)-DotProduct(D3DVECTOR(Ux,Uy,Uz),view)*view; + length=Magnitude(up); + + // 正しいアップベクトルの検索 + if (length<1e-6f) + { + up=D3DVECTOR(F(0),F(1),F(0))-view.y*view; + length=Magnitude(up); + + if (length<1e-6f) + { + up=D3DVECTOR(F(0),F(0),F(1))-view.z*view; + length=Magnitude(up); + + if (length<1e-6f) return FALSE; + } + } + + // Y及びXベクトルを取得 + up/=length; + right=CrossProduct(up,view); + + // オブジェクトを注視 + mat1._14=F(0); + mat1._24=F(0); + mat1._34=F(0); + mat1._44=F(1); + + mat1._11=right.x; + mat1._12=right.y; + mat1._13=right.z; + mat1._21=up.x; + mat1._22=up.y; + mat1._23=up.z; + mat1._31=view.x; + mat1._32=view.y; + mat1._33=view.z; + mat1._41=PolyObj[ObjD4A].ObjectMatrix._41; + mat1._42=PolyObj[ObjD4A].ObjectMatrix._42; + mat1._43=PolyObj[ObjD4A].ObjectMatrix._43; + + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD,&mat1); + D3Device->GetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4A].ObjectMatrix); + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:カメラを注視 -*/ +/*- -*/ +/*- ※ el4D::Object::StaticTransform関数、DynamicTransform関数の後に使用 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Object::LookAtCamera(D4OBJ ObjD4) +{ + mat1=PolyObj[ObjD4].ObjectMatrix; + + mat2._14=F(0); + mat2._24=F(0); + mat2._34=F(0); + mat2._41=F(0); + mat2._42=F(0); + mat2._43=F(0); + mat2._44=F(1); + + mat2._11=Camera::ViewMatrix._11; + mat2._12=Camera::ViewMatrix._21; + mat2._13=Camera::ViewMatrix._31; + mat2._21=Camera::ViewMatrix._12; + mat2._22=Camera::ViewMatrix._22; + mat2._23=Camera::ViewMatrix._32; + mat2._31=Camera::ViewMatrix._13; + mat2._32=Camera::ViewMatrix._23; + mat2._33=Camera::ViewMatrix._33; + + PolyObj[ObjD4].Matrix=mat2*mat1; + + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].Matrix); + D3Device->GetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].ObjectMatrix); + + InitMatrix(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:カメラを注視 ( X軸 ) -*/ +/*- -*/ +/*- ※ el4D::Object::StaticTransform関数、DynamicTransform関数の後に使用 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Object::LookAtCameraX(D4OBJ ObjD4) +{ + mat1=PolyObj[ObjD4].ObjectMatrix; + + mat2._11=F(1); + mat2._12=F(0); + mat2._13=F(0); + mat2._14=F(0); + mat2._21=F(0); + mat2._24=F(0); + mat2._31=F(0); + mat2._34=F(0); + mat2._41=F(0); + mat2._42=F(0); + mat2._43=F(0); + mat2._44=F(1); + + mat2._22=Camera::ViewMatrix._22; + mat2._23=Camera::ViewMatrix._32; + mat2._32=Camera::ViewMatrix._23; + mat2._33=Camera::ViewMatrix._33; + + PolyObj[ObjD4].Matrix=mat2*mat1; + + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].Matrix); + D3Device->GetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].ObjectMatrix); + + InitMatrix(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:カメラを注視 ( Y軸 ) -*/ +/*- -*/ +/*- ※ el4D::Object::StaticTransform関数、DynamicTransform関数の後に使用 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Object::LookAtCameraY(D4OBJ ObjD4) +{ + mat1=PolyObj[ObjD4].ObjectMatrix; + + mat2._12=F(0); + mat2._14=F(0); + mat2._21=F(0); + mat2._22=F(1); + mat2._23=F(0); + mat2._24=F(0); + mat2._32=F(0); + mat2._34=F(0); + mat2._41=F(0); + mat2._42=F(0); + mat2._43=F(0); + mat2._44=F(1); + + mat2._11=Camera::ViewMatrix._11; + mat2._13=Camera::ViewMatrix._31; + mat2._31=Camera::ViewMatrix._13; + mat2._33=Camera::ViewMatrix._33; + + PolyObj[ObjD4].Matrix=mat2*mat1; + + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].Matrix); + D3Device->GetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].ObjectMatrix); + + InitMatrix(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- オブジェクト:カメラを注視 ( Z軸 ) -*/ +/*- -*/ +/*- ※ el4D::Object::StaticTransform関数、DynamicTransform関数の後に使用 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Object::LookAtCameraZ(D4OBJ ObjD4) +{ + mat1=PolyObj[ObjD4].ObjectMatrix; + + mat2._13=F(0); + mat2._14=F(0); + mat2._23=F(0); + mat2._24=F(0); + mat2._31=F(0); + mat2._32=F(0); + mat2._33=F(1); + mat2._34=F(0); + mat2._41=F(0); + mat2._42=F(0); + mat2._43=F(0); + mat2._44=F(1); + + mat2._11=Camera::ViewMatrix._11; + mat2._12=Camera::ViewMatrix._21; + mat2._21=Camera::ViewMatrix._12; + mat2._22=Camera::ViewMatrix._22; + + PolyObj[ObjD4].Matrix=mat2*mat1; + + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].Matrix); + D3Device->GetTransform(D3DTRANSFORMSTATE_WORLD,&PolyObj[ObjD4].ObjectMatrix); + + InitMatrix(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- プリミティブ:三角形 -*/ +/*- -*/ +/*- float Scale : サイズ -*/ +/*- -*/ +/*- 戻り値 : ポリゴンオブジェクト情報 ( D4OBJ型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D4OBJ el4D::Primitive::Triangle(float Scale) +{ + int i; + int vertex=0,index=0; + float ax,az; + D4OBJ ObjD4=-1; + + // 使用可能なポリゴンオブジェクトの検索 + for (i=0;i>=1; + } + + // ポリゴンオブジェクト情報の初期化 + Object::Free(ObjD4); + + PolyObj[ObjD4].VertexType=D3DFVF_VERTEX; + + PolyObj[ObjD4].VertexCount=Size*Size*count; + PolyObj[ObjD4].IndexCount=(Size-1)*(Size-1)*6*count; + + Object::CreateVertexBuffer(ObjD4); + + // パラメーターが省略された場合、Xサイズを使用 + if (ScaleY==F(0)) ScaleY=ScaleX; + if (ScaleZ==F(0)) ScaleZ=ScaleX; + + // 中心から面までの距離 + ScaleX/=F(2); + ScaleY/=F(2); + ScaleZ/=F(2); + + if (el4D::Lock(ObjD4)) + { + // 箱の生成 + #define SET_VERTEX(V,N,TU,TV,SI,EI,PI,SJ,EJ,PJ)\ + \ + for (i=SI;i!=EI;i+=PI)\ + {\ + for (j=SJ;j!=EJ;j+=PJ)\ + {\ + a=F(i)/F(Size-1);\ + b=F(j)/F(Size-1);\ + \ + *(PolyObj[ObjD4].Vertex+vertex++)=D3DVERTEX(V,N,TU,TV);\ + }\ + } + + // 上 + if (Cube&CUBE_TOP) + { + SET_VERTEX(D3DVECTOR(a*ScaleX*F(2)-ScaleX,ScaleY, + b*ScaleZ*F(2)-ScaleZ), + D3DVECTOR(F(0),F(1),F(0)),a,F(1)-b,0,Size,1,0,Size,1); + } + + // 下 + if (Cube&CUBE_BOTTOM) + { + SET_VERTEX(D3DVECTOR(a*ScaleX*F(2)-ScaleX,-ScaleY, + b*ScaleZ*F(2)-ScaleZ), + D3DVECTOR(F(0),F(-1),F(0)),a,b,Size-1,-1,-1,0,Size,1); + } + + // 前 + if (Cube&CUBE_FRONT) + { + SET_VERTEX(D3DVECTOR(a*ScaleX*F(2)-ScaleX,b*ScaleY*F(2)-ScaleY, + ScaleZ), + D3DVECTOR(F(0),F(0),F(1)),F(1)-a,F(1)-b,Size-1,-1,-1,0, + Size,1); + } + + // 後 + if (Cube&CUBE_BACK) + { + SET_VERTEX(D3DVECTOR(a*ScaleX*F(2)-ScaleX,b*ScaleY*F(2)-ScaleY, + -ScaleZ), + D3DVECTOR(F(0),F(0),F(-1)),a,F(1)-b,0,Size,1,0,Size,1); + } + + // 左 + if (Cube&CUBE_LEFT) + { + SET_VERTEX(D3DVECTOR(-ScaleX,a*ScaleY*F(2)-ScaleY, + b*ScaleZ*F(2)-ScaleZ), + D3DVECTOR(F(-1),F(0),F(0)),F(1)-b,F(1)-a,Size-1,-1,-1, + Size-1,-1,-1); + } + + // 右 + if (Cube&CUBE_RIGHT) + { + SET_VERTEX(D3DVECTOR(ScaleX,a*ScaleY*F(2)-ScaleY, + b*ScaleZ*F(2)-ScaleZ), + D3DVECTOR(F(1),F(0),F(0)),b,F(1)-a,0,Size,1,Size-1,-1,-1); + } + + #undef SET_VERTEX + + el4D::Unlock(ObjD4); + } + + vertex/=count; + + for (i=0;i>=1; + } + + // ポリゴンオブジェクト情報の初期化 + Object::Free(ObjD4); + + PolyObj[ObjD4].VertexType=D3DFVF_VERTEX; + + PolyObj[ObjD4].VertexCount=Size*Size*count; + PolyObj[ObjD4].IndexCount=(Size-1)*(Size-1)*6*count; + + Object::CreateVertexBuffer(ObjD4); + + // パラメーターが省略された場合、Xサイズを使用 + if (ScaleY==F(0)) ScaleY=ScaleX; + if (ScaleZ==F(0)) ScaleZ=ScaleX; + + // 中心から面までの距離 + ScaleX/=F(2); + ScaleY/=F(2); + ScaleZ/=F(2); + + if (el4D::Lock(ObjD4)) + { + // 箱の生成 + #define SET_VERTEX(V,N,TU,TV,SI,EI,PI,SJ,EJ,PJ)\ + \ + for (i=SI;i!=EI;i+=PI)\ + {\ + for (j=SJ;j!=EJ;j+=PJ)\ + {\ + a=F(i)/F(Size-1);\ + b=F(j)/F(Size-1);\ + \ + *(PolyObj[ObjD4].Vertex+vertex++)=D3DVERTEX(V,N,TU,TV);\ + }\ + } + + // 上 + if (Cube&CUBE_TOP) + { + SET_VERTEX(D3DVECTOR(a*ScaleX*F(2)-ScaleX,ScaleY, + b*ScaleZ*F(2)-ScaleZ), + D3DVECTOR(F(0),F(-1),F(0)),a,b,Size-1,-1,-1,0,Size,1); + } + + // 下 + if (Cube&CUBE_BOTTOM) + { + SET_VERTEX(D3DVECTOR(a*ScaleX*F(2)-ScaleX,-ScaleY, + b*ScaleZ*F(2)-ScaleZ), + D3DVECTOR(F(0),F(1),F(0)),a,F(1)-b,0,Size,1,0,Size,1); + } + + // 前 + if (Cube&CUBE_FRONT) + { + SET_VERTEX(D3DVECTOR(a*ScaleX*F(2)-ScaleX,b*ScaleY*F(2)-ScaleY, + ScaleZ), + D3DVECTOR(F(0),F(0),F(-1)),a,F(1)-b,0,Size,1,0,Size,1); + } + + // 後 + if (Cube&CUBE_BACK) + { + SET_VERTEX(D3DVECTOR(a*ScaleX*F(2)-ScaleX,b*ScaleY*F(2)-ScaleY, + -ScaleZ), + D3DVECTOR(F(0),F(0),F(1)),F(1)-a,F(1)-b,Size-1,-1,-1,0, + Size,1); + } + + // 左 + if (Cube&CUBE_LEFT) + { + SET_VERTEX(D3DVECTOR(-ScaleX,a*ScaleY*F(2)-ScaleY, + b*ScaleZ*F(2)-ScaleZ), + D3DVECTOR(F(1),F(0),F(0)),b,F(1)-a,0,Size,1,Size-1,-1,-1); + } + + // 右 + if (Cube&CUBE_RIGHT) + { + SET_VERTEX(D3DVECTOR(ScaleX,a*ScaleY*F(2)-ScaleY, + b*ScaleZ*F(2)-ScaleZ), + D3DVECTOR(F(-1),F(0),F(0)),F(1)-b,F(1)-a,Size-1,-1,-1, + Size-1,-1,-1); + } + + #undef SET_VERTEX + + el4D::Unlock(ObjD4); + } + + vertex/=count; + + for (i=0;ix=Px; + (PolyObj[ObjD4].Vertex+No)->y=Py; + (PolyObj[ObjD4].Vertex+No)->z=Pz; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:X座標移動 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float Px : X座標の位置 ( -:左 / +:右 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::MoveX(D4OBJ ObjD4,int No,float Px) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].Vertex+No)->x=Px; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:Y座標移動 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float Py : Y座標の位置 ( -:下 / +:上 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::MoveY(D4OBJ ObjD4,int No,float Py) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].Vertex+No)->y=Py; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:Z座標移動 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float Pz : Z座標の位置 ( -:手前 / +:奥 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::MoveZ(D4OBJ ObjD4,int No,float Pz) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].Vertex+No)->z=Pz; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:頂点数の取得 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline int el4D::Vertex::GetCount(D4OBJ ObjD4) +{ + return PolyObj[ObjD4].VertexCount; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:座標変更 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float Vx : 頂点のX座標 -*/ +/*- float Vy : 頂点のY座標 -*/ +/*- float Vz : 頂点のZ座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::Set(D4OBJ ObjD4,int No,float Vx,float Vy,float Vz) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].Vertex+No)->x=Vx; + (PolyObj[ObjD4].Vertex+No)->y=Vy; + (PolyObj[ObjD4].Vertex+No)->z=Vz; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:X座標変更 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float Vx : 頂点のX座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::SetX(D4OBJ ObjD4,int No,float Vx) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].Vertex+No)->x=Vx; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:Y座標変更 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float Vy : 頂点のY座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::SetY(D4OBJ ObjD4,int No,float Vy) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].Vertex+No)->y=Vy; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:Z座標変更 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float Vz : 頂点のZ座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::SetZ(D4OBJ ObjD4,int No,float Vz) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].Vertex+No)->z=Vz; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:座標取得 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float* Vx : 頂点のX座標 ( 戻り値 ) -*/ +/*- float* Vy : 頂点のY座標 ( 戻り値 ) -*/ +/*- float* Vz : 頂点のZ座標 ( 戻り値 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::Get(D4OBJ ObjD4,int No,float* Vx,float* Vy,float* Vz) +{ + if (el4D::Lock(ObjD4)) + { + *Vx=(PolyObj[ObjD4].Vertex+No)->x; + *Vy=(PolyObj[ObjD4].Vertex+No)->y; + *Vz=(PolyObj[ObjD4].Vertex+No)->z; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:X座標取得 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- -*/ +/*- 戻り値 : 頂点のX座標 ( float型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline float el4D::Vertex::GetX(D4OBJ ObjD4,int No) +{ + float Px=F(0); + + if (el4D::Lock(ObjD4)) + { + Px=(PolyObj[ObjD4].Vertex+No)->x; + + el4D::Unlock(ObjD4); + } + + return Px; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:Y座標取得 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- -*/ +/*- 戻り値 : 頂点のY座標 ( float型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline float el4D::Vertex::GetY(D4OBJ ObjD4,int No) +{ + float Py=F(0); + + if (el4D::Lock(ObjD4)) + { + Py=(PolyObj[ObjD4].Vertex+No)->y; + + el4D::Unlock(ObjD4); + } + + return Py; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:Z座標取得 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- -*/ +/*- 戻り値 : 頂点のZ座標 ( float型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline float el4D::Vertex::GetZ(D4OBJ ObjD4,int No) +{ + float Pz=F(0); + + if (el4D::Lock(ObjD4)) + { + Pz=(PolyObj[ObjD4].Vertex+No)->z; + + el4D::Unlock(ObjD4); + } + + return Pz; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:UV値変更 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float Tu : テクスチャーのU座標 -*/ +/*- float Tv : テクスチャーのV座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::SetUV(D4OBJ ObjD4,int No,float Tu,float Tv) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].Vertex+No)->tu=Tu; + (PolyObj[ObjD4].Vertex+No)->tv=Tv; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:U値変更 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float Tu : テクスチャーのU座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::SetU(D4OBJ ObjD4,int No,float Tu) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].Vertex+No)->tu=Tu; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:V値変更 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float Tv : テクスチャーのV座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::SetV(D4OBJ ObjD4,int No,float Tv) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].Vertex+No)->tv=Tv; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:UV値取得 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float* Tu : テクスチャーのU座標 -*/ +/*- float* Tv : テクスチャーのV座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::GetUV(D4OBJ ObjD4,int No,float* Tu,float* Tv) +{ + if (el4D::Lock(ObjD4)) + { + *Tu=(PolyObj[ObjD4].Vertex+No)->tu; + *Tv=(PolyObj[ObjD4].Vertex+No)->tv; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:U値取得 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- -*/ +/*- 戻り値 : テクスチャーのU値 ( float型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline float el4D::Vertex::GetU(D4OBJ ObjD4,int No) +{ + float Tu=F(0); + + if (el4D::Lock(ObjD4)) + { + Tu=(PolyObj[ObjD4].Vertex+No)->tu; + + el4D::Unlock(ObjD4); + } + + return Tu; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:V値取得 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- -*/ +/*- 戻り値 : テクスチャーのV値 ( float型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline float el4D::Vertex::GetV(D4OBJ ObjD4,int No) +{ + float Tv=F(0); + + if (el4D::Lock(ObjD4)) + { + Tv=(PolyObj[ObjD4].Vertex+No)->tv; + + el4D::Unlock(ObjD4); + } + + return Tv; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:UV値加算 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float Tu : テクスチャーのU座標 -*/ +/*- float Tv : テクスチャーのV座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::AddUV(D4OBJ ObjD4,int No,float Tu,float Tv) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].Vertex+No)->tu+=Tu; + (PolyObj[ObjD4].Vertex+No)->tv+=Tv; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:U値加算 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float Tu : テクスチャーのU座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::AddU(D4OBJ ObjD4,int No,float Tu) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].Vertex+No)->tu+=Tu; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:V値加算 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- float Tv : テクスチャーのV座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::AddV(D4OBJ ObjD4,int No,float Tv) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].Vertex+No)->tv+=Tv; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:スクリーン座標で取得 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : 頂点No -*/ +/*- int* Sx : X座標 ( 戻り値 ) -*/ +/*- int* Sy : Y座標 ( 戻り値 ) -*/ +/*- float* Sz : 省略 = 未使用 -*/ +/*- 任意のfloat*型変数 = Z座標 ( 戻り値 ) -*/ +/*- -*/ +/*- 戻り値 : TRUE = カメラ前方にオブジェクトあり -*/ +/*- FALSE = カメラ後方にオブジェクトあり -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +static float _TempVertexSz; + +BOOL el4D::Vertex::GetScreenPosition(D4OBJ ObjD4,int No,int* Sx,int* Sy, + float* Sz=&_TempVertexSz) +{ + static DWORD clip_w,clip_h; + static float x,y,z,xp,yp,zp,wp,sz; + + // クリップ範囲の取得 + clip_w=(Camera::Vx2-Camera::Vx1)/2; + clip_h=(Camera::Vy2-Camera::Vy1)/2; + + // オブジェクト×ビュー×投影のマトリクスを取得 + mat1=PolyObj[ObjD4].ObjectMatrix*Camera::ViewMatrix; + mat2=mat1*Camera::ProjectionMatrix; + + if (el4D::Lock(ObjD4)) + { + // 頂点の座標を取得 + x=(PolyObj[ObjD4].Vertex+No)->x; + y=(PolyObj[ObjD4].Vertex+No)->y; + z=(PolyObj[ObjD4].Vertex+No)->z; + + el4D::Unlock(ObjD4); + } + + // スクリーン座標の算出 + xp=mat2._11*x+mat2._21*y+mat2._31*z+mat2._41; + yp=mat2._12*x+mat2._22*y+mat2._32*z+mat2._42; + zp=mat2._13*x+mat2._23*y+mat2._33*z+mat2._43; + wp=mat2._14*x+mat2._24*y+mat2._34*z+mat2._44; + + sz=zp/wp; + + // 頂点がカメラの前方にある場合 + if (sz>=F(0) && sztu; + *(PolyObj[ObjD4].Mv[No]+i)=(PolyObj[ObjD4].Vertex+i)->tv; + } + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:Xファイルオブジェクトのマルチマテリアルへ保存 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : マルチマテリアルNo ( 0〜3 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::MMSaveX(D4OBJ ObjD4,int No) +{ + int i; // 汎用カウンター + D4OBJ j=ObjD4; // ポリゴンオブジェクト + + while (TRUE) + { + // ポリゴンデータの場合 + if (PolyObj[j].VertexType!=POLYOBJ_FRAME) + { + // UV座標の保存 + if (el4D::Lock(j)) + { + for (i=0;itu; + *(PolyObj[j].Mv[No]+i)=(PolyObj[j].Vertex+i)->tv; + } + + el4D::Unlock(j); + } + } + + // これ以上オブジェクトがない場合、終了 + if (PolyObj[j++].Next==-1) break; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:マルチマテリアルから読み込み -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : マルチマテリアルNo ( 0〜3 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::MMLoad(D4OBJ ObjD4,int No) +{ + int i; // 汎用カウンター + + // UV座標の読み込み + if (el4D::Lock(ObjD4)) + { + for (i=0;itu=*(PolyObj[ObjD4].Mu[No]+i); + (PolyObj[ObjD4].Vertex+i)->tv=*(PolyObj[ObjD4].Mv[No]+i); + } + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 頂点:Xファイルオブジェクトのマルチマテリアルから読み込み -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : マルチマテリアルNo ( 0〜3 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Vertex::MMLoadX(D4OBJ ObjD4,int No) +{ + int i; // 汎用カウンター + D4OBJ j=ObjD4; // ポリゴンオブジェクト + + while (TRUE) + { + // ポリゴンデータの場合 + if (PolyObj[j].VertexType!=POLYOBJ_FRAME) + { + // UV座標の読み込み + if (el4D::Lock(j)) + { + for (i=0;itu=*(PolyObj[j].Mu[No]+i); + (PolyObj[j].Vertex+i)->tv=*(PolyObj[j].Mv[No]+i); + } + + el4D::Unlock(j); + } + } + + // これ以上オブジェクトがない場合、終了 + if (PolyObj[j++].Next==-1) break; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マトリクス変換:位置 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Transform::P(D4OBJ ObjD4) +{ + mat1=PolyObj[ObjD4].Matrix; + + mat2._11=F(1); + mat2._12=F(0); + mat2._13=F(0); + mat2._14=F(0); + mat2._21=F(0); + mat2._22=F(1); + mat2._23=F(0); + mat2._24=F(0); + mat2._31=F(0); + mat2._32=F(0); + mat2._33=F(1); + mat2._34=F(0); + mat2._44=F(1); + + mat2._41=PolyObj[ObjD4].Px; + mat2._42=PolyObj[ObjD4].Py; + mat2._43=PolyObj[ObjD4].Pz; + + PolyObj[ObjD4].Matrix=mat1*mat2; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マトリクス変換:X軸で回転 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Transform::X(D4OBJ ObjD4) +{ + mat1=PolyObj[ObjD4].Matrix; + + mat2._11=F(1); + mat2._12=F(0); + mat2._13=F(0); + mat2._14=F(0); + mat2._21=F(0); + mat2._24=F(0); + mat2._31=F(0); + mat2._34=F(0); + mat2._41=F(0); + mat2._42=F(0); + mat2._43=F(0); + mat2._44=F(1); + + mat2._22=F(cos(PolyObj[ObjD4].Ax)); + mat2._23=F(-sin(PolyObj[ObjD4].Ax)); + mat2._32=F(sin(PolyObj[ObjD4].Ax)); + mat2._33=F(cos(PolyObj[ObjD4].Ax)); + + PolyObj[ObjD4].Matrix=mat1*mat2; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マトリクス変換:Y軸で回転 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Transform::Y(D4OBJ ObjD4) +{ + mat1=PolyObj[ObjD4].Matrix; + + mat2._12=F(0); + mat2._14=F(0); + mat2._21=F(0); + mat2._22=F(1); + mat2._23=F(0); + mat2._24=F(0); + mat2._32=F(0); + mat2._34=F(0); + mat2._41=F(0); + mat2._42=F(0); + mat2._43=F(0); + mat2._44=F(1); + + mat2._11=F(cos(PolyObj[ObjD4].Ay)); + mat2._13=F(sin(PolyObj[ObjD4].Ay)); + mat2._31=F(-sin(PolyObj[ObjD4].Ay)); + mat2._33=F(cos(PolyObj[ObjD4].Ay)); + + PolyObj[ObjD4].Matrix=mat1*mat2; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マトリクス変換:Z軸で回転 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Transform::Z(D4OBJ ObjD4) +{ + mat1=PolyObj[ObjD4].Matrix; + + mat2._13=F(0); + mat2._14=F(0); + mat2._23=F(0); + mat2._24=F(0); + mat2._31=F(0); + mat2._32=F(0); + mat2._33=F(1); + mat2._34=F(0); + mat2._41=F(0); + mat2._42=F(0); + mat2._43=F(0); + mat2._44=F(1); + + mat2._11=F(cos(PolyObj[ObjD4].Az)); + mat2._12=F(-sin(PolyObj[ObjD4].Az)); + mat2._21=F(sin(PolyObj[ObjD4].Az)); + mat2._22=F(cos(PolyObj[ObjD4].Az)); + + PolyObj[ObjD4].Matrix=mat1*mat2; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マトリクス変換:サイズ -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Transform::S(D4OBJ ObjD4) +{ + mat1=PolyObj[ObjD4].Matrix; + + mat2._12=F(0); + mat2._13=F(0); + mat2._14=F(0); + mat2._21=F(0); + mat2._23=F(0); + mat2._24=F(0); + mat2._31=F(0); + mat2._32=F(0); + mat2._34=F(0); + mat2._41=F(0); + mat2._42=F(0); + mat2._43=F(0); + mat2._44=F(1); + + mat2._11=PolyObj[ObjD4].Sx; + mat2._22=PolyObj[ObjD4].Sy; + mat2._33=PolyObj[ObjD4].Sz; + + PolyObj[ObjD4].Matrix=mat1*mat2; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マトリクス変換:3軸を1つの角度として回転 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Transform::Angle(D4OBJ ObjD4) +{ + float SinAx=sinf(PolyObj[ObjD4].Ax/F(2)); + float SinAy=sinf(PolyObj[ObjD4].Ay/F(2)); + float SinAz=sinf(PolyObj[ObjD4].Az/F(2)); + float CosAx=cosf(PolyObj[ObjD4].Ax/F(2)); + float CosAy=cosf(PolyObj[ObjD4].Ay/F(2)); + float CosAz=cosf(PolyObj[ObjD4].Az/F(2)); + + float x=SinAx*CosAy*CosAz-CosAx*SinAy*SinAz; + float y=CosAx*SinAy*CosAz+SinAx*CosAy*SinAz; + float z=CosAx*CosAy*SinAz-SinAx*SinAy*CosAz; + float w=CosAx*CosAy*CosAz+SinAx*SinAy*SinAz; + + float xx=x*x; + float yy=y*y; + float zz=z*z; + float xy=x*y; + float xz=x*z; + float yz=y*z; + float wx=w*x; + float wy=w*y; + float wz=w*z; + + mat1=PolyObj[ObjD4].Matrix; + + mat2._11=F(1)-F(2)*(yy+zz); + mat2._12=F(2)*(xy-wz); + mat2._13=F(2)*(xz+wy); + mat2._14=F(0); + mat2._21=F(2)*(xy+wz); + mat2._22=F(1)-F(2)*(xx+zz); + mat2._23=F(2)*(yz-wx); + mat2._24=F(0); + mat2._31=F(2)*(xz-wy); + mat2._32=F(2)*(yz+wx); + mat2._33=F(1)-F(2)*(xx+yy); + mat2._34=F(0); + mat2._41=F(0); + mat2._42=F(0); + mat2._43=F(0); + mat2._44=F(1); + + PolyObj[ObjD4].Matrix=mat1*mat2; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マトリクス変換:複合 ※ 関数名の左から順番に処理 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Transform::PX(D4OBJ O) { P(O); X(O); } +inline void el4D::Transform::PY(D4OBJ O) { P(O); Y(O); } +inline void el4D::Transform::PZ(D4OBJ O) { P(O); Z(O); } +inline void el4D::Transform::PS(D4OBJ O) { P(O); S(O); } +inline void el4D::Transform::XP(D4OBJ O) { X(O); P(O); } +inline void el4D::Transform::XY(D4OBJ O) { X(O); Y(O); } +inline void el4D::Transform::XZ(D4OBJ O) { X(O); Z(O); } +inline void el4D::Transform::XS(D4OBJ O) { X(O); S(O); } +inline void el4D::Transform::YP(D4OBJ O) { Y(O); P(O); } +inline void el4D::Transform::YX(D4OBJ O) { Y(O); X(O); } +inline void el4D::Transform::YZ(D4OBJ O) { Y(O); Z(O); } +inline void el4D::Transform::YS(D4OBJ O) { Y(O); S(O); } +inline void el4D::Transform::ZP(D4OBJ O) { Z(O); P(O); } +inline void el4D::Transform::ZX(D4OBJ O) { Z(O); X(O); } +inline void el4D::Transform::ZY(D4OBJ O) { Z(O); Y(O); } +inline void el4D::Transform::ZS(D4OBJ O) { Z(O); S(O); } +inline void el4D::Transform::SP(D4OBJ O) { S(O); P(O); } +inline void el4D::Transform::SX(D4OBJ O) { S(O); X(O); } +inline void el4D::Transform::SY(D4OBJ O) { S(O); Y(O); } +inline void el4D::Transform::SZ(D4OBJ O) { S(O); Z(O); } +inline void el4D::Transform::PXY(D4OBJ O) { P(O); X(O); Y(O); } +inline void el4D::Transform::PXZ(D4OBJ O) { P(O); X(O); Z(O); } +inline void el4D::Transform::PXS(D4OBJ O) { P(O); X(O); S(O); } +inline void el4D::Transform::PYX(D4OBJ O) { P(O); Y(O); X(O); } +inline void el4D::Transform::PYZ(D4OBJ O) { P(O); Y(O); Z(O); } +inline void el4D::Transform::PYS(D4OBJ O) { P(O); Y(O); S(O); } +inline void el4D::Transform::PZX(D4OBJ O) { P(O); Z(O); X(O); } +inline void el4D::Transform::PZY(D4OBJ O) { P(O); Z(O); Y(O); } +inline void el4D::Transform::PZS(D4OBJ O) { P(O); Z(O); S(O); } +inline void el4D::Transform::PSX(D4OBJ O) { P(O); S(O); X(O); } +inline void el4D::Transform::PSY(D4OBJ O) { P(O); S(O); Y(O); } +inline void el4D::Transform::PSZ(D4OBJ O) { P(O); S(O); Z(O); } +inline void el4D::Transform::XPY(D4OBJ O) { X(O); P(O); Y(O); } +inline void el4D::Transform::XPZ(D4OBJ O) { X(O); P(O); Z(O); } +inline void el4D::Transform::XPS(D4OBJ O) { X(O); P(O); S(O); } +inline void el4D::Transform::XYP(D4OBJ O) { X(O); Y(O); P(O); } +inline void el4D::Transform::XYZ(D4OBJ O) { X(O); Y(O); Z(O); } +inline void el4D::Transform::XYS(D4OBJ O) { X(O); Y(O); S(O); } +inline void el4D::Transform::XZP(D4OBJ O) { X(O); Z(O); P(O); } +inline void el4D::Transform::XZY(D4OBJ O) { X(O); Z(O); Y(O); } +inline void el4D::Transform::XZS(D4OBJ O) { X(O); Z(O); S(O); } +inline void el4D::Transform::XSP(D4OBJ O) { X(O); S(O); P(O); } +inline void el4D::Transform::XSY(D4OBJ O) { X(O); S(O); Y(O); } +inline void el4D::Transform::XSZ(D4OBJ O) { X(O); S(O); Z(O); } +inline void el4D::Transform::YPX(D4OBJ O) { Y(O); P(O); X(O); } +inline void el4D::Transform::YPZ(D4OBJ O) { Y(O); P(O); Z(O); } +inline void el4D::Transform::YPS(D4OBJ O) { Y(O); P(O); S(O); } +inline void el4D::Transform::YXP(D4OBJ O) { Y(O); X(O); P(O); } +inline void el4D::Transform::YXZ(D4OBJ O) { Y(O); X(O); Z(O); } +inline void el4D::Transform::YXS(D4OBJ O) { Y(O); X(O); S(O); } +inline void el4D::Transform::YZP(D4OBJ O) { Y(O); Z(O); P(O); } +inline void el4D::Transform::YZX(D4OBJ O) { Y(O); Z(O); X(O); } +inline void el4D::Transform::YZS(D4OBJ O) { Y(O); Z(O); S(O); } +inline void el4D::Transform::YSP(D4OBJ O) { Y(O); S(O); P(O); } +inline void el4D::Transform::YSX(D4OBJ O) { Y(O); S(O); X(O); } +inline void el4D::Transform::YSZ(D4OBJ O) { Y(O); S(O); Z(O); } +inline void el4D::Transform::ZPX(D4OBJ O) { Z(O); P(O); X(O); } +inline void el4D::Transform::ZPY(D4OBJ O) { Z(O); P(O); Y(O); } +inline void el4D::Transform::ZPS(D4OBJ O) { Z(O); P(O); S(O); } +inline void el4D::Transform::ZXP(D4OBJ O) { Z(O); X(O); P(O); } +inline void el4D::Transform::ZXY(D4OBJ O) { Z(O); X(O); Y(O); } +inline void el4D::Transform::ZXS(D4OBJ O) { Z(O); X(O); S(O); } +inline void el4D::Transform::ZYP(D4OBJ O) { Z(O); Y(O); P(O); } +inline void el4D::Transform::ZYX(D4OBJ O) { Z(O); Y(O); X(O); } +inline void el4D::Transform::ZYS(D4OBJ O) { Z(O); Y(O); S(O); } +inline void el4D::Transform::ZSP(D4OBJ O) { Z(O); S(O); P(O); } +inline void el4D::Transform::ZSX(D4OBJ O) { Z(O); S(O); X(O); } +inline void el4D::Transform::ZSY(D4OBJ O) { Z(O); S(O); Y(O); } +inline void el4D::Transform::SPX(D4OBJ O) { S(O); P(O); X(O); } +inline void el4D::Transform::SPY(D4OBJ O) { S(O); P(O); Y(O); } +inline void el4D::Transform::SPZ(D4OBJ O) { S(O); P(O); Z(O); } +inline void el4D::Transform::SXP(D4OBJ O) { S(O); X(O); P(O); } +inline void el4D::Transform::SXY(D4OBJ O) { S(O); X(O); Y(O); } +inline void el4D::Transform::SXZ(D4OBJ O) { S(O); X(O); Z(O); } +inline void el4D::Transform::SYP(D4OBJ O) { S(O); Y(O); P(O); } +inline void el4D::Transform::SYX(D4OBJ O) { S(O); Y(O); X(O); } +inline void el4D::Transform::SYZ(D4OBJ O) { S(O); Y(O); Z(O); } +inline void el4D::Transform::SZP(D4OBJ O) { S(O); Z(O); P(O); } +inline void el4D::Transform::SZX(D4OBJ O) { S(O); Z(O); X(O); } +inline void el4D::Transform::SZY(D4OBJ O) { S(O); Z(O); Y(O); } +inline void el4D::Transform::PXYZ(D4OBJ O) { P(O); X(O); Y(O); Z(O); } +inline void el4D::Transform::PXYS(D4OBJ O) { P(O); X(O); Y(O); S(O); } +inline void el4D::Transform::PXZY(D4OBJ O) { P(O); X(O); Z(O); Y(O); } +inline void el4D::Transform::PXZS(D4OBJ O) { P(O); X(O); Z(O); S(O); } +inline void el4D::Transform::PXSY(D4OBJ O) { P(O); X(O); S(O); Y(O); } +inline void el4D::Transform::PXSZ(D4OBJ O) { P(O); X(O); S(O); Z(O); } +inline void el4D::Transform::PYXZ(D4OBJ O) { P(O); Y(O); X(O); Z(O); } +inline void el4D::Transform::PYXS(D4OBJ O) { P(O); Y(O); X(O); S(O); } +inline void el4D::Transform::PYZX(D4OBJ O) { P(O); Y(O); Z(O); X(O); } +inline void el4D::Transform::PYZS(D4OBJ O) { P(O); Y(O); Z(O); S(O); } +inline void el4D::Transform::PYSX(D4OBJ O) { P(O); Y(O); S(O); X(O); } +inline void el4D::Transform::PYSZ(D4OBJ O) { P(O); Y(O); S(O); Z(O); } +inline void el4D::Transform::PZXY(D4OBJ O) { P(O); Z(O); X(O); Y(O); } +inline void el4D::Transform::PZXS(D4OBJ O) { P(O); Z(O); X(O); S(O); } +inline void el4D::Transform::PZYX(D4OBJ O) { P(O); Z(O); Y(O); X(O); } +inline void el4D::Transform::PZYS(D4OBJ O) { P(O); Z(O); Y(O); S(O); } +inline void el4D::Transform::PZSX(D4OBJ O) { P(O); Z(O); S(O); X(O); } +inline void el4D::Transform::PZSY(D4OBJ O) { P(O); Z(O); S(O); Y(O); } +inline void el4D::Transform::PSXY(D4OBJ O) { P(O); S(O); X(O); Y(O); } +inline void el4D::Transform::PSXZ(D4OBJ O) { P(O); S(O); X(O); Z(O); } +inline void el4D::Transform::PSYX(D4OBJ O) { P(O); S(O); Y(O); X(O); } +inline void el4D::Transform::PSYZ(D4OBJ O) { P(O); S(O); Y(O); Z(O); } +inline void el4D::Transform::PSZX(D4OBJ O) { P(O); S(O); Z(O); X(O); } +inline void el4D::Transform::PSZY(D4OBJ O) { P(O); S(O); Z(O); Y(O); } +inline void el4D::Transform::XPYZ(D4OBJ O) { X(O); P(O); Y(O); Z(O); } +inline void el4D::Transform::XPYS(D4OBJ O) { X(O); P(O); Y(O); S(O); } +inline void el4D::Transform::XPZY(D4OBJ O) { X(O); P(O); Z(O); Y(O); } +inline void el4D::Transform::XPZS(D4OBJ O) { X(O); P(O); Z(O); S(O); } +inline void el4D::Transform::XPSY(D4OBJ O) { X(O); P(O); S(O); Y(O); } +inline void el4D::Transform::XPSZ(D4OBJ O) { X(O); P(O); S(O); Z(O); } +inline void el4D::Transform::XYPZ(D4OBJ O) { X(O); Y(O); P(O); Z(O); } +inline void el4D::Transform::XYPS(D4OBJ O) { X(O); Y(O); P(O); S(O); } +inline void el4D::Transform::XYZP(D4OBJ O) { X(O); Y(O); Z(O); P(O); } +inline void el4D::Transform::XYZS(D4OBJ O) { X(O); Y(O); Z(O); S(O); } +inline void el4D::Transform::XYSP(D4OBJ O) { X(O); Y(O); S(O); P(O); } +inline void el4D::Transform::XYSZ(D4OBJ O) { X(O); Y(O); S(O); Z(O); } +inline void el4D::Transform::XZPY(D4OBJ O) { X(O); Z(O); P(O); Y(O); } +inline void el4D::Transform::XZPS(D4OBJ O) { X(O); Z(O); P(O); S(O); } +inline void el4D::Transform::XZYP(D4OBJ O) { X(O); Z(O); Y(O); P(O); } +inline void el4D::Transform::XZYS(D4OBJ O) { X(O); Z(O); Y(O); S(O); } +inline void el4D::Transform::XZSP(D4OBJ O) { X(O); Z(O); S(O); P(O); } +inline void el4D::Transform::XZSY(D4OBJ O) { X(O); Z(O); S(O); Y(O); } +inline void el4D::Transform::XSPY(D4OBJ O) { X(O); S(O); P(O); Y(O); } +inline void el4D::Transform::XSPZ(D4OBJ O) { X(O); S(O); P(O); Z(O); } +inline void el4D::Transform::XSYP(D4OBJ O) { X(O); S(O); Y(O); P(O); } +inline void el4D::Transform::XSYZ(D4OBJ O) { X(O); S(O); Y(O); Z(O); } +inline void el4D::Transform::XSZP(D4OBJ O) { X(O); S(O); Z(O); P(O); } +inline void el4D::Transform::XSZY(D4OBJ O) { X(O); S(O); Z(O); Y(O); } +inline void el4D::Transform::YPXZ(D4OBJ O) { Y(O); P(O); X(O); Z(O); } +inline void el4D::Transform::YPXS(D4OBJ O) { Y(O); P(O); X(O); S(O); } +inline void el4D::Transform::YPZX(D4OBJ O) { Y(O); P(O); Z(O); X(O); } +inline void el4D::Transform::YPZS(D4OBJ O) { Y(O); P(O); Z(O); S(O); } +inline void el4D::Transform::YPSX(D4OBJ O) { Y(O); P(O); S(O); X(O); } +inline void el4D::Transform::YPSZ(D4OBJ O) { Y(O); P(O); S(O); Z(O); } +inline void el4D::Transform::YXPZ(D4OBJ O) { Y(O); X(O); P(O); Z(O); } +inline void el4D::Transform::YXPS(D4OBJ O) { Y(O); X(O); P(O); S(O); } +inline void el4D::Transform::YXZP(D4OBJ O) { Y(O); X(O); Z(O); P(O); } +inline void el4D::Transform::YXZS(D4OBJ O) { Y(O); X(O); Z(O); S(O); } +inline void el4D::Transform::YXSP(D4OBJ O) { Y(O); X(O); S(O); P(O); } +inline void el4D::Transform::YXSZ(D4OBJ O) { Y(O); X(O); S(O); Z(O); } +inline void el4D::Transform::YZPX(D4OBJ O) { Y(O); Z(O); P(O); X(O); } +inline void el4D::Transform::YZPS(D4OBJ O) { Y(O); Z(O); P(O); S(O); } +inline void el4D::Transform::YZXP(D4OBJ O) { Y(O); Z(O); X(O); P(O); } +inline void el4D::Transform::YZXS(D4OBJ O) { Y(O); Z(O); X(O); S(O); } +inline void el4D::Transform::YZSP(D4OBJ O) { Y(O); Z(O); S(O); P(O); } +inline void el4D::Transform::YZSX(D4OBJ O) { Y(O); Z(O); S(O); X(O); } +inline void el4D::Transform::YSPX(D4OBJ O) { Y(O); S(O); P(O); X(O); } +inline void el4D::Transform::YSPZ(D4OBJ O) { Y(O); S(O); P(O); Z(O); } +inline void el4D::Transform::YSXP(D4OBJ O) { Y(O); S(O); X(O); P(O); } +inline void el4D::Transform::YSXZ(D4OBJ O) { Y(O); S(O); X(O); Z(O); } +inline void el4D::Transform::YSZP(D4OBJ O) { Y(O); S(O); Z(O); P(O); } +inline void el4D::Transform::YSZX(D4OBJ O) { Y(O); S(O); Z(O); X(O); } +inline void el4D::Transform::ZPXY(D4OBJ O) { Z(O); P(O); X(O); Y(O); } +inline void el4D::Transform::ZPXS(D4OBJ O) { Z(O); P(O); X(O); S(O); } +inline void el4D::Transform::ZPYX(D4OBJ O) { Z(O); P(O); Y(O); X(O); } +inline void el4D::Transform::ZPYS(D4OBJ O) { Z(O); P(O); Y(O); S(O); } +inline void el4D::Transform::ZPSX(D4OBJ O) { Z(O); P(O); S(O); X(O); } +inline void el4D::Transform::ZPSY(D4OBJ O) { Z(O); P(O); S(O); Y(O); } +inline void el4D::Transform::ZXPY(D4OBJ O) { Z(O); X(O); P(O); Y(O); } +inline void el4D::Transform::ZXPS(D4OBJ O) { Z(O); X(O); P(O); S(O); } +inline void el4D::Transform::ZXYP(D4OBJ O) { Z(O); X(O); Y(O); P(O); } +inline void el4D::Transform::ZXYS(D4OBJ O) { Z(O); X(O); Y(O); S(O); } +inline void el4D::Transform::ZXSP(D4OBJ O) { Z(O); X(O); S(O); P(O); } +inline void el4D::Transform::ZXSY(D4OBJ O) { Z(O); X(O); S(O); Y(O); } +inline void el4D::Transform::ZYPX(D4OBJ O) { Z(O); Y(O); P(O); X(O); } +inline void el4D::Transform::ZYPS(D4OBJ O) { Z(O); Y(O); P(O); S(O); } +inline void el4D::Transform::ZYXP(D4OBJ O) { Z(O); Y(O); X(O); P(O); } +inline void el4D::Transform::ZYXS(D4OBJ O) { Z(O); Y(O); X(O); S(O); } +inline void el4D::Transform::ZYSP(D4OBJ O) { Z(O); Y(O); S(O); P(O); } +inline void el4D::Transform::ZYSX(D4OBJ O) { Z(O); Y(O); S(O); X(O); } +inline void el4D::Transform::ZSPX(D4OBJ O) { Z(O); S(O); P(O); X(O); } +inline void el4D::Transform::ZSPY(D4OBJ O) { Z(O); S(O); P(O); Y(O); } +inline void el4D::Transform::ZSXP(D4OBJ O) { Z(O); S(O); X(O); P(O); } +inline void el4D::Transform::ZSXY(D4OBJ O) { Z(O); S(O); X(O); Y(O); } +inline void el4D::Transform::ZSYP(D4OBJ O) { Z(O); S(O); Y(O); P(O); } +inline void el4D::Transform::ZSYX(D4OBJ O) { Z(O); S(O); Y(O); X(O); } +inline void el4D::Transform::SPXY(D4OBJ O) { S(O); P(O); X(O); Y(O); } +inline void el4D::Transform::SPXZ(D4OBJ O) { S(O); P(O); X(O); Z(O); } +inline void el4D::Transform::SPYX(D4OBJ O) { S(O); P(O); Y(O); X(O); } +inline void el4D::Transform::SPYZ(D4OBJ O) { S(O); P(O); Y(O); Z(O); } +inline void el4D::Transform::SPZX(D4OBJ O) { S(O); P(O); Z(O); X(O); } +inline void el4D::Transform::SPZY(D4OBJ O) { S(O); P(O); Z(O); Y(O); } +inline void el4D::Transform::SXPY(D4OBJ O) { S(O); X(O); P(O); Y(O); } +inline void el4D::Transform::SXPZ(D4OBJ O) { S(O); X(O); P(O); Z(O); } +inline void el4D::Transform::SXYP(D4OBJ O) { S(O); X(O); Y(O); P(O); } +inline void el4D::Transform::SXYZ(D4OBJ O) { S(O); X(O); Y(O); Z(O); } +inline void el4D::Transform::SXZP(D4OBJ O) { S(O); X(O); Z(O); P(O); } +inline void el4D::Transform::SXZY(D4OBJ O) { S(O); X(O); Z(O); Y(O); } +inline void el4D::Transform::SYPX(D4OBJ O) { S(O); Y(O); P(O); X(O); } +inline void el4D::Transform::SYPZ(D4OBJ O) { S(O); Y(O); P(O); Z(O); } +inline void el4D::Transform::SYXP(D4OBJ O) { S(O); Y(O); X(O); P(O); } +inline void el4D::Transform::SYXZ(D4OBJ O) { S(O); Y(O); X(O); Z(O); } +inline void el4D::Transform::SYZP(D4OBJ O) { S(O); Y(O); Z(O); P(O); } +inline void el4D::Transform::SYZX(D4OBJ O) { S(O); Y(O); Z(O); X(O); } +inline void el4D::Transform::SZPX(D4OBJ O) { S(O); Z(O); P(O); X(O); } +inline void el4D::Transform::SZPY(D4OBJ O) { S(O); Z(O); P(O); Y(O); } +inline void el4D::Transform::SZXP(D4OBJ O) { S(O); Z(O); X(O); P(O); } +inline void el4D::Transform::SZXY(D4OBJ O) { S(O); Z(O); X(O); Y(O); } +inline void el4D::Transform::SZYP(D4OBJ O) { S(O); Z(O); Y(O); P(O); } +inline void el4D::Transform::SZYX(D4OBJ O) { S(O); Z(O); Y(O); X(O); } +inline void el4D::Transform::PXYZS(D4OBJ O) { P(O); X(O); Y(O); Z(O); S(O); } +inline void el4D::Transform::PXYSZ(D4OBJ O) { P(O); X(O); Y(O); S(O); Z(O); } +inline void el4D::Transform::PXZYS(D4OBJ O) { P(O); X(O); Z(O); Y(O); S(O); } +inline void el4D::Transform::PXZSY(D4OBJ O) { P(O); X(O); Z(O); S(O); Y(O); } +inline void el4D::Transform::PXSYZ(D4OBJ O) { P(O); X(O); S(O); Y(O); Z(O); } +inline void el4D::Transform::PXSZY(D4OBJ O) { P(O); X(O); S(O); Z(O); Y(O); } +inline void el4D::Transform::PYXZS(D4OBJ O) { P(O); Y(O); X(O); Z(O); S(O); } +inline void el4D::Transform::PYXSZ(D4OBJ O) { P(O); Y(O); X(O); S(O); Z(O); } +inline void el4D::Transform::PYZXS(D4OBJ O) { P(O); Y(O); Z(O); X(O); S(O); } +inline void el4D::Transform::PYZSX(D4OBJ O) { P(O); Y(O); Z(O); S(O); X(O); } +inline void el4D::Transform::PYSXZ(D4OBJ O) { P(O); Y(O); S(O); X(O); Z(O); } +inline void el4D::Transform::PYSZX(D4OBJ O) { P(O); Y(O); S(O); Z(O); X(O); } +inline void el4D::Transform::PZXYS(D4OBJ O) { P(O); Z(O); X(O); Y(O); S(O); } +inline void el4D::Transform::PZXSY(D4OBJ O) { P(O); Z(O); X(O); S(O); Y(O); } +inline void el4D::Transform::PZYXS(D4OBJ O) { P(O); Z(O); Y(O); X(O); S(O); } +inline void el4D::Transform::PZYSX(D4OBJ O) { P(O); Z(O); Y(O); S(O); X(O); } +inline void el4D::Transform::PZSXY(D4OBJ O) { P(O); Z(O); S(O); X(O); Y(O); } +inline void el4D::Transform::PZSYX(D4OBJ O) { P(O); Z(O); S(O); Y(O); X(O); } +inline void el4D::Transform::PSXYZ(D4OBJ O) { P(O); S(O); X(O); Y(O); Z(O); } +inline void el4D::Transform::PSXZY(D4OBJ O) { P(O); S(O); X(O); Z(O); Y(O); } +inline void el4D::Transform::PSYXZ(D4OBJ O) { P(O); S(O); Y(O); X(O); Z(O); } +inline void el4D::Transform::PSYZX(D4OBJ O) { P(O); S(O); Y(O); Z(O); X(O); } +inline void el4D::Transform::PSZXY(D4OBJ O) { P(O); S(O); Z(O); X(O); Y(O); } +inline void el4D::Transform::PSZYX(D4OBJ O) { P(O); S(O); Z(O); Y(O); X(O); } +inline void el4D::Transform::XPYZS(D4OBJ O) { X(O); P(O); Y(O); Z(O); S(O); } +inline void el4D::Transform::XPYSZ(D4OBJ O) { X(O); P(O); Y(O); S(O); Z(O); } +inline void el4D::Transform::XPZYS(D4OBJ O) { X(O); P(O); Z(O); Y(O); S(O); } +inline void el4D::Transform::XPZSY(D4OBJ O) { X(O); P(O); Z(O); S(O); Y(O); } +inline void el4D::Transform::XPSYZ(D4OBJ O) { X(O); P(O); S(O); Y(O); Z(O); } +inline void el4D::Transform::XPSZY(D4OBJ O) { X(O); P(O); S(O); Z(O); Y(O); } +inline void el4D::Transform::XYPZS(D4OBJ O) { X(O); Y(O); P(O); Z(O); S(O); } +inline void el4D::Transform::XYPSZ(D4OBJ O) { X(O); Y(O); P(O); S(O); Z(O); } +inline void el4D::Transform::XYZPS(D4OBJ O) { X(O); Y(O); Z(O); P(O); S(O); } +inline void el4D::Transform::XYZSP(D4OBJ O) { X(O); Y(O); Z(O); S(O); P(O); } +inline void el4D::Transform::XYSPZ(D4OBJ O) { X(O); Y(O); S(O); P(O); Z(O); } +inline void el4D::Transform::XYSZP(D4OBJ O) { X(O); Y(O); S(O); Z(O); P(O); } +inline void el4D::Transform::XZPYS(D4OBJ O) { X(O); Z(O); P(O); Y(O); S(O); } +inline void el4D::Transform::XZPSY(D4OBJ O) { X(O); Z(O); P(O); S(O); Y(O); } +inline void el4D::Transform::XZYPS(D4OBJ O) { X(O); Z(O); Y(O); P(O); S(O); } +inline void el4D::Transform::XZYSP(D4OBJ O) { X(O); Z(O); Y(O); S(O); P(O); } +inline void el4D::Transform::XZSPY(D4OBJ O) { X(O); Z(O); S(O); P(O); Y(O); } +inline void el4D::Transform::XZSYP(D4OBJ O) { X(O); Z(O); S(O); Y(O); P(O); } +inline void el4D::Transform::XSPYZ(D4OBJ O) { X(O); S(O); P(O); Y(O); Z(O); } +inline void el4D::Transform::XSPZY(D4OBJ O) { X(O); S(O); P(O); Z(O); Y(O); } +inline void el4D::Transform::XSYPZ(D4OBJ O) { X(O); S(O); Y(O); P(O); Z(O); } +inline void el4D::Transform::XSYZP(D4OBJ O) { X(O); S(O); Y(O); Z(O); P(O); } +inline void el4D::Transform::XSZPY(D4OBJ O) { X(O); S(O); Z(O); P(O); Y(O); } +inline void el4D::Transform::XSZYP(D4OBJ O) { X(O); S(O); Z(O); Y(O); P(O); } +inline void el4D::Transform::YPXZS(D4OBJ O) { Y(O); P(O); X(O); Z(O); S(O); } +inline void el4D::Transform::YPXSZ(D4OBJ O) { Y(O); P(O); X(O); S(O); Z(O); } +inline void el4D::Transform::YPZXS(D4OBJ O) { Y(O); P(O); Z(O); X(O); S(O); } +inline void el4D::Transform::YPZSX(D4OBJ O) { Y(O); P(O); Z(O); S(O); X(O); } +inline void el4D::Transform::YPSXZ(D4OBJ O) { Y(O); P(O); S(O); X(O); Z(O); } +inline void el4D::Transform::YPSZX(D4OBJ O) { Y(O); P(O); S(O); Z(O); X(O); } +inline void el4D::Transform::YXPZS(D4OBJ O) { Y(O); X(O); P(O); Z(O); S(O); } +inline void el4D::Transform::YXPSZ(D4OBJ O) { Y(O); X(O); P(O); S(O); Z(O); } +inline void el4D::Transform::YXZPS(D4OBJ O) { Y(O); X(O); Z(O); P(O); S(O); } +inline void el4D::Transform::YXZSP(D4OBJ O) { Y(O); X(O); Z(O); S(O); P(O); } +inline void el4D::Transform::YXSPZ(D4OBJ O) { Y(O); X(O); S(O); P(O); Z(O); } +inline void el4D::Transform::YXSZP(D4OBJ O) { Y(O); X(O); S(O); Z(O); P(O); } +inline void el4D::Transform::YZPXS(D4OBJ O) { Y(O); Z(O); P(O); X(O); S(O); } +inline void el4D::Transform::YZPSX(D4OBJ O) { Y(O); Z(O); P(O); S(O); X(O); } +inline void el4D::Transform::YZXPS(D4OBJ O) { Y(O); Z(O); X(O); P(O); S(O); } +inline void el4D::Transform::YZXSP(D4OBJ O) { Y(O); Z(O); X(O); S(O); P(O); } +inline void el4D::Transform::YZSPX(D4OBJ O) { Y(O); Z(O); S(O); P(O); X(O); } +inline void el4D::Transform::YZSXP(D4OBJ O) { Y(O); Z(O); S(O); X(O); P(O); } +inline void el4D::Transform::YSPXZ(D4OBJ O) { Y(O); S(O); P(O); X(O); Z(O); } +inline void el4D::Transform::YSPZX(D4OBJ O) { Y(O); S(O); P(O); Z(O); X(O); } +inline void el4D::Transform::YSXPZ(D4OBJ O) { Y(O); S(O); X(O); P(O); Z(O); } +inline void el4D::Transform::YSXZP(D4OBJ O) { Y(O); S(O); X(O); Z(O); P(O); } +inline void el4D::Transform::YSZPX(D4OBJ O) { Y(O); S(O); Z(O); P(O); X(O); } +inline void el4D::Transform::YSZXP(D4OBJ O) { Y(O); S(O); Z(O); X(O); P(O); } +inline void el4D::Transform::ZPXYS(D4OBJ O) { Z(O); P(O); X(O); Y(O); S(O); } +inline void el4D::Transform::ZPXSY(D4OBJ O) { Z(O); P(O); X(O); S(O); Y(O); } +inline void el4D::Transform::ZPYXS(D4OBJ O) { Z(O); P(O); Y(O); X(O); S(O); } +inline void el4D::Transform::ZPYSX(D4OBJ O) { Z(O); P(O); Y(O); S(O); X(O); } +inline void el4D::Transform::ZPSXY(D4OBJ O) { Z(O); P(O); S(O); X(O); Y(O); } +inline void el4D::Transform::ZPSYX(D4OBJ O) { Z(O); P(O); S(O); Y(O); X(O); } +inline void el4D::Transform::ZXPYS(D4OBJ O) { Z(O); X(O); P(O); Y(O); S(O); } +inline void el4D::Transform::ZXPSY(D4OBJ O) { Z(O); X(O); P(O); S(O); Y(O); } +inline void el4D::Transform::ZXYPS(D4OBJ O) { Z(O); X(O); Y(O); P(O); S(O); } +inline void el4D::Transform::ZXYSP(D4OBJ O) { Z(O); X(O); Y(O); S(O); P(O); } +inline void el4D::Transform::ZXSPY(D4OBJ O) { Z(O); X(O); S(O); P(O); Y(O); } +inline void el4D::Transform::ZXSYP(D4OBJ O) { Z(O); X(O); S(O); Y(O); P(O); } +inline void el4D::Transform::ZYPXS(D4OBJ O) { Z(O); Y(O); P(O); X(O); S(O); } +inline void el4D::Transform::ZYPSX(D4OBJ O) { Z(O); Y(O); P(O); S(O); X(O); } +inline void el4D::Transform::ZYXPS(D4OBJ O) { Z(O); Y(O); X(O); P(O); S(O); } +inline void el4D::Transform::ZYXSP(D4OBJ O) { Z(O); Y(O); X(O); S(O); P(O); } +inline void el4D::Transform::ZYSPX(D4OBJ O) { Z(O); Y(O); S(O); P(O); X(O); } +inline void el4D::Transform::ZYSXP(D4OBJ O) { Z(O); Y(O); S(O); X(O); P(O); } +inline void el4D::Transform::ZSPXY(D4OBJ O) { Z(O); S(O); P(O); X(O); Y(O); } +inline void el4D::Transform::ZSPYX(D4OBJ O) { Z(O); S(O); P(O); Y(O); X(O); } +inline void el4D::Transform::ZSXPY(D4OBJ O) { Z(O); S(O); X(O); P(O); Y(O); } +inline void el4D::Transform::ZSXYP(D4OBJ O) { Z(O); S(O); X(O); Y(O); P(O); } +inline void el4D::Transform::ZSYPX(D4OBJ O) { Z(O); S(O); Y(O); P(O); X(O); } +inline void el4D::Transform::ZSYXP(D4OBJ O) { Z(O); S(O); Y(O); X(O); P(O); } +inline void el4D::Transform::SPXYZ(D4OBJ O) { S(O); P(O); X(O); Y(O); Z(O); } +inline void el4D::Transform::SPXZY(D4OBJ O) { S(O); P(O); X(O); Z(O); Y(O); } +inline void el4D::Transform::SPYXZ(D4OBJ O) { S(O); P(O); Y(O); X(O); Z(O); } +inline void el4D::Transform::SPYZX(D4OBJ O) { S(O); P(O); Y(O); Z(O); X(O); } +inline void el4D::Transform::SPZXY(D4OBJ O) { S(O); P(O); Z(O); X(O); Y(O); } +inline void el4D::Transform::SPZYX(D4OBJ O) { S(O); P(O); Z(O); Y(O); X(O); } +inline void el4D::Transform::SXPYZ(D4OBJ O) { S(O); X(O); P(O); Y(O); Z(O); } +inline void el4D::Transform::SXPZY(D4OBJ O) { S(O); X(O); P(O); Z(O); Y(O); } +inline void el4D::Transform::SXYPZ(D4OBJ O) { S(O); X(O); Y(O); P(O); Z(O); } +inline void el4D::Transform::SXYZP(D4OBJ O) { S(O); X(O); Y(O); Z(O); P(O); } +inline void el4D::Transform::SXZPY(D4OBJ O) { S(O); X(O); Z(O); P(O); Y(O); } +inline void el4D::Transform::SXZYP(D4OBJ O) { S(O); X(O); Z(O); Y(O); P(O); } +inline void el4D::Transform::SYPXZ(D4OBJ O) { S(O); Y(O); P(O); X(O); Z(O); } +inline void el4D::Transform::SYPZX(D4OBJ O) { S(O); Y(O); P(O); Z(O); X(O); } +inline void el4D::Transform::SYXPZ(D4OBJ O) { S(O); Y(O); X(O); P(O); Z(O); } +inline void el4D::Transform::SYXZP(D4OBJ O) { S(O); Y(O); X(O); Z(O); P(O); } +inline void el4D::Transform::SYZPX(D4OBJ O) { S(O); Y(O); Z(O); P(O); X(O); } +inline void el4D::Transform::SYZXP(D4OBJ O) { S(O); Y(O); Z(O); X(O); P(O); } +inline void el4D::Transform::SZPXY(D4OBJ O) { S(O); Z(O); P(O); X(O); Y(O); } +inline void el4D::Transform::SZPYX(D4OBJ O) { S(O); Z(O); P(O); Y(O); X(O); } +inline void el4D::Transform::SZXPY(D4OBJ O) { S(O); Z(O); X(O); P(O); Y(O); } +inline void el4D::Transform::SZXYP(D4OBJ O) { S(O); Z(O); X(O); Y(O); P(O); } +inline void el4D::Transform::SZYPX(D4OBJ O) { S(O); Z(O); Y(O); P(O); X(O); } +inline void el4D::Transform::SZYXP(D4OBJ O) { S(O); Z(O); Y(O); X(O); P(O); } + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:ビューポートの設定 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::Viewport(int X1,int Y1,int X2,int Y2) +{ + D3DVIEWPORT7 vp; + + memset(&vp,0x00,sizeof(D3DVIEWPORT7)); + + vp.dwX=X1; + vp.dwY=Y1; + vp.dwWidth=X2-X1; + vp.dwHeight=Y2-Y1; + vp.dvMinZ=F(0); + vp.dvMaxZ=F(1); + + D3Device->SetViewport(&vp); + + Vx1=X1; + Vy1=Y1; + Vx2=X2; + Vy2=Y2; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:投影の設定 -*/ +/*- -*/ +/*- float Near : 手前のクリップ位置 -*/ +/*- 省略 = 直前に設定された値 -*/ +/*- float Far : 奥のクリップ位置 -*/ +/*- 省略 = 直前に設定された値 -*/ +/*- float Aspect : アスペクト比 -*/ +/*- 省略 = 高さ÷幅 -*/ +/*- float Fov : FOV -*/ +/*- 省略 = π÷3 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::Projection(float Near=Camera::Near, + float Far=Camera::Far, + float Aspect=F(Vy2-Vy1)/F(Vx2-Vx1), + float Fov=F(PAI)/F(3)) +{ + ProjectionMatrix._12=F(0); + ProjectionMatrix._13=F(0); + ProjectionMatrix._14=F(0); + ProjectionMatrix._21=F(0); + ProjectionMatrix._23=F(0); + ProjectionMatrix._24=F(0); + ProjectionMatrix._31=F(0); + ProjectionMatrix._32=F(0); + ProjectionMatrix._41=F(0); + ProjectionMatrix._42=F(0); + ProjectionMatrix._44=F(0); + + ProjectionMatrix._11=Aspect*(F(cos(Fov/F(2)))/F(sin(Fov/F(2)))); + ProjectionMatrix._22=F(1)*(F(cos(Fov/F(2)))/F(sin(Fov/F(2)))); + ProjectionMatrix._33=Far/(Far-Near); + ProjectionMatrix._34=F(1); + ProjectionMatrix._43=-(Far/(Far-Near))*Near; + + D3Device->SetTransform(D3DTRANSFORMSTATE_PROJECTION,&ProjectionMatrix); + + Camera::Near=Near; + Camera::Far=Far; + Camera::Aspect=Aspect; + Camera::Fov=Fov; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:移動 -*/ +/*- -*/ +/*- float Px : X座標の位置 ( -:左 / +:右 ) -*/ +/*- float Py : Y座標の位置 ( -:下 / +:上 ) -*/ +/*- float Pz : Z座標の位置 ( -:手前 / +:奥 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::Move(float Px,float Py,float Pz) +{ + PolyObj[CAMERA_OBJECT].Px=-Px; + PolyObj[CAMERA_OBJECT].Py=-Py; + PolyObj[CAMERA_OBJECT].Pz=-Pz; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:X座標移動 -*/ +/*- -*/ +/*- float Px : X座標の位置 ( -:左 / +:右 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::MoveX(float Px) +{ + PolyObj[CAMERA_OBJECT].Px=-Px; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:Y座標移動 -*/ +/*- -*/ +/*- float Py : Y座標の位置 ( -:下 / +:上 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::MoveY(float Py) +{ + PolyObj[CAMERA_OBJECT].Py=-Py; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:Z座標移動 -*/ +/*- -*/ +/*- float Pz : Z座標の位置 ( -:手前 / +:奥 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::MoveZ(float Pz) +{ + PolyObj[CAMERA_OBJECT].Pz=-Pz; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:回転 -*/ +/*- -*/ +/*- float Ax : X軸の角度 ( +:軸をプラス方向に見て時計回り / -:逆方向 ) -*/ +/*- float Ay : Y軸の角度 (           〃          ) -*/ +/*- float Az : Z軸の角度 (           〃          ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::Rotate(float Ax,float Ay,float Az) +{ + PolyObj[CAMERA_OBJECT].Ax=-Ax; + PolyObj[CAMERA_OBJECT].Ay=-Ay; + PolyObj[CAMERA_OBJECT].Az=-Az; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:X軸回転 -*/ +/*- -*/ +/*- float Ax : X軸の角度 ( +:軸をプラス方向に見て時計回り / -:逆方向 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::RotateX(float Ax) +{ + PolyObj[CAMERA_OBJECT].Ax=-Ax; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:Y軸回転 -*/ +/*- -*/ +/*- float Ay : Y軸の角度 ( +:軸をプラス方向に見て時計回り / -:逆方向 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::RotateY(float Ay) +{ + PolyObj[CAMERA_OBJECT].Ay=-Ay; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:Z軸回転 -*/ +/*- -*/ +/*- float Az : Z軸の角度 ( +:軸をプラス方向に見て時計回り / -:逆方向 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::RotateZ(float Az) +{ + PolyObj[CAMERA_OBJECT].Az=-Az; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:マトリクス変換 ( 静的 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::StaticTransform(void) +{ + D3Device->SetTransform(D3DTRANSFORMSTATE_VIEW, + &PolyObj[CAMERA_OBJECT].Matrix); + D3Device->GetTransform(D3DTRANSFORMSTATE_VIEW,&ViewMatrix); + + // 座標取得用 + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD, + &PolyObj[CAMERA_OBJECT].Matrix); + D3Device->GetTransform(D3DTRANSFORMSTATE_WORLD, + &PolyObj[CAMERA_OBJECT].ObjectMatrix); + + InitMatrix(CAMERA_OBJECT); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:マトリクス変換 ( 動的 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::DynamicTransform(void) +{ + mat1=ViewMatrix*PolyObj[CAMERA_OBJECT].Matrix; + + D3Device->SetTransform(D3DTRANSFORMSTATE_VIEW,&mat1); + D3Device->GetTransform(D3DTRANSFORMSTATE_VIEW,&ViewMatrix); + + // 座標取得用 + D3Device->SetTransform(D3DTRANSFORMSTATE_WORLD, + &PolyObj[CAMERA_OBJECT].ObjectMatrix); + D3Device->MultiplyTransform(D3DTRANSFORMSTATE_WORLD, + &PolyObj[CAMERA_OBJECT].Matrix); + D3Device->GetTransform(D3DTRANSFORMSTATE_WORLD, + &PolyObj[CAMERA_OBJECT].ObjectMatrix); + + InitMatrix(CAMERA_OBJECT); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:すでに変換されたマトリクスを読み込み -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::LoadMatrix(void) +{ + D3Device->SetTransform(D3DTRANSFORMSTATE_VIEW,&ViewMatrix); + + InitMatrix(CAMERA_OBJECT); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:任意のマトリクス情報を設定 -*/ +/*- -*/ +/*- D4MTX& MtxD4 : マトリクス情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::SetMatrix(D4MTX& MtxD4) +{ + ViewMatrix=MtxD4; + + D3Device->SetTransform(D3DTRANSFORMSTATE_VIEW,&ViewMatrix); + + InitMatrix(CAMERA_OBJECT); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:変換されたマトリクス情報の取得 -*/ +/*- -*/ +/*- 戻り値 : マトリクス情報 ( D4MTX型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline D4MTX& el4D::Camera::GetMatrix(void) +{ + return ViewMatrix; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:ワールド座標の取得 -*/ +/*- -*/ +/*- ※ el4D::Camera::StaticTransform関数、DynamicTransform関数の後に使用 -*/ +/*- -*/ +/*- ( 戻り値 ) : PolyObj[CAMERA_OBJECT].PosX〜PosZに格納 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::GetPosition(void) +{ + PolyObj[CAMERA_OBJECT].PosX=PolyObj[CAMERA_OBJECT].ObjectMatrix._41; + PolyObj[CAMERA_OBJECT].PosY=PolyObj[CAMERA_OBJECT].ObjectMatrix._42; + PolyObj[CAMERA_OBJECT].PosZ=-PolyObj[CAMERA_OBJECT].ObjectMatrix._43; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:指定された位置を注視 -*/ +/*- -*/ +/*- ※ el4D::Camera::StaticTransform関数、DynamicTransform関数の後に使用 -*/ +/*- -*/ +/*- float Lx : 注視点のX座標 -*/ +/*- float Ly : 注視点のY座標 -*/ +/*- float Lz : 注視点のZ座標 -*/ +/*- float Ux : アップXベクトル -*/ +/*- 省略 = 0 -*/ +/*- float Uy : アップYベクトル -*/ +/*- 省略 = 1 -*/ +/*- float Uz : アップZベクトル -*/ +/*- 省略 = 0 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline BOOL el4D::Camera::LookAt(float Lx,float Ly,float Lz, + float Ux=F(0),float Uy=F(1),float Uz=F(0)) +{ + static D3DVECTOR from,at,view,up,right; + static float length; + + // 見る側の位置を取得 + GetPosition(); + + from=D3DVECTOR(PolyObj[CAMERA_OBJECT].PosX,PolyObj[CAMERA_OBJECT].PosY, + PolyObj[CAMERA_OBJECT].PosZ); + + // 見られる側の位置を取得 + at=D3DVECTOR(Lx,Ly,Lz); + + // 視点のZベクトルを取得 + view=at-from; + length=Magnitude(view); + if (length<1e-6f) return FALSE; + view/=length; + up=D3DVECTOR(Ux,Uy,Uz)-DotProduct(D3DVECTOR(Ux,Uy,Uz),view)*view; + length=Magnitude(up); + + // 正しいアップベクトルの検索 + if (length<1e-6f) + { + up=D3DVECTOR(F(0),F(1),F(0))-view.y*view; + length=Magnitude(up); + + if (length<1e-6f) + { + up=D3DVECTOR(F(0),F(0),F(1))-view.z*view; + length=Magnitude(up); + + if (length<1e-6f) return FALSE; + } + } + + // Y及びXベクトルを取得 + up/=length; + right=CrossProduct(up,view); + + // 注視 + mat1._14=F(0); + mat1._24=F(0); + mat1._34=F(0); + mat1._44=F(1); + + mat1._11=right.x; + mat1._12=up.x; + mat1._13=view.x; + mat1._21=right.y; + mat1._22=up.y; + mat1._23=view.y; + mat1._31=right.z; + mat1._32=up.z; + mat1._33=view.z; + mat1._41=-DotProduct(from,right); + mat1._42=-DotProduct(from,up); + mat1._43=-DotProduct(from,view); + + D3Device->SetTransform(D3DTRANSFORMSTATE_VIEW,&mat1); + D3Device->GetTransform(D3DTRANSFORMSTATE_VIEW,&ViewMatrix); + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:オブジェクトを注視 -*/ +/*- -*/ +/*- ※ el4D::Camera::StaticTransform関数、DynamicTransform関数の後に使用 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float Ux : アップXベクトル -*/ +/*- 省略 = 0 -*/ +/*- float Uy : アップYベクトル -*/ +/*- 省略 = 1 -*/ +/*- float Uz : アップZベクトル -*/ +/*- 省略 = 0 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::LookAtObject(D4OBJ ObjD4,float Ux=F(0),float Uy=F(1), + float Uz=F(0)) +{ + Object::GetPosition(ObjD4); + + LookAt(PolyObj[ObjD4].PosX,PolyObj[ObjD4].PosY,PolyObj[ObjD4].PosZ,Ux,Uy,Uz); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:オブジェクトのミラー視点に設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::ObjectMirror(D4OBJ ObjD4) +{ + D4MTX Matrix; + + Matrix._14=F(0); + Matrix._24=F(0); + Matrix._34=F(0); + Matrix._44=F(1); + + // オブジェクトからカメラを見た視点に設定 + Matrix._11=ViewMatrix._11; + Matrix._12=ViewMatrix._21; + Matrix._13=ViewMatrix._31; + Matrix._21=ViewMatrix._12; + Matrix._22=ViewMatrix._22; + Matrix._23=ViewMatrix._32; + Matrix._31=-ViewMatrix._13; + Matrix._32=-ViewMatrix._23; + Matrix._33=-ViewMatrix._33; + + // オブジェクトの位置に設定 + Matrix._41=PolyObj[ObjD4].ObjectMatrix._21+PolyObj[ObjD4].ObjectMatrix._31+ + PolyObj[ObjD4].ObjectMatrix._41; + Matrix._42=PolyObj[ObjD4].ObjectMatrix._12+PolyObj[ObjD4].ObjectMatrix._32+ + PolyObj[ObjD4].ObjectMatrix._42; + Matrix._43=PolyObj[ObjD4].ObjectMatrix._13+PolyObj[ObjD4].ObjectMatrix._23+ + PolyObj[ObjD4].ObjectMatrix._43; + + D3Device->SetTransform(D3DTRANSFORMSTATE_VIEW,&Matrix); + + State::Reverse(TRUE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:オブジェクトのミラー視点から復元 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::ObjectMirror(void) +{ + // 視点を復元 + D3Device->SetTransform(D3DTRANSFORMSTATE_VIEW,&ViewMatrix); + + State::Reverse(FALSE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カメラ:ズーム -*/ +/*- -*/ +/*- float Zm : ズーム値 ( 0.1〜3.14 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Camera::Zoom(float Zm) +{ + Fov=Zm; + + ProjectionMatrix._12=F(0); + ProjectionMatrix._13=F(0); + ProjectionMatrix._14=F(0); + ProjectionMatrix._21=F(0); + ProjectionMatrix._23=F(0); + ProjectionMatrix._24=F(0); + ProjectionMatrix._31=F(0); + ProjectionMatrix._32=F(0); + ProjectionMatrix._41=F(0); + ProjectionMatrix._42=F(0); + ProjectionMatrix._44=F(0); + + ProjectionMatrix._11=Aspect*(F(cos(Fov/F(2)))/F(sin(Fov/F(2)))); + ProjectionMatrix._22=F(1)*(F(cos(Fov/F(2)))/F(sin(Fov/F(2)))); + ProjectionMatrix._33=Far/(Far-Near); + ProjectionMatrix._34=F(1); + ProjectionMatrix._43=-(Far/(Far-Near))*Near; + + D3Device->SetTransform(D3DTRANSFORMSTATE_PROJECTION,&ProjectionMatrix); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライト:生成 -*/ +/*- -*/ +/*- int Type : ライトタイプ -*/ +/*- LIGHT_DIR = 方位光源 -*/ +/*- LIGHT_SPOT = スポットライト -*/ +/*- LIGHT_POINT = 点光源 -*/ +/*- -*/ +/*- 戻り値 : ライト情報 ( D4LGT型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D4LGT el4D::Light::Create(int Type) +{ + int i; + D4LGT LgtD4=-1; + + // 使用可能なライトオブジェクトの検索 + for (i=0;iLightEnable(LgtD4,FALSE); + + LightObj[LgtD4].Use=FALSE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライト:表示 -*/ +/*- -*/ +/*- D4LGT LgtD4 : ライトオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Light::Show(D4LGT LgtD4) +{ + D3Device->LightEnable(LgtD4,TRUE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライト:非表示 -*/ +/*- -*/ +/*- D4LGT LgtD4 : ライトオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Light::Hide(D4LGT LgtD4) +{ + D3Device->LightEnable(LgtD4,FALSE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライト:更新 -*/ +/*- -*/ +/*- D4LGT LgtD4 : ライトオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Light::Update(D4LGT LgtD4) +{ + D3Device->SetLight(LgtD4,&LightObj[LgtD4].Data); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライト:色の設定 -*/ +/*- -*/ +/*- D4LGT LgtD4 : ライトオブジェクト情報 -*/ +/*- float R : 赤の強さ ( 0.0〜1.0 ) -*/ +/*- float G : 緑の強さ ( 0.0〜1.0 ) -*/ +/*- float B : 青の強さ ( 0.0〜1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Light::Color(D4LGT LgtD4,float R,float G,float B) +{ + LightObj[LgtD4].Data.dcvDiffuse.r=R; + LightObj[LgtD4].Data.dcvDiffuse.g=G; + LightObj[LgtD4].Data.dcvDiffuse.b=B; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライト:反射色の設定 -*/ +/*- -*/ +/*- D4LGT LgtD4 : ライトオブジェクト情報 -*/ +/*- float R : 赤の強さ ( 0.0〜1.0 ) -*/ +/*- float G : 緑の強さ ( 0.0〜1.0 ) -*/ +/*- float B : 青の強さ ( 0.0〜1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Light::Specular(D4LGT LgtD4,float R,float G,float B) +{ + LightObj[LgtD4].Data.dcvSpecular.r=R; + LightObj[LgtD4].Data.dcvSpecular.g=G; + LightObj[LgtD4].Data.dcvSpecular.b=B; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライト:環境光の設定 -*/ +/*- -*/ +/*- float R : 赤の強さ ( 0.0〜1.0 ) -*/ +/*- float G : 緑の強さ ( 0.0〜1.0 ) -*/ +/*- float B : 青の強さ ( 0.0〜1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Light::Ambient(float R,float G,float B) +{ + D3Device->SetRenderState(D3DRENDERSTATE_AMBIENT,D3DRGB(R,G,B)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライト:スポットライトの大きさの設定 -*/ +/*- -*/ +/*- D4LGT LgtD4 : ライトオブジェクト情報 -*/ +/*- float In : 内側の大きさ ( 0.0〜外側の大きさ ) -*/ +/*- float Out : 外側の大きさ ( 内側の大きさ〜3.14 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Light::SpotSize(D4LGT LgtD4,float In,float Out) +{ + LightObj[LgtD4].Data.dvTheta=In; + LightObj[LgtD4].Data.dvPhi=Out; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライト:スポットライトの強さの設定 -*/ +/*- -*/ +/*- D4LGT LgtD4 : ライトオブジェクト情報 -*/ +/*- float Power : 強さ ( 0.0〜1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Light::SpotPower(D4LGT LgtD4,float Power) +{ + LightObj[LgtD4].Data.dvAttenuation0=F(1)-Power; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライト:点光源の強さの設定 -*/ +/*- -*/ +/*- D4LGT LgtD4 : ライトオブジェクト情報 -*/ +/*- float Power : 強さ ( 0.0〜1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Light::PointPower(D4LGT LgtD4,float Power) +{ + LightObj[LgtD4].Data.dvAttenuation1=F(1)-Power; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライト:位置の設定 ※ 方位光源 ( LIGHT_DIR ) では無効 -*/ +/*- -*/ +/*- D4LGT LgtD4 : ライトオブジェクト情報 -*/ +/*- float Px : X座標の位置 ( -:左 / +:右 ) -*/ +/*- float Py : Y座標の位置 ( -:下 / +:上 ) -*/ +/*- float Pz : Z座標の位置 ( -:手前 / +:奥 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Light::Move(D4LGT LgtD4,float Px,float Py,float Pz) +{ + LightObj[LgtD4].Data.dvPosition=D3DVECTOR(Px,Py,Pz); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ライト:方向の設定 ( 注視点 ) ※ 点光源 ( LIGHT_POINT ) では無効 -*/ +/*- -*/ +/*- D4LGT LgtD4 : ライトオブジェクト情報 -*/ +/*- float Px : X座標の位置 ( -:左 / +:右 ) -*/ +/*- float Py : Y座標の位置 ( -:下 / +:上 ) -*/ +/*- float Pz : Z座標の位置 ( -:手前 / +:奥 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Light::Direction(D4LGT LgtD4,float Px,float Py,float Pz) +{ + LightObj[LgtD4].Data.dvDirection=D3DVECTOR(Px,Py,Pz); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:生成 -*/ +/*- -*/ +/*- int Sx : Xサイズ -*/ +/*- int Sy : Yサイズ -*/ +/*- -*/ +/*- 戻り値 : テクスチャー情報 ( D4TXR型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D4TXR el4D::Texture::Create(int Sx,int Sy) +{ + // スプライトをテクスチャー指定で生成 + return (D4TXR)elDraw::CreateObject(Sx,Sy,LOAD_TEXTURE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:レンダリング先として生成 -*/ +/*- -*/ +/*- int Sx : Xサイズ -*/ +/*- int Sy : Yサイズ -*/ +/*- -*/ +/*- 戻り値 : テクスチャー情報 ( D4TXR型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D4TXR el4D::Texture::CreateTarget(int Sx,int Sy) +{ + D4TXR TxrD4; + LPDIRECTDRAWSURFACE7 Z=NULL; + DDSURFACEDESC2 ddsd; + HRESULT ddret; + + // スプライトをターゲット指定で生成 + TxrD4=(D4TXR)elDraw::CreateObject(Sx,Sy,LOAD_TARGET); + + // Zバッファの生成 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC2)); + ddsd.dwSize=sizeof(DDSURFACEDESC2); + ddsd.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT; + ddsd.ddsCaps.dwCaps=DDSCAPS_ZBUFFER; + ddsd.dwWidth=Sx; + ddsd.dwHeight=Sy; + + memcpy(&ddsd.ddpfPixelFormat,&el4D::Config::ZBuffer,sizeof(DDPIXELFORMAT)); + + if (el4D::Config::Driver&DC4D_HAL) + { + // HALの場合はVRAMに生成 + ddsd.ddsCaps.dwCaps|=DDSCAPS_VIDEOMEMORY; + } + else + { + // HELの場合はRAMに生成 + ddsd.ddsCaps.dwCaps|=DDSCAPS_SYSTEMMEMORY; + } + + ddret=DDObject->CreateSurface(&ddsd,&Z,NULL); + + if (ddret!=DD_OK) + { + return (D4TXR) elDraw::Error("el4D::Texture::CreateTarget", + "Z Bufferが生成できません",ddret); + } + + // Zバッファの接続 + ddret=Sprite[TxrD4].Object->AddAttachedSurface(Z); + + if (ddret!=DD_OK) + { + return (D4TXR) elDraw::Error("el4D::Texture::CreateTarget", + "Z Bufferが接続できません",ddret); + } + + return TxrD4; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:読み込み -*/ +/*- -*/ +/*- char* FileName : BMPファイル名またはリソース名 -*/ +/*- int Alpha : アルファ付きテクスチャーの使用 -*/ +/*- 省略 = 通常のテクスチャー -*/ +/*- LOAD_ALPHA = アルファ付きテクスチャー -*/ +/*- -*/ +/*- 戻り値 : テクスチャー情報 ( D4TXR型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D4TXR el4D::Texture::Load(char* FileName,int AlphaBit=0) +{ + static D4TXR TxrD4; + + // アルファ付きテクスチャーとして読み込む場合 + if (AlphaBit==LOAD_ALPHA) + { + AlphaFormat=TRUE; + } + else + { + AlphaFormat=FALSE; + } + + // スプライトをテクスチャー指定で読み込み + TxrD4=(D4TXR)elDraw::LoadObject(FileName,LOAD_TEXTURE); + + // アルファビットの設定 + if (AlphaBit==LOAD_ALPHA) SetAlpha(TxrD4); + + return TxrD4; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:交換 -*/ +/*- -*/ +/*- char* FileName : BMPファイル名またはリソース名 -*/ +/*- D4TXR TxrD4 : テクスチャー情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::Texture::Swap(char* FileName,D4TXR TxrD4) +{ + // スプライトをテクスチャー指定で交換 + elDraw::SwapObject(FileName,TxrD4,LOAD_TEXTURE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:パックファイルの指定 -*/ +/*- -*/ +/*- char* PackName : パックファイル名 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::Texture::SetPack(char* PackName) +{ + elDraw::SetPack(PackName); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:読み込み ( パックファイル ) -*/ +/*- -*/ +/*- char* FileName : BMPファイル名 -*/ +/*- -*/ +/*- 戻り値 : テクスチャー情報 ( D4TXR型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D4TXR el4D::Texture::LoadPack(char* FileName) +{ + // スプライトをテクスチャー指定で読み込み + return (D4TXR)elDraw::LoadPack(FileName,LOAD_TEXTURE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:交換 ( パックファイル ) -*/ +/*- -*/ +/*- char* FileName : BMPファイル名 -*/ +/*- D4TXR TxrD4 : テクスチャー情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::Texture::SwapPack(char* FileName,D4TXR TxrD4) +{ + // スプライトをテクスチャー指定で交換 + elDraw::SwapPack(FileName,TxrD4,LOAD_TEXTURE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:削除してメモリから開放 -*/ +/*- -*/ +/*- D4TXR TxrD4 : テクスチャー情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Texture::Free(D4TXR TxrD4) +{ + elDraw::FreeObject(TxrD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:オブジェクトに設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- D4TXR TxrD4 : テクスチャー情報 -*/ +/*- 省略 = テクスチャーを剥がす -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Texture::Set(D4OBJ ObjD4,D4TXR TxrD4=-1) +{ + PolyObj[ObjD4].Texture=TxrD4; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:Xファイルオブジェクトに設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- D4TXR TxrD4 : テクスチャー情報 -*/ +/*- 省略 = テクスチャーを剥がす -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Texture::SetX(D4OBJ ObjD4,D4TXR TxrD4=-1) +{ + D4OBJ i=ObjD4; // ポリゴンオブジェクト + int j; // 汎用カウンター + + while (TRUE) + { + // ポリゴンデータの場合 + if (PolyObj[i].VertexType!=POLYOBJ_FRAME) + { + PolyObj[i].Texture=TxrD4; + + for (j=0;jSetRenderState(D3DRENDERSTATE_COLORKEYENABLE,Flag); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:フィルターの設定 -*/ +/*- -*/ +/*- int Min : フィルタータイプ ( 縮小時 ) -*/ +/*- FILTER_NONE = フィルターなし -*/ +/*- FILTER_LINEAR = リニア -*/ +/*- int Mag : フィルタータイプ ( 拡大時 ) -*/ +/*- 省略 = 縮小時と同様なフィルター -*/ +/*- FILTER_NONE = フィルターなし -*/ +/*- FILTER_LINEAR = リニア -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Texture::Filter(int Min,int Mag=-1) +{ + // 縮小時のフィルター選択 + switch (Min) + { + // フィルターなし + case FILTER_NONE: + { + D3Device->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTFN_POINT); + + break; + } + + // リニア + case FILTER_LINEAR: + { + D3Device->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTFN_LINEAR); + + break; + } + } + + // 縮小時と同様なフィルターの場合 + if (Mag==-1) Mag=Min; + + // 拡大時のフィルター選択 + switch (Mag) + { + // フィルターなし + case FILTER_NONE: + { + D3Device->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTFG_POINT); + + break; + } + + // リニア + case FILTER_LINEAR: + { + D3Device->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTFG_LINEAR); + + break; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:パースペクティブの設定 -*/ +/*- -*/ +/*- BOOL Flag : TRUE = 使用 -*/ +/*- FALSE = 未使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Texture::Perspective(BOOL Flag) +{ + D3Device->SetRenderState(D3DRENDERSTATE_TEXTUREPERSPECTIVE,Flag); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:オートマチックテクスチャーマネージャーの設定 -*/ +/*- -*/ +/*- BOOL Flag : TRUE = 使用 -*/ +/*- FALSE = 未使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::Texture::Atm(BOOL Flag) +{ + AtmMode=Flag; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:アルファビットの設定 -*/ +/*- -*/ +/*- D4TXR TxrD4 : テクスチャー情報 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL el4D::Texture::SetAlpha(D4TXR TxrD4) +{ + static DDSURFACEDESC ddsd; + static LPWORD data16; + static WORD Alpha16,Buff16; + static LPDWORD data32; + static DWORD Alpha32,Buff32; + static DWORD AddPitch; + static int x,y; + + // 構造体の初期化 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + + // テクスチャーのロック + if (Sprite[TxrD4].Object->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL)) return FALSE; + + // 16ビットカラーの場合 + if (Texture::Format[Texture::AlphaTexture].dwRGBBitCount==16) + { + // Y方向への追加バイト数の取得 + AddPitch=ddsd.lPitch>>1; + + // テクスチャーの先頭位置を取得 + data16=(LPWORD)ddsd.lpSurface; + + // アルファビットの取得 + Alpha16=(WORD)Texture::Format[Texture::AlphaTexture].dwRGBAlphaBitMask; + + // データ転送 + for (y=0;y>2; + + // テクスチャーの先頭位置を取得 + data32=(LPDWORD)ddsd.lpSurface; + + // アルファビットの取得 + Alpha32=(DWORD)Texture::Format[Texture::AlphaTexture].dwRGBAlphaBitMask; + + // データ転送 + for (y=0;y0 && x0 && ynx; + Ny=(PolyObj[ObjD4].Vertex+i)->ny; + Nz=(PolyObj[ObjD4].Vertex+i)->nz; + + (PolyObj[ObjD4].Vertex+i)->tu=F(0.5)*(F(1)+(Nx*Matrix._11+ + Ny*Matrix._21+Nz*Matrix._31)); + (PolyObj[ObjD4].Vertex+i)->tv=F(0.5)*(F(1)-(Nx*Matrix._12+ + Ny*Matrix._22+Nz*Matrix._32)); + } + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:Xファイルオブジェクトに環境マッピング -*/ +/*- -*/ +/*- ※ el4D::Object::StaticTransform関数、DynamicTransform関数の後に使用 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Texture::EnvMapX(D4OBJ ObjD4) +{ + int i; // 汎用カウンター + D4OBJ j=ObjD4; // ポリゴンオブジェクト + D4MTX TopMatrix,Matrix; // マトリクス + float Nx,Ny,Nz; // 法線 + + // オブジェクト×ビューのマトリクスを取得 + TopMatrix=PolyObj[j].ObjectMatrix*el4D::Camera::ViewMatrix; + Matrix=TopMatrix; + + while (TRUE) + { + // ポリゴンデータの場合 + if (PolyObj[j].VertexType!=POLYOBJ_FRAME) + { + if (ObjD4!=j) Matrix=PolyObj[j].ObjectMatrix*TopMatrix; + + // 環境マッピング + if (el4D::Lock(j)) + { + for (i=0;inx; + Ny=(PolyObj[j].Vertex+i)->ny; + Nz=(PolyObj[j].Vertex+i)->nz; + + (PolyObj[j].Vertex+i)->tu=F(0.5)*(F(1)+(Nx*Matrix._11+ + Ny*Matrix._21+Nz*Matrix._31)); + (PolyObj[j].Vertex+i)->tv=F(0.5)*(F(1)-(Nx*Matrix._12+ + Ny*Matrix._22+Nz*Matrix._32)); + } + + el4D::Unlock(j); + } + } + + // これ以上オブジェクトがない場合、終了 + if (PolyObj[j++].Next==-1) break; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:マルチマテリアルへ保存 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : マルチマテリアルNo ( 0〜3 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Texture::MMSave(D4OBJ ObjD4,int No) +{ + PolyObj[ObjD4].Mt[No][0]=PolyObj[ObjD4].Texture; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- テクスチャー:Xファイルオブジェクトのマルチマテリアルへ保存 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int No : マルチマテリアルNo ( 0〜3 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Texture::MMSaveX(D4OBJ ObjD4,int No) +{ + D4OBJ i=ObjD4; // ポリゴンオブジェクト + int j; // 汎用カウンター + + while (TRUE) + { + // ポリゴンデータの場合 + if (PolyObj[i].VertexType!=POLYOBJ_FRAME) + { + PolyObj[i].Mt[No][0]=PolyObj[i].Texture; + + for (j=0;jSetRenderState(D3DRENDERSTATE_FOGENABLE,TRUE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フォグ:非表示 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Fog::Hide(void) +{ + D3Device->SetRenderState(D3DRENDERSTATE_FOGENABLE,FALSE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フォグ:色の設定 -*/ +/*- -*/ +/*- float R : 赤の強さ ( 0.0〜1.0 ) -*/ +/*- float G : 緑の強さ ( 0.0〜1.0 ) -*/ +/*- float B : 青の強さ ( 0.0〜1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Fog::Color(float R,float G,float B) +{ + D3Device->SetRenderState(D3DRENDERSTATE_FOGCOLOR,D3DRGB(R,G,B)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フォグ:範囲の設定 -*/ +/*- -*/ +/*- float Start : フォグの開始位置 -*/ +/*- float End : 最大のフォグ効果になる位置 -*/ +/*- BOOL Real : フォグの広がり方 -*/ +/*- 省略/FALSE = 視点と水平にフォグ発生 -*/ +/*- TRUE = 視点から円状に正しい距離でフォグ発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Fog::Range(float Start,float End,BOOL Real=FALSE) +{ + D3Device->SetRenderState(D3DRENDERSTATE_FOGSTART,*(DWORD*)(&Start)); + D3Device->SetRenderState(D3DRENDERSTATE_FOGEND,*(DWORD*)(&End)); + D3Device->SetRenderState(D3DRENDERSTATE_RANGEFOGENABLE,Real); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マテリアル:基本色の設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float R : 赤の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float G : 緑の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float B : 青の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Material::Color(D4OBJ ObjD4,float R,float G,float B) +{ + PolyObj[ObjD4].Material.diffuse.r=R; + PolyObj[ObjD4].Material.diffuse.g=G; + PolyObj[ObjD4].Material.diffuse.b=B; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マテリアル:Xファイルオブジェクトの基本色の設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float R : 赤の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float G : 緑の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float B : 青の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Material::ColorX(D4OBJ ObjD4,float R,float G,float B) +{ + D4OBJ i=ObjD4; // ポリゴンオブジェクト + int j; // 汎用カウンター + + while (TRUE) + { + // ポリゴンデータの場合 + if (PolyObj[i].VertexType!=POLYOBJ_FRAME) + { + PolyObj[i].Material.diffuse.r=R; + PolyObj[i].Material.diffuse.g=G; + PolyObj[i].Material.diffuse.b=B; + + for (j=0;jSetRenderState(D3DRENDERSTATE_ZENABLE,D3DZB_TRUE); + } + else + { + D3Device->SetRenderState(D3DRENDERSTATE_ZENABLE,D3DZB_FALSE); + } + + el4D::Clear::Z(Flag); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ステート:Wバッファの設定 -*/ +/*- -*/ +/*- BOOL Flag : TRUE = 使用 -*/ +/*- FALSE = 未使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::State::W(BOOL Flag) +{ + if (Flag) + { + D3Device->SetRenderState(D3DRENDERSTATE_ZENABLE,el4D::Config::WBuffer); + } + else + { + D3Device->SetRenderState(D3DRENDERSTATE_ZENABLE,D3DZB_FALSE); + } + + el4D::Clear::Z(Flag); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ステート:Zバッファの比較設定 -*/ +/*- -*/ +/*- int Mode : Zバッファ比較タイプ -*/ +/*- 省略/Z_DEFAULT = デフォルト ( Z_LESSEQUALと同じ ) -*/ +/*- Z_NOCHECK = Z値の比較なし ( 無条件レンダリング ) -*/ +/*- Z_EQUAL = Z値が等しい -*/ +/*- Z_NOTEQUAL = Z値が等しくない -*/ +/*- Z_LESS = Z値が小さい -*/ +/*- Z_LESSEQUAL = Z値以下 -*/ +/*- Z_GREATER = Z値が大きい -*/ +/*- Z_GREATEREQUAL = Z値以上 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::State::CheckZ(int Mode=Z_DEFAULT) +{ + D3Device->SetRenderState(D3DRENDERSTATE_ZFUNC,Mode); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ステート:Zバッファへの書き込み設定 -*/ +/*- -*/ +/*- BOOL Flag : TRUE = 書き込む -*/ +/*- FALSE = 書き込まない -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::State::WriteZ(BOOL Flag) +{ + D3Device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE,Flag); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ステート:ディザの設定 -*/ +/*- -*/ +/*- BOOL Flag : TRUE = 使用 -*/ +/*- FALSE = 未使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::State::Dither(BOOL Flag) +{ + D3Device->SetRenderState(D3DRENDERSTATE_DITHERENABLE,Flag); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ステート:反射特性の設定 -*/ +/*- -*/ +/*- BOOL Flag : TRUE = 使用 -*/ +/*- FALSE = 未使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::State::Specular(BOOL Flag) +{ + D3Device->SetRenderState(D3DRENDERSTATE_SPECULARENABLE,Flag); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ステート:シェードタイプの設定 -*/ +/*- -*/ +/*- int Type : シェードタイプ -*/ +/*- SHADE_GOURAUD = グーロー -*/ +/*- SHADE_FLAT = フラット -*/ +/*- SHADE_WIREFRAME = ワイヤーフレーム -*/ +/*- SHADE_POINT = ポイント -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::State::Shade(int Type) +{ + switch (Type) + { + // グーロー + case SHADE_GOURAUD: + { + D3Device->SetRenderState(D3DRENDERSTATE_SHADEMODE,D3DSHADE_GOURAUD); + D3Device->SetRenderState(D3DRENDERSTATE_FILLMODE,D3DFILL_SOLID); + + break; + } + + // フラット + case SHADE_FLAT: + { + D3Device->SetRenderState(D3DRENDERSTATE_SHADEMODE,D3DSHADE_FLAT); + D3Device->SetRenderState(D3DRENDERSTATE_FILLMODE,D3DFILL_SOLID); + + break; + } + + // ワイヤーフレーム + case SHADE_WIREFRAME: + { + D3Device->SetRenderState(D3DRENDERSTATE_SHADEMODE,D3DSHADE_FLAT); + D3Device->SetRenderState(D3DRENDERSTATE_FILLMODE,D3DFILL_WIREFRAME); + + break; + } + + // ポイント + case SHADE_POINT: + { + D3Device->SetRenderState(D3DRENDERSTATE_SHADEMODE,D3DSHADE_FLAT); + D3Device->SetRenderState(D3DRENDERSTATE_FILLMODE,D3DFILL_POINT); + + break; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ステート:アンチエイリアスの設定 -*/ +/*- -*/ +/*- BOOL Flag : TRUE = 使用 -*/ +/*- FALSE = 未使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::State::Antialias(BOOL Flag) +{ + if (Flag) + { + D3Device->SetRenderState(D3DRENDERSTATE_ANTIALIAS, + el4D::Config::Antialias); + } + else + { + D3Device->SetRenderState(D3DRENDERSTATE_ANTIALIAS,D3DANTIALIAS_NONE); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ステート:アルファブレンドの設定 -*/ +/*- -*/ +/*- int Mode : アルファブレンドタイプ -*/ +/*- ALPHA_NONE = アルファブレンドなし -*/ +/*- ALPHA_NORMAL = 通常 -*/ +/*- ALPHA_ADD = 加算 -*/ +/*- ALPHA_DELETE = 減算 -*/ +/*- ALPHA_REVERSE = 反転 ( アルファ値無効 ) -*/ +/*- ALPHA_BRIGHT = 明度 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::State::Alpha(int Mode) +{ + switch (Mode) + { + // アルファブレンドなし + case ALPHA_NONE: + { + D3Device->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,FALSE); + + break; + } + + // 通常 + case ALPHA_NORMAL: + { + D3Device->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, + el4D::Config::AlphaBlendNormal); + D3Device->SetRenderState(D3DRENDERSTATE_SRCBLEND,D3DBLEND_SRCALPHA); + D3Device->SetRenderState(D3DRENDERSTATE_DESTBLEND, + D3DBLEND_INVSRCALPHA); + + break; + } + + // 加算 + case ALPHA_ADD: + { + D3Device->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, + el4D::Config::AlphaBlendAdd); + D3Device->SetRenderState(D3DRENDERSTATE_SRCBLEND,D3DBLEND_SRCALPHA); + D3Device->SetRenderState(D3DRENDERSTATE_DESTBLEND,D3DBLEND_ONE); + + break; + } + + // 減算 + case ALPHA_DELETE: + { + D3Device->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, + el4D::Config::AlphaBlendDelete); + D3Device->SetRenderState(D3DRENDERSTATE_SRCBLEND,D3DBLEND_ZERO); + D3Device->SetRenderState(D3DRENDERSTATE_DESTBLEND, + D3DBLEND_INVSRCALPHA); + + break; + } + + // 反転 ( アルファ値無効 ) + case ALPHA_REVERSE: + { + D3Device->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, + el4D::Config::AlphaBlendReverse); + D3Device->SetRenderState(D3DRENDERSTATE_SRCBLEND, + D3DBLEND_INVDESTCOLOR); + D3Device->SetRenderState(D3DRENDERSTATE_DESTBLEND,D3DBLEND_ZERO); + + break; + } + + // 明度 + case ALPHA_BRIGHT: + { + D3Device->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, + el4D::Config::AlphaBlendBright); + D3Device->SetRenderState(D3DRENDERSTATE_SRCBLEND,D3DBLEND_DESTCOLOR); + D3Device->SetRenderState(D3DRENDERSTATE_DESTBLEND,D3DBLEND_SRCALPHA); + + break; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ステート:ポリゴン面の裏返し設定 -*/ +/*- -*/ +/*- BOOL Flag : TRUE = 裏面をレンダリング -*/ +/*- FALSE = 表面をレンダリング -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::State::Reverse(BOOL Flag) +{ + if (Flag) + { + D3Device->SetRenderState(D3DRENDERSTATE_CULLMODE,D3DCULL_CW); + } + else + { + D3Device->SetRenderState(D3DRENDERSTATE_CULLMODE,D3DCULL_CCW); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ステート:有効になるアルファの設定 -*/ +/*- -*/ +/*- int Mode : 有効になるアルファタイプ -*/ +/*- USE_TEXTURE = テクスチャー側 -*/ +/*- USE_MATERIAL = マテリアル側 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::State::UseAlpha(int Mode) +{ + if (Mode==USE_TEXTURE) + { + // テクスチャーのアルファを使用 + D3Device->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1); + D3Device->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE); + } + else + { + // テクスチャーのアルファの次にマテリアルのアルファを使用 + D3Device->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_MODULATE); + D3Device->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE); + D3Device->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ステート:アルファビットの比較設定 -*/ +/*- -*/ +/*- int Mode : アルファビット比較タイプ -*/ +/*- 省略/ALPHA_DEFAULT = デフォルト ( ALPHA_GREATEREQUALと同じ ) -*/ +/*- ALPHA_EQUAL = 等しい -*/ +/*- ALPHA_NOTEQUAL = 等しくない -*/ +/*- ALPHA_LESS = 小さい -*/ +/*- ALPHA_LESSEQUAL = 以下 -*/ +/*- ALPHA_GREATER = 大きい -*/ +/*- ALPHA_GREATEREQUAL = 以上 -*/ +/*- BYTE Bit : アルファビット -*/ +/*- 省略 = 中間の値 ( 0x80 ) -*/ +/*- 0x00〜0xFF = 任意の値 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::State::CheckAlpha(int Mode=ALPHA_DEFAULT,BYTE Bit=0x80) +{ + D3Device->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE,TRUE); + D3Device->SetRenderState(D3DRENDERSTATE_ALPHAREF,Bit); + D3Device->SetRenderState(D3DRENDERSTATE_ALPHAFUNC,Mode); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ステート:アルファビットの比較解除 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void el4D::State::UnCheckAlpha(void) +{ + D3Device->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE,FALSE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:平面オブジェクトを生成 -*/ +/*- -*/ +/*- 戻り値 : ポリゴンオブジェクト情報 ( D4OBJ型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D4OBJ el4D::Flat::Create(void) +{ + int i; + D4OBJ ObjD4=-1; + + // 使用可能なポリゴンオブジェクトの検索 + for (i=0;iSetTexture(0,Sprite[Texture::LastTexture].Object); + } + else + { + D3Device->SetTexture(0,NULL); + } + } + + el4D::Render::Polygon(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:平面レンダリング ( アルファブレンド ) -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int Alpha : アルファブレンドタイプ -*/ +/*- ALPHA_NONE = アルファブレンドなし -*/ +/*- ALPHA_NORMAL = 通常 -*/ +/*- ALPHA_ADD = 加算 -*/ +/*- ALPHA_DELETE = 減算 -*/ +/*- ALPHA_REVERSE = 反転 ( アルファ値無効 ) -*/ +/*- ALPHA_BRIGHT = 明度 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::AlphaRender(D4OBJ ObjD4,int Alpha) +{ + State::Alpha(Alpha); + + Flat::Render(ObjD4); + + State::Alpha(ALPHA_NONE); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:レンダリング位置の移動 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float Px : X座標の位置 -*/ +/*- float Py : Y座標の位置 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::Move(D4OBJ ObjD4,float Px,float Py) +{ + PolyObj[ObjD4].PiPx=Px; + PolyObj[ObjD4].PiPy=Py; + + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].VertexTL+0)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+0)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+1)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+1)->sy=PolyObj[ObjD4].PiPy; + (PolyObj[ObjD4].VertexTL+2)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+2)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+3)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+3)->sy=PolyObj[ObjD4].PiPy; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:レンダリングサイズの設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float Sx : X方向のサイズ -*/ +/*- float Sy : Y方向のサイズ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::Size(D4OBJ ObjD4,float Sx,float Sy) +{ + PolyObj[ObjD4].PiSx=Sx; + PolyObj[ObjD4].PiSy=Sy; + + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].VertexTL+0)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+0)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+1)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+1)->sy=PolyObj[ObjD4].PiPy; + (PolyObj[ObjD4].VertexTL+2)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+2)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+3)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+3)->sy=PolyObj[ObjD4].PiPy; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:レンダリング範囲の設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float X1 : 左上X座標の位置 -*/ +/*- float Y1 : 左上Y座標の位置 -*/ +/*- float X2 : 右下X座標の位置 -*/ +/*- float Y2 : 右下Y座標の位置 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::Area(D4OBJ ObjD4,float X1,float Y1,float X2,float Y2) +{ + PolyObj[ObjD4].PiPx=X1; + PolyObj[ObjD4].PiPy=Y1; + PolyObj[ObjD4].PiSx=F(X2-X1); + PolyObj[ObjD4].PiSy=F(Y2-Y1); + + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].VertexTL+0)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+0)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+1)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+1)->sy=PolyObj[ObjD4].PiPy; + (PolyObj[ObjD4].VertexTL+2)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+2)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+3)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+3)->sy=PolyObj[ObjD4].PiPy; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:頂点位置の設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float X1 : 左上X座標の位置 -*/ +/*- float Y1 : 左上Y座標の位置 -*/ +/*- float X2 : 右上X座標の位置 -*/ +/*- float Y2 : 右上Y座標の位置 -*/ +/*- float X3 : 左下X座標の位置 -*/ +/*- float Y3 : 左下Y座標の位置 -*/ +/*- float X4 : 右下X座標の位置 -*/ +/*- float Y4 : 右下Y座標の位置 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::Vertex(D4OBJ ObjD4,float X1,float Y1,float X2,float Y2, + float X3,float Y3,float X4,float Y4) +{ + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].VertexTL+0)->sx=X3; + (PolyObj[ObjD4].VertexTL+0)->sy=Y3; + (PolyObj[ObjD4].VertexTL+1)->sx=X1; + (PolyObj[ObjD4].VertexTL+1)->sy=Y1; + (PolyObj[ObjD4].VertexTL+2)->sx=X4; + (PolyObj[ObjD4].VertexTL+2)->sy=Y4; + (PolyObj[ObjD4].VertexTL+3)->sx=X2; + (PolyObj[ObjD4].VertexTL+3)->sy=Y2; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:回転 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float Angle : 角度 ( +:時計回り / -:逆方向 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::Rotate(D4OBJ ObjD4,float Angle) +{ + static int i; // 汎用カウンター + static float Px,Py; // 回転前の頂点座標 + static float Vx[4],Vy[4]; // 頂点座標 + + // 頂点ごとに座標を回転 + Px=PolyObj[ObjD4].PiSx/F(2); + Py=PolyObj[ObjD4].PiSy/F(2); + Vx[0]=F(Px*cos(Angle)-Py*sin(Angle)); + Vy[0]=F(Px*sin(Angle)+Py*cos(Angle)); + + Px=-PolyObj[ObjD4].PiSx/F(2); + Py=PolyObj[ObjD4].PiSy/F(2); + Vx[1]=F(Px*cos(Angle)-Py*sin(Angle)); + Vy[1]=F(Px*sin(Angle)+Py*cos(Angle)); + + Px=-PolyObj[ObjD4].PiSx/F(2); + Py=-PolyObj[ObjD4].PiSy/F(2); + Vx[2]=F(Px*cos(Angle)-Py*sin(Angle)); + Vy[2]=F(Px*sin(Angle)+Py*cos(Angle)); + + Px=PolyObj[ObjD4].PiSx/F(2); + Py=-PolyObj[ObjD4].PiSy/F(2); + Vx[3]=F(Px*cos(Angle)-Py*sin(Angle)); + Vy[3]=F(Px*sin(Angle)+Py*cos(Angle)); + + // 描画座標の加算 + for (i=0;i<4;i++) + { + Vx[i]+=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx/F(2); + Vy[i]+=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy/F(2); + } + + // 頂点を移動 + el4D::Flat::Vertex(ObjD4,Vx[2],Vy[2],Vx[3],Vy[3],Vx[1],Vy[1],Vx[0],Vy[0]); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:テクスチャー座標によるUV座標の設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float X1 : テクスチャー左上X座標 -*/ +/*- float Y1 : テクスチャー左上Y座標 -*/ +/*- float X2 : テクスチャー右下X座標 -*/ +/*- float Y2 : テクスチャー右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::TexturePosition(D4OBJ ObjD4,float X1,float Y1,float X2, + float Y2) +{ + float Tu1=(F(X1)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeX)+F(0.5)); + float Tv1=(F(Y1)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeY)+F(0.5)); + float Tu2=(F(X2)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeX)+F(0.5)); + float Tv2=(F(Y2)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeY)+F(0.5)); + + PolyObj[ObjD4].PiSx=F(X2-X1); + PolyObj[ObjD4].PiSy=F(Y2-Y1); + + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].VertexTL+0)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+0)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+1)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+1)->sy=PolyObj[ObjD4].PiPy; + (PolyObj[ObjD4].VertexTL+2)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+2)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+3)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+3)->sy=PolyObj[ObjD4].PiPy; + + (PolyObj[ObjD4].VertexTL+0)->tu=Tu1; + (PolyObj[ObjD4].VertexTL+0)->tv=Tv2; + (PolyObj[ObjD4].VertexTL+1)->tu=Tu1; + (PolyObj[ObjD4].VertexTL+1)->tv=Tv1; + (PolyObj[ObjD4].VertexTL+2)->tu=Tu2; + (PolyObj[ObjD4].VertexTL+2)->tv=Tv2; + (PolyObj[ObjD4].VertexTL+3)->tu=Tu2; + (PolyObj[ObjD4].VertexTL+3)->tv=Tv1; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:アルファ値の設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float Alpha : アルファ値の強さ ( 0.0〜1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::Alpha(D4OBJ ObjD4,float Alpha) +{ + PolyObj[ObjD4].A[0]=Alpha; + PolyObj[ObjD4].A[1]=Alpha; + PolyObj[ObjD4].A[2]=Alpha; + PolyObj[ObjD4].A[3]=Alpha; + + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].VertexTL+0)->color=D3DRGBA(PolyObj[ObjD4].R[0], + PolyObj[ObjD4].G[0], + PolyObj[ObjD4].B[0], + PolyObj[ObjD4].A[0]); + (PolyObj[ObjD4].VertexTL+1)->color=D3DRGBA(PolyObj[ObjD4].R[1], + PolyObj[ObjD4].G[1], + PolyObj[ObjD4].B[1], + PolyObj[ObjD4].A[1]); + (PolyObj[ObjD4].VertexTL+2)->color=D3DRGBA(PolyObj[ObjD4].R[2], + PolyObj[ObjD4].G[2], + PolyObj[ObjD4].B[2], + PolyObj[ObjD4].A[2]); + (PolyObj[ObjD4].VertexTL+3)->color=D3DRGBA(PolyObj[ObjD4].R[3], + PolyObj[ObjD4].G[3], + PolyObj[ObjD4].B[3], + PolyObj[ObjD4].A[3]); + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:アルファ値の設定 ( 頂点単位 ) -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float Alpha1 : 左上のアルファ値の強さ ( 0.0〜1.0 ) -*/ +/*- float Alpha2 : 右上のアルファ値の強さ ( 0.0〜1.0 ) -*/ +/*- float Alpha3 : 左下のアルファ値の強さ ( 0.0〜1.0 ) -*/ +/*- float Alpha4 : 右下のアルファ値の強さ ( 0.0〜1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::Alpha(D4OBJ ObjD4,float Alpha1,float Alpha2,float Alpha3, + float Alpha4) +{ + PolyObj[ObjD4].A[0]=Alpha3; + PolyObj[ObjD4].A[1]=Alpha1; + PolyObj[ObjD4].A[2]=Alpha4; + PolyObj[ObjD4].A[3]=Alpha2; + + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].VertexTL+0)->color=D3DRGBA(PolyObj[ObjD4].R[0], + PolyObj[ObjD4].G[0], + PolyObj[ObjD4].B[0], + PolyObj[ObjD4].A[0]); + (PolyObj[ObjD4].VertexTL+1)->color=D3DRGBA(PolyObj[ObjD4].R[1], + PolyObj[ObjD4].G[1], + PolyObj[ObjD4].B[1], + PolyObj[ObjD4].A[1]); + (PolyObj[ObjD4].VertexTL+2)->color=D3DRGBA(PolyObj[ObjD4].R[2], + PolyObj[ObjD4].G[2], + PolyObj[ObjD4].B[2], + PolyObj[ObjD4].A[2]); + (PolyObj[ObjD4].VertexTL+3)->color=D3DRGBA(PolyObj[ObjD4].R[3], + PolyObj[ObjD4].G[3], + PolyObj[ObjD4].B[3], + PolyObj[ObjD4].A[3]); + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:基本色の設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float R : 赤の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float G : 緑の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float B : 青の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::Color(D4OBJ ObjD4,float R,float G,float B) +{ + PolyObj[ObjD4].R[0]=R; + PolyObj[ObjD4].R[1]=R; + PolyObj[ObjD4].R[2]=R; + PolyObj[ObjD4].R[3]=R; + PolyObj[ObjD4].G[0]=G; + PolyObj[ObjD4].G[1]=G; + PolyObj[ObjD4].G[2]=G; + PolyObj[ObjD4].G[3]=G; + PolyObj[ObjD4].B[0]=B; + PolyObj[ObjD4].B[1]=B; + PolyObj[ObjD4].B[2]=B; + PolyObj[ObjD4].B[3]=B; + + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].VertexTL+0)->color=D3DRGBA(PolyObj[ObjD4].R[0], + PolyObj[ObjD4].G[0], + PolyObj[ObjD4].B[0], + PolyObj[ObjD4].A[0]); + (PolyObj[ObjD4].VertexTL+1)->color=D3DRGBA(PolyObj[ObjD4].R[1], + PolyObj[ObjD4].G[1], + PolyObj[ObjD4].B[1], + PolyObj[ObjD4].A[1]); + (PolyObj[ObjD4].VertexTL+2)->color=D3DRGBA(PolyObj[ObjD4].R[2], + PolyObj[ObjD4].G[2], + PolyObj[ObjD4].B[2], + PolyObj[ObjD4].A[2]); + (PolyObj[ObjD4].VertexTL+3)->color=D3DRGBA(PolyObj[ObjD4].R[3], + PolyObj[ObjD4].G[3], + PolyObj[ObjD4].B[3], + PolyObj[ObjD4].A[3]); + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:基本色の設定 ( 頂点単位 ) -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float R1 : 左上の赤の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float G1 : 左上の緑の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float B1 : 左上の青の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float R2 : 右上の赤の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float G2 : 右上の緑の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float B2 : 右上の青の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float R3 : 左下の赤の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float G3 : 左下の緑の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float B3 : 左下の青の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float R4 : 右下の赤の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float G4 : 右下の緑の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- float B4 : 右下の青の強さ ( -1.0〜0.0〜1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::Color(D4OBJ ObjD4,float R1,float G1,float B1,float R2, + float G2,float B2,float R3,float G3,float B3, + float R4,float G4,float B4) +{ + PolyObj[ObjD4].R[0]=R3; + PolyObj[ObjD4].R[1]=R1; + PolyObj[ObjD4].R[2]=R4; + PolyObj[ObjD4].R[3]=R2; + PolyObj[ObjD4].G[0]=G3; + PolyObj[ObjD4].G[1]=G1; + PolyObj[ObjD4].G[2]=G4; + PolyObj[ObjD4].G[3]=G2; + PolyObj[ObjD4].B[0]=B3; + PolyObj[ObjD4].B[1]=B1; + PolyObj[ObjD4].B[2]=B4; + PolyObj[ObjD4].B[3]=B2; + + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].VertexTL+0)->color=D3DRGBA(PolyObj[ObjD4].R[0], + PolyObj[ObjD4].G[0], + PolyObj[ObjD4].B[0], + PolyObj[ObjD4].A[0]); + (PolyObj[ObjD4].VertexTL+1)->color=D3DRGBA(PolyObj[ObjD4].R[1], + PolyObj[ObjD4].G[1], + PolyObj[ObjD4].B[1], + PolyObj[ObjD4].A[1]); + (PolyObj[ObjD4].VertexTL+2)->color=D3DRGBA(PolyObj[ObjD4].R[2], + PolyObj[ObjD4].G[2], + PolyObj[ObjD4].B[2], + PolyObj[ObjD4].A[2]); + (PolyObj[ObjD4].VertexTL+3)->color=D3DRGBA(PolyObj[ObjD4].R[3], + PolyObj[ObjD4].G[3], + PolyObj[ObjD4].B[3], + PolyObj[ObjD4].A[3]); + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:テクスチャーUV座標の設定 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float U1 : 左上のU座標 ( 0.0 〜 1.0 ) -*/ +/*- float V1 : 左上のV座標 ( 0.0 〜 1.0 ) -*/ +/*- float U2 : 右上のU座標 ( 0.0 〜 1.0 ) -*/ +/*- float V2 : 右上のV座標 ( 0.0 〜 1.0 ) -*/ +/*- float U3 : 左下のU座標 ( 0.0 〜 1.0 ) -*/ +/*- float V3 : 左下のV座標 ( 0.0 〜 1.0 ) -*/ +/*- float U4 : 右下のU座標 ( 0.0 〜 1.0 ) -*/ +/*- float V4 : 右下のV座標 ( 0.0 〜 1.0 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::Uv(D4OBJ ObjD4,float U1,float V1,float U2,float V2, + float U3,float V3,float U4,float V4) +{ + PolyObj[ObjD4].U[0]=U3; + PolyObj[ObjD4].U[1]=U1; + PolyObj[ObjD4].U[2]=U4; + PolyObj[ObjD4].U[3]=U2; + PolyObj[ObjD4].V[0]=V3; + PolyObj[ObjD4].V[1]=V1; + PolyObj[ObjD4].V[2]=V4; + PolyObj[ObjD4].V[3]=V2; + + if (el4D::Lock(ObjD4)) + { + (PolyObj[ObjD4].VertexTL+0)->tu=PolyObj[ObjD4].U[0]; + (PolyObj[ObjD4].VertexTL+0)->tv=PolyObj[ObjD4].V[0]; + (PolyObj[ObjD4].VertexTL+1)->tu=PolyObj[ObjD4].U[1]; + (PolyObj[ObjD4].VertexTL+1)->tv=PolyObj[ObjD4].V[1]; + (PolyObj[ObjD4].VertexTL+2)->tu=PolyObj[ObjD4].U[2]; + (PolyObj[ObjD4].VertexTL+2)->tv=PolyObj[ObjD4].V[2]; + (PolyObj[ObjD4].VertexTL+3)->tu=PolyObj[ObjD4].U[3]; + (PolyObj[ObjD4].VertexTL+3)->tv=PolyObj[ObjD4].V[3]; + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:テクスチャーUV座標の反転 -*/ +/*- -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- int Type : 反転タイプ -*/ +/*- UV_NORMAL = 反転なし -*/ +/*- UV_X = X方向に反転 -*/ +/*- UV_Y = Y方向に反転 -*/ +/*- UV_XY = XY方向に反転 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::ReverseUv(D4OBJ ObjD4,int Type) +{ + if (el4D::Lock(ObjD4)) + { + // 反転なしの場合 + if (Type==UV_NORMAL) + { + (PolyObj[ObjD4].VertexTL+0)->tu=PolyObj[ObjD4].U[0]; + (PolyObj[ObjD4].VertexTL+0)->tv=PolyObj[ObjD4].V[0]; + (PolyObj[ObjD4].VertexTL+1)->tu=PolyObj[ObjD4].U[1]; + (PolyObj[ObjD4].VertexTL+1)->tv=PolyObj[ObjD4].V[1]; + (PolyObj[ObjD4].VertexTL+2)->tu=PolyObj[ObjD4].U[2]; + (PolyObj[ObjD4].VertexTL+2)->tv=PolyObj[ObjD4].V[2]; + (PolyObj[ObjD4].VertexTL+3)->tu=PolyObj[ObjD4].U[3]; + (PolyObj[ObjD4].VertexTL+3)->tv=PolyObj[ObjD4].V[3]; + } + // X方向に反転の場合 + else if (Type==UV_X) + { + (PolyObj[ObjD4].VertexTL+0)->tu=PolyObj[ObjD4].U[2]; + (PolyObj[ObjD4].VertexTL+0)->tv=PolyObj[ObjD4].V[2]; + (PolyObj[ObjD4].VertexTL+1)->tu=PolyObj[ObjD4].U[3]; + (PolyObj[ObjD4].VertexTL+1)->tv=PolyObj[ObjD4].V[3]; + (PolyObj[ObjD4].VertexTL+2)->tu=PolyObj[ObjD4].U[0]; + (PolyObj[ObjD4].VertexTL+2)->tv=PolyObj[ObjD4].V[0]; + (PolyObj[ObjD4].VertexTL+3)->tu=PolyObj[ObjD4].U[1]; + (PolyObj[ObjD4].VertexTL+3)->tv=PolyObj[ObjD4].V[1]; + } + // Y方向に反転の場合 + else if (Type==UV_Y) + { + (PolyObj[ObjD4].VertexTL+0)->tu=PolyObj[ObjD4].U[1]; + (PolyObj[ObjD4].VertexTL+0)->tv=PolyObj[ObjD4].V[1]; + (PolyObj[ObjD4].VertexTL+1)->tu=PolyObj[ObjD4].U[0]; + (PolyObj[ObjD4].VertexTL+1)->tv=PolyObj[ObjD4].V[0]; + (PolyObj[ObjD4].VertexTL+2)->tu=PolyObj[ObjD4].U[3]; + (PolyObj[ObjD4].VertexTL+2)->tv=PolyObj[ObjD4].V[3]; + (PolyObj[ObjD4].VertexTL+3)->tu=PolyObj[ObjD4].U[2]; + (PolyObj[ObjD4].VertexTL+3)->tv=PolyObj[ObjD4].V[2]; + } + // XY方向に反転の場合 + else if (Type==UV_XY) + { + (PolyObj[ObjD4].VertexTL+0)->tu=PolyObj[ObjD4].U[3]; + (PolyObj[ObjD4].VertexTL+0)->tv=PolyObj[ObjD4].V[3]; + (PolyObj[ObjD4].VertexTL+1)->tu=PolyObj[ObjD4].U[2]; + (PolyObj[ObjD4].VertexTL+1)->tv=PolyObj[ObjD4].V[2]; + (PolyObj[ObjD4].VertexTL+2)->tu=PolyObj[ObjD4].U[1]; + (PolyObj[ObjD4].VertexTL+2)->tv=PolyObj[ObjD4].V[1]; + (PolyObj[ObjD4].VertexTL+3)->tu=PolyObj[ObjD4].U[0]; + (PolyObj[ObjD4].VertexTL+3)->tv=PolyObj[ObjD4].V[0]; + } + + el4D::Unlock(ObjD4); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:スプライトの描画1 -*/ +/*- -*/ +/*- float Px : X座標の位置 -*/ +/*- float Py : Y座標の位置 -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float X1 : テクスチャー左上X座標 -*/ +/*- float Y1 : テクスチャー左上Y座標 -*/ +/*- float X2 : テクスチャー右下X座標 -*/ +/*- float Y2 : テクスチャー右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::Layer(float Px,float Py,D4OBJ ObjD4, + float X1,float Y1,float X2,float Y2) +{ + // テクスチャー座標の算出 + float Tu1=(F(X1)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeX)+F(0.5)); + float Tv1=(F(Y1)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeY)+F(0.5)); + float Tu2=(F(X2)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeX)+F(0.5)); + float Tv2=(F(Y2)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeY)+F(0.5)); + + // 描画座標の設定 + PolyObj[ObjD4].PiPx=Px; + PolyObj[ObjD4].PiPy=Py; + + // サイズの設定 + PolyObj[ObjD4].PiSx=F(X2-X1); + PolyObj[ObjD4].PiSy=F(Y2-Y1); + + if (el4D::Lock(ObjD4)) + { + // 頂点を更新 + (PolyObj[ObjD4].VertexTL+0)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+0)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+1)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+1)->sy=PolyObj[ObjD4].PiPy; + (PolyObj[ObjD4].VertexTL+2)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+2)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+3)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+3)->sy=PolyObj[ObjD4].PiPy; + + // UV座標を更新 + (PolyObj[ObjD4].VertexTL+0)->tu=Tu1; + (PolyObj[ObjD4].VertexTL+0)->tv=Tv2; + (PolyObj[ObjD4].VertexTL+1)->tu=Tu1; + (PolyObj[ObjD4].VertexTL+1)->tv=Tv1; + (PolyObj[ObjD4].VertexTL+2)->tu=Tu2; + (PolyObj[ObjD4].VertexTL+2)->tv=Tv2; + (PolyObj[ObjD4].VertexTL+3)->tu=Tu2; + (PolyObj[ObjD4].VertexTL+3)->tv=Tv1; + + el4D::Unlock(ObjD4); + } + + // レンダリング + Render(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:スプライトの描画2 -*/ +/*- -*/ +/*- float Px : X座標の位置 -*/ +/*- float Py : Y座標の位置 -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::Layer(float Px,float Py,D4OBJ ObjD4) +{ + // 描画座標の設定 + PolyObj[ObjD4].PiPx=Px; + PolyObj[ObjD4].PiPy=Py; + + if (el4D::Lock(ObjD4)) + { + // 頂点を更新 + (PolyObj[ObjD4].VertexTL+0)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+0)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+1)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+1)->sy=PolyObj[ObjD4].PiPy; + (PolyObj[ObjD4].VertexTL+2)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+2)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+3)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+3)->sy=PolyObj[ObjD4].PiPy; + + el4D::Unlock(ObjD4); + } + + // レンダリング + Render(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:スプライトの描画 ( 回転1 ) -*/ +/*- -*/ +/*- float Px : X座標の位置 -*/ +/*- float Py : Y座標の位置 -*/ +/*- float Angle : 角度 ( +:時計回り / -:逆方向 ) -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float X1 : テクスチャー左上X座標 -*/ +/*- float Y1 : テクスチャー左上Y座標 -*/ +/*- float X2 : テクスチャー右下X座標 -*/ +/*- float Y2 : テクスチャー右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::RotateLayer(float Px,float Py,float Angle,D4OBJ ObjD4, + float X1,float Y1,float X2,float Y2) +{ + static int i; // 汎用カウンター + static float Rx,Ry; // 回転前の頂点座標 + static float Vx[4],Vy[4]; // 頂点座標 + + // テクスチャー座標の算出 + float Tu1=(F(X1)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeX)+F(0.5)); + float Tv1=(F(Y1)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeY)+F(0.5)); + float Tu2=(F(X2)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeX)+F(0.5)); + float Tv2=(F(Y2)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeY)+F(0.5)); + + // 描画座標の設定 + PolyObj[ObjD4].PiPx=Px; + PolyObj[ObjD4].PiPy=Py; + + // サイズの設定 + PolyObj[ObjD4].PiSx=F(X2-X1); + PolyObj[ObjD4].PiSy=F(Y2-Y1); + + // 頂点ごとに座標を回転 + Rx=PolyObj[ObjD4].PiSx/F(2); + Ry=PolyObj[ObjD4].PiSy/F(2); + Vx[0]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[0]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + Rx=-PolyObj[ObjD4].PiSx/F(2); + Ry=PolyObj[ObjD4].PiSy/F(2); + Vx[1]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[1]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + Rx=-PolyObj[ObjD4].PiSx/F(2); + Ry=-PolyObj[ObjD4].PiSy/F(2); + Vx[2]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[2]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + Rx=PolyObj[ObjD4].PiSx/F(2); + Ry=-PolyObj[ObjD4].PiSy/F(2); + Vx[3]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[3]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + // 描画座標の加算 + for (i=0;i<4;i++) + { + Vx[i]+=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx/F(2); + Vy[i]+=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy/F(2); + } + + if (el4D::Lock(ObjD4)) + { + // 頂点を更新 + (PolyObj[ObjD4].VertexTL+0)->sx=Vx[1]; + (PolyObj[ObjD4].VertexTL+0)->sy=Vy[1]; + (PolyObj[ObjD4].VertexTL+1)->sx=Vx[2]; + (PolyObj[ObjD4].VertexTL+1)->sy=Vy[2]; + (PolyObj[ObjD4].VertexTL+2)->sx=Vx[0]; + (PolyObj[ObjD4].VertexTL+2)->sy=Vy[0]; + (PolyObj[ObjD4].VertexTL+3)->sx=Vx[3]; + (PolyObj[ObjD4].VertexTL+3)->sy=Vy[3]; + + // UV座標を更新 + (PolyObj[ObjD4].VertexTL+0)->tu=Tu1; + (PolyObj[ObjD4].VertexTL+0)->tv=Tv2; + (PolyObj[ObjD4].VertexTL+1)->tu=Tu1; + (PolyObj[ObjD4].VertexTL+1)->tv=Tv1; + (PolyObj[ObjD4].VertexTL+2)->tu=Tu2; + (PolyObj[ObjD4].VertexTL+2)->tv=Tv2; + (PolyObj[ObjD4].VertexTL+3)->tu=Tu2; + (PolyObj[ObjD4].VertexTL+3)->tv=Tv1; + + el4D::Unlock(ObjD4); + } + + // レンダリング + Render(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:スプライトの描画 ( 回転2 ) -*/ +/*- -*/ +/*- float Px : X座標の位置 -*/ +/*- float Py : Y座標の位置 -*/ +/*- float Angle : 角度 ( +:時計回り / -:逆方向 ) -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::RotateLayer(float Px,float Py,float Angle,D4OBJ ObjD4) +{ + static int i; // 汎用カウンター + static float Rx,Ry; // 回転前の頂点座標 + static float Vx[4],Vy[4]; // 頂点座標 + + // 描画座標の設定 + PolyObj[ObjD4].PiPx=Px; + PolyObj[ObjD4].PiPy=Py; + + // 頂点ごとに座標を回転 + Rx=PolyObj[ObjD4].PiSx/F(2); + Ry=PolyObj[ObjD4].PiSy/F(2); + Vx[0]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[0]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + Rx=-PolyObj[ObjD4].PiSx/F(2); + Ry=PolyObj[ObjD4].PiSy/F(2); + Vx[1]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[1]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + Rx=-PolyObj[ObjD4].PiSx/F(2); + Ry=-PolyObj[ObjD4].PiSy/F(2); + Vx[2]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[2]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + Rx=PolyObj[ObjD4].PiSx/F(2); + Ry=-PolyObj[ObjD4].PiSy/F(2); + Vx[3]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[3]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + // 描画座標の加算 + for (i=0;i<4;i++) + { + Vx[i]+=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx/F(2); + Vy[i]+=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy/F(2); + } + + if (el4D::Lock(ObjD4)) + { + // 頂点を更新 + (PolyObj[ObjD4].VertexTL+0)->sx=Vx[1]; + (PolyObj[ObjD4].VertexTL+0)->sy=Vy[1]; + (PolyObj[ObjD4].VertexTL+1)->sx=Vx[2]; + (PolyObj[ObjD4].VertexTL+1)->sy=Vy[2]; + (PolyObj[ObjD4].VertexTL+2)->sx=Vx[0]; + (PolyObj[ObjD4].VertexTL+2)->sy=Vy[0]; + (PolyObj[ObjD4].VertexTL+3)->sx=Vx[3]; + (PolyObj[ObjD4].VertexTL+3)->sy=Vy[3]; + + el4D::Unlock(ObjD4); + } + + // レンダリング + Render(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:スプライトの描画 ( 拡大縮小1 ) -*/ +/*- -*/ +/*- float Px : X座標の位置 -*/ +/*- float Py : Y座標の位置 -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float X1 : テクスチャー左上X座標 -*/ +/*- float Y1 : テクスチャー左上Y座標 -*/ +/*- float X2 : テクスチャー右下X座標 -*/ +/*- float Y2 : テクスチャー右下Y座標 -*/ +/*- float Sx : Xサイズ -*/ +/*- float Sy : Yサイズ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::StretchLayer(float Px,float Py,D4OBJ ObjD4, + float X1,float Y1,float X2,float Y2, + float Sx,float Sy) +{ + // テクスチャー座標の算出 + float Tu1=(F(X1)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeX)+F(0.5)); + float Tv1=(F(Y1)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeY)+F(0.5)); + float Tu2=(F(X2)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeX)+F(0.5)); + float Tv2=(F(Y2)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeY)+F(0.5)); + + // 描画座標の設定 + PolyObj[ObjD4].PiPx=Px; + PolyObj[ObjD4].PiPy=Py; + + // サイズの設定 + PolyObj[ObjD4].PiSx=Sx; + PolyObj[ObjD4].PiSy=Sy; + + if (el4D::Lock(ObjD4)) + { + // 頂点を更新 + (PolyObj[ObjD4].VertexTL+0)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+0)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+1)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+1)->sy=PolyObj[ObjD4].PiPy; + (PolyObj[ObjD4].VertexTL+2)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+2)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+3)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+3)->sy=PolyObj[ObjD4].PiPy; + + // UV座標を更新 + (PolyObj[ObjD4].VertexTL+0)->tu=Tu1; + (PolyObj[ObjD4].VertexTL+0)->tv=Tv2; + (PolyObj[ObjD4].VertexTL+1)->tu=Tu1; + (PolyObj[ObjD4].VertexTL+1)->tv=Tv1; + (PolyObj[ObjD4].VertexTL+2)->tu=Tu2; + (PolyObj[ObjD4].VertexTL+2)->tv=Tv2; + (PolyObj[ObjD4].VertexTL+3)->tu=Tu2; + (PolyObj[ObjD4].VertexTL+3)->tv=Tv1; + + el4D::Unlock(ObjD4); + } + + // レンダリング + Render(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:スプライトの描画 ( 拡大縮小2 ) -*/ +/*- -*/ +/*- float Px : X座標の位置 -*/ +/*- float Py : Y座標の位置 -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float Sx : Xサイズ -*/ +/*- float Sy : Yサイズ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::StretchLayer(float Px,float Py,D4OBJ ObjD4, + float Sx,float Sy) +{ + // 描画座標の設定 + PolyObj[ObjD4].PiPx=Px; + PolyObj[ObjD4].PiPy=Py; + + // サイズの設定 + PolyObj[ObjD4].PiSx=Sx; + PolyObj[ObjD4].PiSy=Sy; + + if (el4D::Lock(ObjD4)) + { + // 頂点を更新 + (PolyObj[ObjD4].VertexTL+0)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+0)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+1)->sx=PolyObj[ObjD4].PiPx; + (PolyObj[ObjD4].VertexTL+1)->sy=PolyObj[ObjD4].PiPy; + (PolyObj[ObjD4].VertexTL+2)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+2)->sy=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy; + (PolyObj[ObjD4].VertexTL+3)->sx=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx; + (PolyObj[ObjD4].VertexTL+3)->sy=PolyObj[ObjD4].PiPy; + + el4D::Unlock(ObjD4); + } + + // レンダリング + Render(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:スプライトの描画 ( 拡大縮小+回転1 ) -*/ +/*- -*/ +/*- float Px : X座標の位置 -*/ +/*- float Py : Y座標の位置 -*/ +/*- float Angle : 角度 ( +:時計回り / -:逆方向 ) -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float X1 : テクスチャー左上X座標 -*/ +/*- float Y1 : テクスチャー左上Y座標 -*/ +/*- float X2 : テクスチャー右下X座標 -*/ +/*- float Y2 : テクスチャー右下Y座標 -*/ +/*- float Sx : Xサイズ -*/ +/*- float Sy : Yサイズ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::ZoomLayer(float Px,float Py,float Angle,D4OBJ ObjD4, + float X1,float Y1,float X2,float Y2, + float Sx,float Sy) +{ + static int i; // 汎用カウンター + static float Rx,Ry; // 回転前の頂点座標 + static float Vx[4],Vy[4]; // 頂点座標 + + // テクスチャー座標の算出 + float Tu1=(F(X1)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeX)+F(0.5)); + float Tv1=(F(Y1)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeY)+F(0.5)); + float Tu2=(F(X2)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeX)+F(0.5)); + float Tv2=(F(Y2)+F(0.5))/(F(Sprite[PolyObj[ObjD4].Texture].SizeY)+F(0.5)); + + // 描画座標の設定 + PolyObj[ObjD4].PiPx=Px; + PolyObj[ObjD4].PiPy=Py; + + // サイズの設定 + PolyObj[ObjD4].PiSx=Sx; + PolyObj[ObjD4].PiSy=Sy; + + // 頂点ごとに座標を回転 + Rx=PolyObj[ObjD4].PiSx/F(2); + Ry=PolyObj[ObjD4].PiSy/F(2); + Vx[0]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[0]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + Rx=-PolyObj[ObjD4].PiSx/F(2); + Ry=PolyObj[ObjD4].PiSy/F(2); + Vx[1]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[1]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + Rx=-PolyObj[ObjD4].PiSx/F(2); + Ry=-PolyObj[ObjD4].PiSy/F(2); + Vx[2]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[2]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + Rx=PolyObj[ObjD4].PiSx/F(2); + Ry=-PolyObj[ObjD4].PiSy/F(2); + Vx[3]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[3]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + // 描画座標の加算 + for (i=0;i<4;i++) + { + Vx[i]+=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx/F(2); + Vy[i]+=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy/F(2); + } + + if (el4D::Lock(ObjD4)) + { + // 頂点を更新 + (PolyObj[ObjD4].VertexTL+0)->sx=Vx[1]; + (PolyObj[ObjD4].VertexTL+0)->sy=Vy[1]; + (PolyObj[ObjD4].VertexTL+1)->sx=Vx[2]; + (PolyObj[ObjD4].VertexTL+1)->sy=Vy[2]; + (PolyObj[ObjD4].VertexTL+2)->sx=Vx[0]; + (PolyObj[ObjD4].VertexTL+2)->sy=Vy[0]; + (PolyObj[ObjD4].VertexTL+3)->sx=Vx[3]; + (PolyObj[ObjD4].VertexTL+3)->sy=Vy[3]; + + // UV座標を更新 + (PolyObj[ObjD4].VertexTL+0)->tu=Tu1; + (PolyObj[ObjD4].VertexTL+0)->tv=Tv2; + (PolyObj[ObjD4].VertexTL+1)->tu=Tu1; + (PolyObj[ObjD4].VertexTL+1)->tv=Tv1; + (PolyObj[ObjD4].VertexTL+2)->tu=Tu2; + (PolyObj[ObjD4].VertexTL+2)->tv=Tv2; + (PolyObj[ObjD4].VertexTL+3)->tu=Tu2; + (PolyObj[ObjD4].VertexTL+3)->tv=Tv1; + + el4D::Unlock(ObjD4); + } + + // レンダリング + Render(ObjD4); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フラット:スプライトの描画 ( 拡大縮小+回転2 ) -*/ +/*- -*/ +/*- float Px : X座標の位置 -*/ +/*- float Py : Y座標の位置 -*/ +/*- float Angle : 角度 ( +:時計回り / -:逆方向 ) -*/ +/*- D4OBJ ObjD4 : ポリゴンオブジェクト情報 -*/ +/*- float Sx : Xサイズ -*/ +/*- float Sy : Yサイズ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +inline void el4D::Flat::ZoomLayer(float Px,float Py,float Angle,D4OBJ ObjD4, + float Sx,float Sy) +{ + static int i; // 汎用カウンター + static float Rx,Ry; // 回転前の頂点座標 + static float Vx[4],Vy[4]; // 頂点座標 + + // 描画座標の設定 + PolyObj[ObjD4].PiPx=Px; + PolyObj[ObjD4].PiPy=Py; + + // サイズの設定 + PolyObj[ObjD4].PiSx=Sx; + PolyObj[ObjD4].PiSy=Sy; + + // 頂点ごとに座標を回転 + Rx=PolyObj[ObjD4].PiSx/F(2); + Ry=PolyObj[ObjD4].PiSy/F(2); + Vx[0]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[0]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + Rx=-PolyObj[ObjD4].PiSx/F(2); + Ry=PolyObj[ObjD4].PiSy/F(2); + Vx[1]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[1]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + Rx=-PolyObj[ObjD4].PiSx/F(2); + Ry=-PolyObj[ObjD4].PiSy/F(2); + Vx[2]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[2]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + Rx=PolyObj[ObjD4].PiSx/F(2); + Ry=-PolyObj[ObjD4].PiSy/F(2); + Vx[3]=F(Rx*cos(Angle)-Ry*sin(Angle)); + Vy[3]=F(Rx*sin(Angle)+Ry*cos(Angle)); + + // 描画座標の加算 + for (i=0;i<4;i++) + { + Vx[i]+=PolyObj[ObjD4].PiPx+PolyObj[ObjD4].PiSx/F(2); + Vy[i]+=PolyObj[ObjD4].PiPy+PolyObj[ObjD4].PiSy/F(2); + } + + if (el4D::Lock(ObjD4)) + { + // 頂点を更新 + (PolyObj[ObjD4].VertexTL+0)->sx=Vx[1]; + (PolyObj[ObjD4].VertexTL+0)->sy=Vy[1]; + (PolyObj[ObjD4].VertexTL+1)->sx=Vx[2]; + (PolyObj[ObjD4].VertexTL+1)->sy=Vy[2]; + (PolyObj[ObjD4].VertexTL+2)->sx=Vx[0]; + (PolyObj[ObjD4].VertexTL+2)->sy=Vy[0]; + (PolyObj[ObjD4].VertexTL+3)->sx=Vx[3]; + (PolyObj[ObjD4].VertexTL+3)->sy=Vy[3]; + + el4D::Unlock(ObjD4); + } + + // レンダリング + Render(ObjD4); +} + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= ムービークラス定義 ( elMovie ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef DIRECTSHOW + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ムービー再生中動作関数の設定 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL _MoviePlayProc(void) +{ + // ムービー停止の要求があった場合 + if (elMovie::MoviePause==1) + { + // 停止 + _AMObject->Pause(); + + // フラグを停止状態に設定 + elMovie::MoviePause=2; + } + + // ムービーが終了した場合 + if (!MovieEnd && _AMObject->End()) + { + MovieEnd=TRUE; + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ムービークラスの初期化 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMovie::Init(void) +{ + _AMObject=NULL; + MovieStart=FALSE; + MovieEnd=TRUE; + DrawSkip=FALSE; + MoviePause=0; + ViewLayer=FALSE; + ViewDrawEvent=FALSE; + ViewStretch=TRUE; + ViewLeft=0; + ViewTop=0; + ViewWidth=elDraw::Width; + ViewHeight=elDraw::Height; + MovieWait=timeGetTime(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 動画の読み込み -*/ +/*- -*/ +/*- char* FileName : 動画ファイル名 ( DirectShow/ActiveMovie対応形式 ) -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elMovie::LoadObject(char* FileName) +{ + HRESULT amret; + + if (MovieStart) + { + DestroyObject(); + } + + elSound::DestroyObject(); + + strcpy(MovieName,elSystem::Directory()); + strcat(MovieName,FileName); + + _AMObject=new elMovieObject(&amret,DDObject,DDFront); + + if (amret<0) + { + return elDraw::Error("elMovie::LoadObject", + "DirectShowまたはActiveMovieが使用できません"); + } + + MovieStart=TRUE; + DrawSkip=TRUE; + + if (_FullScreen && elDraw::SearchVideoCard) + { + _AMObject->Start(MovieName,DDObject,DDFront,TRUE,_MoviePlayProc); + } + else + { + _AMObject->Start(MovieName,DDObject,DDFront,FALSE,_MoviePlayProc); + } + + ShowImage(); + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 全オブジェクトの破棄 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMovie::DestroyObject(void) +{ + if (MovieStart) + { + _AMObject->Stop(); + _AMObject->Close(); + + delete _AMObject; + _AMObject=NULL; + + MovieStart=FALSE; + MovieEnd=TRUE; + DrawSkip=FALSE; + MoviePause=0; + ViewLayer=FALSE; + ViewDrawEvent=FALSE; + ViewStretch=TRUE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 再生時のイベント発生要求 ( elMovie::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMovie::DrawEvent(void) +{ + if (MovieStart) + { + DestroyObject(); + } + + ViewDrawEvent=TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ムービーのスプライト化 ( elMovie::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMovie::DrawLayer(void) +{ + if (MovieStart) + { + DestroyObject(); + } + + ViewLayer=TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ムービー描画領域の設定 ( elMovie::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*- int Left : 描画左上X座標 -*/ +/*- int Top : 描画左上Y座標 -*/ +/*- int Width : 描画領域の幅 -*/ +/*- int Height : 描画領域の高さ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMovie::Size(int Left,int Top,int Width,int Height) +{ + if (MovieStart) + { + DestroyObject(); + } + + ViewLeft=Left; + ViewTop=Top; + ViewWidth=Width; + ViewHeight=Height; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ムービーサイズの拡縮不可に設定 ( elMovie::LoadObject関数の前に使用 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMovie::NoStretch(void) +{ + if (MovieStart) + { + DestroyObject(); + } + + ViewStretch=FALSE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ムービーの終了 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMovie::Close(void) +{ + DestroyObject(); + + elSound::ReloadObject(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ムービーの再生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMovie::Play(void) +{ + if (timeGetTime()>MovieWait) + { + if (MovieStart) + { + _AMObject->Play(); + + MoviePause=0; + MovieEnd=FALSE; + } + + MovieWait=timeGetTime()+(ULONG)700; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ムービーの1フレーム描画 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMovie::ShowImage(void) +{ + if (MovieStart) + { + _AMObject->Play(); + + MoviePause=1; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ムービーの停止 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMovie::Pause(void) +{ + if (MovieStart && !MoviePause) + { + MoviePause=1; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ムービーの早送り -*/ +/*- -*/ +/*- int Speed : 早送り速度 ( ムービー全長÷Speed ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMovie::Forward(int Speed) +{ + if (timeGetTime()>MovieWait) + { + if (MovieStart) + { + Pause(); + + _AMObject->Forward(Speed); + + if (MoviePause) ShowImage(); + } + + MovieWait=timeGetTime()+(ULONG)700; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ムービーの巻戻し -*/ +/*- -*/ +/*- int Speed : 巻戻し速度 ( ムービー全長÷Speed ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMovie::Backward(int Speed) +{ + if (timeGetTime()>MovieWait) + { + if (MovieStart) + { + Pause(); + + _AMObject->Backward(Speed); + + if (MoviePause) ShowImage(); + } + + MovieWait=timeGetTime()+(ULONG)700; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ムービー先頭に移動 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMovie::Top(void) +{ + if (MovieStart) + { + _AMObject->Top(); + + if (MoviePause) ShowImage(); + } +} + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= ストリームクラス定義 ( elStream ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef MEDIASTREAM + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ストリームクラスの初期化 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elStream::Init(void) +{ + // データ初期化 + LoadCheck=FALSE; + PlayCheck=FALSE; + PauseCheck=FALSE; + OneShot=FALSE; + + #ifndef DIRECTMUSIC + + CoInitialize(NULL); + + #endif +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 全オブジェクトの破棄 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elStream::DestroyObject(void) +{ + // オブジェクトの開放 + elStream::FreeObject(); + + #ifndef DIRECTMUSIC + + CoUninitialize(); + + #endif +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ストリームの読み込み -*/ +/*- -*/ +/*- char* FileName : 動画ファイル名 ( DirectShow/ActiveMovie対応形式 ) -*/ +/*- BOOL Sound : サウンドの再生 -*/ +/*- 省略/TRUE = 再生あり -*/ +/*- FALSE = 再生なし -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elStream::LoadObject(char* FileName,BOOL Sound=TRUE) +{ + char Current[256]; + WCHAR Path[MAX_PATH]; + BOOL error; + RECT rect; + IAMMultiMediaStream* media; + + // ストリームを再生中の場合 + if (PlayCheck) + { + // 停止 + elStream::Stop(); + } + + // ストリームがロードされている場合 + if (LoadCheck) + { + // オブジェクトの開放 + elStream::FreeObject(); + } + + while (TRUE) + { + error=TRUE; + + // DirectShow/ActiveMovieの初期化 + if (FAILED(CoCreateInstance(CLSID_AMMultiMediaStream,NULL, + CLSCTX_INPROC_SERVER,IID_IAMMultiMediaStream, + (void **)&media))) + { + break; + } + + if (FAILED(media->Initialize(STREAMTYPE_READ,0,NULL))) break; + + // DirectDrawに接続 + if (FAILED(media->AddMediaStream(DDObject,&MSPID_PrimaryVideo,0,NULL))) + { + break; + } + + // サウンドを再生する場合 + if (Sound) + { + // DirectSoundに接続 + if (FAILED(media->AddMediaStream(NULL,&MSPID_PrimaryAudio, + AMMSF_ADDDEFAULTRENDERER,NULL))) + { + break; + } + } + + // ファイルからストリームを読み込む + GetCurrentDirectory(254,Current); + SetCurrentDirectory(elSystem::Directory()); + + mbstowcs(Path,FileName,MAX_PATH); + + if (FAILED(media->OpenFile(Path,0))) break; + STMultiMediaStream=media; + media->AddRef(); + + SetCurrentDirectory(Current); + + error=FALSE; + + break; + } + + media->Release(); + + if (error) + { + return elDraw::Error("elStream::LoadObject", + "ストリームを読み込めません"); + } + + while (TRUE) + { + error=TRUE; + + // 初期化の続きとDirectDrawサーフェースへの接続 + if (FAILED((STMultiMediaStream->GetMediaStream(MSPID_PrimaryVideo, + &STMediaStream)))) + { + break; + } + + if (FAILED((STMediaStream->QueryInterface(IID_IDirectDrawMediaStream, + (void**)&STMediaStreamDD)))) + { + break; + } + + if (FAILED((STMediaStreamDD->CreateSample(NULL,NULL,0,&STStreamSample)))) + { + break; + } + + #ifdef NEWCODE + + #undef IDirectDrawSurface + + if (FAILED((STStreamSample->GetSurface((IDirectDrawSurface**) + &STStreamSurface,&rect)))) break; + + #define IDirectDrawSurface IDirectDrawSurface7 + + #else + + if (FAILED((STStreamSample->GetSurface(&STStreamSurface,&rect)))) break; + + #endif + + error=FALSE; + + break; + } + + if (error) + { + return elDraw::Error("elStream::LoadObject", + "DirectShow/ActiveMovieが使えません"); + } + + // ストリーム時間の取得 + STMultiMediaStream->GetDuration(&MovieTime); + + // ストリームの描画サイズの取得 + Sx=rect.right-rect.left; + Sy=rect.bottom-rect.top; + + LoadCheck=TRUE; + PlayCheck=FALSE; + PauseCheck=FALSE; + OneShot=FALSE; + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ストリームを削除してメモリから解放 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elStream::FreeObject(void) +{ + if (STMediaStream!=NULL) + { + STMediaStream->Release(); + STMediaStream=NULL; + } + + if (STMediaStreamDD!=NULL) + { + STMediaStreamDD->Release(); + STMediaStreamDD=NULL; + } + + if (STStreamSample!=NULL) + { + STStreamSample->Release(); + STStreamSample=NULL; + } + + if (STMultiMediaStream!=NULL) + { + STMultiMediaStream->Release(); + STMultiMediaStream=NULL; + } + + if (STStreamSurface!=NULL) + { + STStreamSurface->Release(); + STStreamSurface=NULL; + } + + LoadCheck=FALSE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- レンダリング -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- 省略 = 左 -*/ +/*- int Py : 描画Y座標 -*/ +/*- 省略 = 上 -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- 省略 = 裏画面へレンダリング -*/ +/*- 指定 = 任意のスプライトにレンダリング -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elStream::Rendering(int Px=0,int Py=0,DDOBJ ObjDD=-1) +{ + static RECT rect; + + // ストリームを再生中の場合 + if (PlayCheck && !PauseCheck && LoadCheck) + { + // レンダリング + if (STStreamSample->Update(0,NULL,NULL,0)==S_OK) + { + // 裏画面へのレンダリングの場合 + if (ObjDD==-1) + { + // 描画領域のチェック + rect.left=0; + rect.top=0; + rect.right=Sx; + rect.bottom=Sy; + + if (Px+rect.leftelDraw::Vx2) + { + rect.right-=Px+rect.right-elDraw::Vx2; + } + + if (Py+rect.bottom>elDraw::Vy2) + { + rect.bottom-=Py+rect.bottom-elDraw::Vy2; + } + + // 描画できる場合 + if (rect.leftBltFast(Px,Py,STStreamSurface,&rect, + DDBLTFAST_WAIT)==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } + } + else + { + // 任意のスプライトに描画 + rect.left=0; + rect.top=0; + rect.right=Sx; + rect.bottom=Sy; + + if (Sprite[ObjDD].Object->BltFast(Px,Py,STStreamSurface,&rect, + DDBLTFAST_WAIT)==DDERR_SURFACELOST) + { + elDraw::ReloadObject(); + } + } + + // 1フレームだけ描画した場合 + if (OneShot) + { + OneShot=FALSE; + PauseCheck=TRUE; + + STMultiMediaStream->SetState(STREAMSTATE_STOP); + } + } + else + { + // ストリーム再生の終了 + PlayCheck=FALSE; + PauseCheck=FALSE; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ストリームの1フレーム描画 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elStream::ShowImage(void) +{ + // ストリームがロードされている場合 + if (LoadCheck) + { + if (!PlayCheck || PlayCheck && PauseCheck) + { + STMultiMediaStream->SetState(STREAMSTATE_RUN); + } + + OneShot=TRUE; + PlayCheck=TRUE; + PauseCheck=FALSE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ストリームの再生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elStream::Play(void) +{ + // ストリームがロードされている場合 + if (LoadCheck) + { + elStream::Top(); + + STMultiMediaStream->SetState(STREAMSTATE_RUN); + + PlayCheck=TRUE; + PauseCheck=FALSE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ストリームの一時停止及び一時停止解除 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elStream::Pause(void) +{ + // ストリームを再生中の場合 + if (PlayCheck) + { + if (PauseCheck) + { + STMultiMediaStream->SetState(STREAMSTATE_RUN); + } + else + { + STMultiMediaStream->SetState(STREAMSTATE_STOP); + } + + PauseCheck=!PauseCheck; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ストリームの停止 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elStream::Stop(void) +{ + // ストリームを再生中の場合 + if (PlayCheck) + { + STMultiMediaStream->SetState(STREAMSTATE_STOP); + + PlayCheck=FALSE; + PauseCheck=FALSE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ストリームの早送り -*/ +/*- -*/ +/*- int Time : 早送り時間 ( ミリ秒 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elStream::Forward(int Time) +{ + static STREAM_TIME stm; + + // ストリームがロードされている場合 + if (LoadCheck) + { + STMultiMediaStream->GetTime(&stm); + + stm+=Time*10000L; + if (stm>MovieTime) stm=MovieTime; + + STMultiMediaStream->Seek(stm); + + if (!PlayCheck || PlayCheck && PauseCheck) + { + elStream::ShowImage(); + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ストリームの巻戻し -*/ +/*- -*/ +/*- int Time : 巻戻し時間 ( ミリ秒 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elStream::Backward(int Time) +{ + static STREAM_TIME stm; + + // ストリームがロードされている場合 + if (LoadCheck) + { + STMultiMediaStream->GetTime(&stm); + + stm-=Time*10000L; + if (stm<0L) stm=0L; + + STMultiMediaStream->Seek(stm); + + if (!PlayCheck || PlayCheck && PauseCheck) + { + elStream::ShowImage(); + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ストリーム先頭に移動 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elStream::Top(void) +{ + // ストリームがロードされている場合 + if (LoadCheck) + { + STMultiMediaStream->Seek((STREAM_TIME)0L); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 再生状態の取得 -*/ +/*- -*/ +/*- 戻り値 : 再生状態 ( int型 ) -*/ +/*- STREAM_NONE = ストリーム無し -*/ +/*- STREAM_PLAY = 再生中 -*/ +/*- STREAM_PAUSE = 一時停止中 -*/ +/*- STREAM_STOP = 停止中 -*/ +/*- STREAM_END = ストリーム終端 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// 再生状態 +static const int STREAM_NONE=0; // ストリーム無し +static const int STREAM_PLAY=1; // 再生中 +static const int STREAM_PAUSE=2; // 一時停止中 +static const int STREAM_STOP=3; // 停止中 +static const int STREAM_END=4; // ストリーム終端 + +int elStream::GetStatus(void) +{ + static STREAM_TIME stm; + + // ストリームがロードされている場合 + if (elStream::LoadCheck) + { + STMultiMediaStream->GetTime(&stm); + + if (stm>=MovieTime) return STREAM_END; + + if (PauseCheck) return STREAM_PAUSE; + if (PlayCheck) return STREAM_PLAY; + + return STREAM_STOP; + } + + return STREAM_NONE; +} + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= フォントクラス定義 ( elFont ) =*/ +/*= =*/ +/*==============================================================================*/ + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フォントクラスの初期化 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elFont::Init(void) +{ + int i; + + // データ初期化 + FontInfo=(PLOGFONT)GlobalAlloc(GPTR,sizeof(LOGFONT)); + + for (i=0;i=FONT_MAX) return 0; + + // フォント名の取得 + strcpy(FontData[MaxFont].Name,Lf->lfFaceName); + + // フォントタイプの判別 + if (Lf->lfCharSet==SHIFTJIS_CHARSET) + { + // 日本語フォント + FontData[MaxFont].Type=FONT_SHIFTJIS; + } + else if (Lf->lfCharSet==SYMBOL_CHARSET) + { + // シンボルフォント + FontData[MaxFont].Type=FONT_SYMBOL; + } + else + { + // 英語フォント + FontData[MaxFont].Type=FONT_ANSI; + } + + // 文字セットの取得 + FontData[MaxFont].CharSet=Lf->lfCharSet; + + MaxFont++; + + return 1; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 全オブジェクトの破棄 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elFont::DestroyObject(void) +{ + GlobalFree((LOCALHANDLE)FontInfo); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フォント使用開始 ( 明朝とゴシック ) -*/ +/*- -*/ +/*- int Type : フォント種別 -*/ +/*- MINCHOH = 明朝体 -*/ +/*- GOTHIC = ゴシック体 -*/ +/*- int Size : ドット数 -*/ +/*- int Round : 回転角度 ( 反時計回り ) -*/ +/*- 省略/0 = 回転なし -*/ +/*- BOOL Bold : 省略/FALSE = 太字なし -*/ +/*- TRUE = 太字 -*/ +/*- BOOL Italic : 省略/FALSE = 斜体なし -*/ +/*- TRUE = 斜体 -*/ +/*- BOOL Line : 省略/FALSE = 下線なし -*/ +/*- TRUE = 下線 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elFont::Begin(int Type,int Size,int Round=0, + BOOL Bold=FALSE,BOOL Italic=FALSE,BOOL Line=FALSE) +{ + switch (Type) + { + case MINCHOH: + { + lstrcpy(FontInfo->lfFaceName,"標準明朝"); + + break; + } + + case GOTHIC: + { + lstrcpy(FontInfo->lfFaceName,"標準ゴシック"); + + break; + } + } + + FontHeight=Size; + + FontInfo->lfWeight=(Bold==FALSE)*FW_NORMAL+(Bold==TRUE)*FW_BOLD; + FontInfo->lfEscapement=Round*10; + FontInfo->lfWidth=0; + FontInfo->lfHeight=FontHeight; + FontInfo->lfItalic=Italic; + FontInfo->lfUnderline=Line; + FontInfo->lfCharSet=SHIFTJIS_CHARSET; + + NewFont=CreateFontIndirect(FontInfo); + + DDBack->GetDC(&FontDC); + + OldFont=(HFONT)SelectObject(FontDC,NewFont); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フォント使用開始 ( 自由指定 ) -*/ +/*- -*/ +/*- char* Type : フォント種別 -*/ +/*- int Size : ドット数 -*/ +/*- int Round : 回転角度 ( 反時計回り ) -*/ +/*- 省略/0 = 回転なし -*/ +/*- BOOL Bold : 省略/FALSE = 太字なし -*/ +/*- TRUE = 太字 -*/ +/*- BOOL Italic : 省略/FALSE = 斜体なし -*/ +/*- TRUE = 斜体 -*/ +/*- BOOL Line : 省略/FALSE = 下線なし -*/ +/*- TRUE = 下線 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elFont::Begin(char* Type,int Size,int Round=0, + BOOL Bold=FALSE,BOOL Italic=FALSE,BOOL Line=FALSE) +{ + int i; + + lstrcpy(FontInfo->lfFaceName,Type); + + FontHeight=Size; + + FontInfo->lfWeight=(Bold==FALSE)*FW_NORMAL+(Bold==TRUE)*FW_BOLD; + FontInfo->lfEscapement=Round*10; + FontInfo->lfWidth=0; + FontInfo->lfHeight=FontHeight; + FontInfo->lfItalic=Italic; + FontInfo->lfUnderline=Line; + FontInfo->lfCharSet=SHIFTJIS_CHARSET; + + for (i=0;ilfCharSet=FontData[i].CharSet; + + break; + } + } + + NewFont=CreateFontIndirect(FontInfo); + + DDBack->GetDC(&FontDC); + + OldFont=(HFONT)SelectObject(FontDC,NewFont); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- フォント使用終了 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elFont::Before(void) +{ + SelectObject(FontDC,OldFont); + DeleteObject(NewFont); + + DDBack->ReleaseDC(FontDC); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 色指定 -*/ +/*- -*/ +/*- COLORREF TextColor : テキストの色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- COLORREF BackColor : 背景の色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- 省略 = RGB(0,0,0) -*/ +/*- BOOL Mode : 省略/TRUE = 背景色の透明化 -*/ +/*- FALSE = 背景色有効 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elFont::Color(COLORREF TextColor,COLORREF BackColor=RGB(0,0,0), + BOOL Mode=TRUE) +{ + SetTextColor(FontDC,TextColor); + SetBkColor(FontDC,BackColor); + + FontTextColor=TextColor; + FontBackColor=BackColor; + + if (Mode) + { + SetBkMode(FontDC,TRANSPARENT); + } + else + { + SetBkMode(FontDC,OPAQUE); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 文字列の描画 -*/ +/*- -*/ +/*- int Px : X座標 -*/ +/*- int Py : Y座標 -*/ +/*- char* Str : 描画する文字列 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elFont::Draw(int Px,int Py,char* Str) +{ + TextOut(FontDC,Px,Py,Str,strlen(Str)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 領域内に文字列の描画 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- char* Str : 描画する文字列 -*/ +/*- WORD Effect : 文字装飾 -*/ +/*- 省略 = なし -*/ +/*- FONT_SHADOW = 影 -*/ +/*- FONT_BOLD = 太字 -*/ +/*- FONT_BOLDY = 縦に太字 -*/ +/*- 1〜255 = 改行幅 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// 文字装飾 +static const WORD FONT_SHADOW=0x0100; // 影 +static const WORD FONT_BOLD= 0x0200; // 太字 +static const WORD FONT_BOLDY= 0x0400; // 縦に太字 + +void elFont::Draw(int X1,int Y1,int X2,int Y2,char* Str,WORD Effect=0x0000) +{ + static int i,j,k; // 汎用カウンター + static BOOL f; // 汎用フラグ + static int Dx,Dy; // 描画座標 + static int Sy; // 文字のYサイズ + static char Buffer[]=" "; // 描画する文字 + static SIZE size; // 描画した文字のサイズ + + // 裏画面をロック解除 + SelectObject(FontDC,OldFont); + DeleteObject(NewFont); + DDBack->ReleaseDC(FontDC); + + // フォントスプライトのクリアー + elDraw::SpriteClear(FONT_SPRITE); + + // フォントスプライトで再ロック + NewFont=CreateFontIndirect(FontInfo); + Sprite[FONT_SPRITE].Object->GetDC(&FontDC); + OldFont=(HFONT)SelectObject(FontDC,NewFont); + + SetBkMode(FontDC,TRANSPARENT); + + // 座標の初期化 + Dx=X1; + Dy=Y1; + Sy=FontHeight+(Effect&0xFF); + + // 文字の色が黒に近すぎる場合 + if (GetRValue(FontTextColor)<16 && GetGValue(FontTextColor)<16 && + GetBValue(FontTextColor)<16) + { + // RGB(16,16,16)を文字の色に設定 + FontTextColor=RGB(16,16,16); + } + + // 影の色が黒に近すぎる場合 + if (GetRValue(FontBackColor)<16 && GetGValue(FontBackColor)<16 && + GetBValue(FontBackColor)<16) + { + // RGB(16,16,16)を影の色に設定 + FontBackColor=RGB(16,16,16); + } + + // 左上の描画範囲を取得 + TextPos[0].X1=Dx; + TextPos[0].Y1=Dy; + + FontCount=1; + + // 1文字ずつ描画 + for (i=0;i<(int)strlen(Str);i++) + { + // 2バイト文字の場合 + if (IsDBCSLeadByte(Str[i])) + { + // 全角1文字描画 + Buffer[0]=Str[i]; + Buffer[1]=Str[i+1]; + + // 1文字のサイズを取得 + GetTextExtentPoint32(FontDC,Buffer,2,&size); + + // 影をつける場合 + if (Effect&FONT_SHADOW) + { + size.cx++; + size.cy++; + } + + // 横に太字の場合 + if (Effect&FONT_BOLD) size.cx++; + + // 縦に太字の場合 + if (Effect&FONT_BOLDY) size.cy++; + + i++; + j=2; + } + // 1バイト文字の場合 + else + { + // 改行コードの場合 + if (Str[i]==0x0A) + { + // 描画しないで改行 + size.cx=0; + size.cy=0; + } + else + { + // 半角1文字描画 + Buffer[0]=Str[i]; + Buffer[1]=NULL; + + // 1文字のサイズを取得 + GetTextExtentPoint32(FontDC,Buffer,1,&size); + + // 影をつける場合 + if (Effect&FONT_SHADOW) + { + size.cx++; + size.cy++; + } + + // 横に太字の場合 + if (Effect&FONT_BOLD) size.cx++; + + // 縦に太字の場合 + if (Effect&FONT_BOLDY) size.cy++; + } + + j=1; + } + + // フォント描画位置の保存 + TextPos[FontCount].X1=Dx; + TextPos[FontCount].Y1=Dy; + TextPos[FontCount].X2=TextPos[FontCount].X1+size.cx; + TextPos[FontCount].Y2=TextPos[FontCount].Y1+size.cy; + + FontCount++; + + // スプライト内座標の更新 + Dx+=size.cx; + if (size.cy>Sy) Sy=size.cy; + + // 描画範囲の幅を超えたか改行コードがあった場合 + if (Dx>X2 || Str[i]==0x0A) + { + FontCount--; + + // 最後が禁則文字かどうかチェック + f=FALSE; + + if (Dx>X2) + { + for (k=0;kX2 || Str[i]==0x0A) + { + // 新たに左端から描画開始 + Dx=X1; + Dy+=Sy; + } + + // 描画範囲を超えた場合、終了 + if (Dy+Sy>=Y2) break; + } + else + { + // 影をつける場合 + if (Effect&FONT_SHADOW) + { + SetTextColor(FontDC,FontBackColor); + + // 横に太字の場合 + if (Effect&FONT_BOLD) + { + // 縦に太字の場合 + if (Effect&FONT_BOLDY) + { + Draw(Dx-size.cx+2,Dy+2,Buffer); + } + else + { + Draw(Dx-size.cx+2,Dy+1,Buffer); + } + } + else + { + // 縦に太字の場合 + if (Effect&FONT_BOLDY) + { + Draw(Dx-size.cx+1,Dy+2,Buffer); + } + else + { + Draw(Dx-size.cx+1,Dy+1,Buffer); + } + } + } + + // 通常の文字を描画 + SetTextColor(FontDC,FontTextColor); + Draw(Dx-size.cx,Dy,Buffer); + + // 横に太字の場合 + if (Effect&FONT_BOLD) + { + Draw(Dx-size.cx+1,Dy,Buffer); + + // 縦に太字の場合 + if (Effect&FONT_BOLDY) Draw(Dx-size.cx+1,Dy+1,Buffer); + } + + // 縦に太字の場合 + if (Effect&FONT_BOLDY) Draw(Dx-size.cx,Dy+1,Buffer); + + // 右下の描画範囲を更新 + if (TextPos[0].X2ReleaseDC(FontDC); + + // そのまま裏画面に描画する場合 + if (DrawAndShow) + { + // 1回で全てを表示 + elDraw::Layer(TextPos[0].X1,TextPos[0].Y1,FONT_SPRITE, + TextPos[0].X1,TextPos[0].Y1, + TextPos[0].X2,TextPos[0].Y2); + } + + // 裏画面で再ロック + NewFont=CreateFontIndirect(FontInfo); + DDBack->GetDC(&FontDC); + OldFont=(HFONT)SelectObject(FontDC,NewFont); + + // 表示カウントと表示ウェイトを初期化 + ShowCount=0; + ShowWait=F(0); + + // フォント描画後の表示フラグを初期化 + DrawAndShow=TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 文字列を非表示状態で描画 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- char* Str : 描画する文字列 -*/ +/*- WORD Effect : 文字装飾 -*/ +/*- 省略 = なし -*/ +/*- FONT_SHADOW = 影 -*/ +/*- FONT_BOLD = 太字 -*/ +/*- FONT_BOLDY = 縦に太字 -*/ +/*- 1〜255 = 改行幅 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elFont::HideDraw(int X1,int Y1,int X2,int Y2,char* Str,WORD Effect=0x0000) +{ + DrawAndShow=FALSE; + + Draw(X1,Y1,X2,Y2,Str,Effect); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 領域内に文字列の描画 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- char* Str : 描画する文字列 -*/ +/*- int Pos : 描画位置 -*/ +/*- 省略 = FONT_LEFT -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// 描画位置 +static const int FONT_LEFT=0; // 左寄せ +static const int FONT_CENTER=1; // 中央 +static const int FONT_RIGHT=2; // 右寄せ + +void elFont::AreaDraw(int X1,int Y1,int X2,int Y2,char* Str,int Pos=FONT_LEFT) +{ + static RECT rect; + + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + switch (Pos) + { + // 左寄せ + case FONT_LEFT: + { + DrawText(FontDC,Str,-1,&rect,DT_WORDBREAK|DT_NOPREFIX|DT_LEFT); + + break; + } + + // 中央 + case FONT_CENTER: + { + DrawText(FontDC,Str,-1,&rect,DT_WORDBREAK|DT_NOPREFIX|DT_CENTER); + + break; + } + + // 右寄せ + case FONT_RIGHT: + { + DrawText(FontDC,Str,-1,&rect,DT_WORDBREAK|DT_NOPREFIX|DT_RIGHT); + + break; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 範囲指定された文字列の高さの取得 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- char* Str : 描画する文字列 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elFont::GetHeight(int X1,int Y1,int X2,int Y2,char* Str) +{ + static RECT rect; + + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + return DrawText(FontDC,Str,-1,&rect,DT_WORDBREAK|DT_NOPREFIX|DT_CALCRECT); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- アンチエイリアスフォント使用開始 ( 明朝とゴシック ) -*/ +/*- -*/ +/*- int Type : フォント種別 -*/ +/*- MINCHOH = 明朝体 -*/ +/*- GOTHIC = ゴシック体 -*/ +/*- int Size : ドット数 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elFont::BeginAA(int Type,int Size) +{ + switch (Type) + { + case MINCHOH: + { + lstrcpy(FontInfo->lfFaceName,"標準明朝"); + + break; + } + + case GOTHIC: + { + lstrcpy(FontInfo->lfFaceName,"標準ゴシック"); + + break; + } + } + + FontHeight=Size*2; + + FontInfo->lfWeight=FW_NORMAL; + FontInfo->lfEscapement=0; + FontInfo->lfWidth=0; + FontInfo->lfHeight=FontHeight; + FontInfo->lfItalic=FALSE; + FontInfo->lfUnderline=FALSE; + FontInfo->lfCharSet=SHIFTJIS_CHARSET; + + NewFont=CreateFontIndirect(FontInfo); + + Sprite[FONTBUFFER_SPRITE].Object->GetDC(&FontDC); + + OldFont=(HFONT)SelectObject(FontDC,NewFont); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- アンチエイリアスフォント使用開始 ( 自由指定 ) -*/ +/*- -*/ +/*- char* Type : フォント種別 -*/ +/*- int Size : ドット数 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elFont::BeginAA(char* Type,int Size) +{ + int i; + + lstrcpy(FontInfo->lfFaceName,Type); + + FontHeight=Size*2; + + FontInfo->lfWeight=FW_NORMAL; + FontInfo->lfEscapement=0; + FontInfo->lfWidth=0; + FontInfo->lfHeight=FontHeight; + FontInfo->lfItalic=FALSE; + FontInfo->lfUnderline=FALSE; + FontInfo->lfCharSet=SHIFTJIS_CHARSET; + + for (i=0;ilfCharSet=FontData[i].CharSet; + + break; + } + } + + NewFont=CreateFontIndirect(FontInfo); + + Sprite[FONTBUFFER_SPRITE].Object->GetDC(&FontDC); + + OldFont=(HFONT)SelectObject(FontDC,NewFont); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- アンチエイリアスフォント使用終了 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elFont::BeforeAA(void) +{ + SelectObject(FontDC,OldFont); + DeleteObject(NewFont); + + Sprite[FONTBUFFER_SPRITE].Object->ReleaseDC(FontDC); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- アンチエイリアスをして文字列を描画 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- char* Str : 描画する文字列 -*/ +/*- WORD Effect : 文字装飾 -*/ +/*- 省略 = なし -*/ +/*- FONT_SHADOW = 影 -*/ +/*- FONT_BOLD = 太字 -*/ +/*- FONT_BOLDY = 縦に太字 -*/ +/*- 1〜255 = 改行幅 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elFont::DrawAA(int X1,int Y1,int X2,int Y2,char* Str,WORD Effect=0x0000) +{ + static int i,j,k; // 汎用カウンター + static BOOL f; // 汎用フラグ + static int Dx,Dy; // 描画座標 + static int Sx,Sy,Sy2; // スプライト内座標 + static char Buffer[]=" "; // 描画する文字 + static SIZE size; // 描画した文字のサイズ + + // フォントスプライトのクリアー + elDraw::SpriteClear(FONT_SPRITE); + + // ロック解除 + SelectObject(FontDC,OldFont); + DeleteObject(NewFont); + Sprite[FONTBUFFER_SPRITE].Object->ReleaseDC(FontDC); + + // フォントバッファスプライトのクリアー + elDraw::SpriteClear(FONTBUFFER_SPRITE); + + // 再ロック + NewFont=CreateFontIndirect(FontInfo); + Sprite[FONTBUFFER_SPRITE].Object->GetDC(&FontDC); + OldFont=(HFONT)SelectObject(FontDC,NewFont); + + SetBkMode(FontDC,TRANSPARENT); + + // 座標の初期化 + Dx=X1; + Dy=Y1; + Sx=0; + Sy=FontHeight+(Effect&0xFF); + + // 文字の色が黒に近すぎる場合 + if (GetRValue(FontTextColor)<16 && GetGValue(FontTextColor)<16 && + GetBValue(FontTextColor)<16) + { + // RGB(16,16,16)を文字の色に設定 + FontTextColor=RGB(16,16,16); + } + + // 影の色が黒に近すぎる場合 + if (GetRValue(FontBackColor)<16 && GetGValue(FontBackColor)<16 && + GetBValue(FontBackColor)<16) + { + // RGB(16,16,16)を影の色に設定 + FontBackColor=RGB(16,16,16); + } + + // 左上の描画範囲を取得 + TextPos[0].X1=Dx; + TextPos[0].Y1=Dy; + + FontCount=1; + + // 1文字ずつ描画 + for (i=0;i<(int)strlen(Str);i++) + { + // 2バイト文字の場合 + if (IsDBCSLeadByte(Str[i])) + { + // 全角1文字描画 + Buffer[0]=Str[i]; + Buffer[1]=Str[i+1]; + + // 影をつける場合 + if (Effect&FONT_SHADOW) + { + SetTextColor(FontDC,FontBackColor); + + // 横に太字の場合 + if (Effect&FONT_BOLD) + { + // 縦に太字の場合 + if (Effect&FONT_BOLDY) + { + Draw(Sx+3,3,Buffer); + } + else + { + Draw(Sx+3,2,Buffer); + } + } + else + { + // 縦に太字の場合 + if (Effect&FONT_BOLDY) + { + Draw(Sx+2,3,Buffer); + } + else + { + Draw(Sx+2,2,Buffer); + } + } + } + + // 通常の文字を描画 + SetTextColor(FontDC,FontTextColor); + Draw(Sx,0,Buffer); + + // 横に太字の場合 + if (Effect&FONT_BOLD) + { + Draw(Sx+1,0,Buffer); + + // 縦に太字の場合 + if (Effect&FONT_BOLDY) Draw(Sx+1,1,Buffer); + } + + // 縦に太字の場合 + if (Effect&FONT_BOLDY) Draw(Sx,1,Buffer); + + // 1文字のサイズを取得 + GetTextExtentPoint32(FontDC,Buffer,2,&size); + + // 奇数だった場合、偶数に変換 + if (size.cx%2) size.cx++; + if (size.cy%2) size.cy++; + + // 影をつける場合 + if (Effect&FONT_SHADOW) + { + size.cx+=2; + size.cy+=2; + } + + // 横に太字の場合 + if (Effect&FONT_BOLD) size.cx++; + + // 縦に太字の場合 + if (Effect&FONT_BOLDY) size.cy++; + + i++; + j=2; + } + // 1バイト文字の場合 + else + { + // 改行コードの場合 + if (Str[i]==0x0A) + { + // 描画しないで改行 + size.cx=0; + size.cy=0; + } + else + { + // 半角1文字描画 + Buffer[0]=Str[i]; + Buffer[1]=NULL; + + // 影をつける場合 + if (Effect&FONT_SHADOW) + { + SetTextColor(FontDC,FontBackColor); + + // 横に太字の場合 + if (Effect&FONT_BOLD) + { + // 縦に太字の場合 + if (Effect&FONT_BOLDY) + { + Draw(Sx+3,3,Buffer); + } + else + { + Draw(Sx+3,2,Buffer); + } + } + else + { + // 縦に太字の場合 + if (Effect&FONT_BOLDY) + { + Draw(Sx+2,3,Buffer); + } + else + { + Draw(Sx+2,2,Buffer); + } + } + } + + // 通常の文字を描画 + SetTextColor(FontDC,FontTextColor); + Draw(Sx,0,Buffer); + + // 横に太字の場合 + if (Effect&FONT_BOLD) + { + Draw(Sx+1,0,Buffer); + + // 縦に太字の場合 + if (Effect&FONT_BOLDY) Draw(Sx+1,1,Buffer); + } + + // 縦に太字の場合 + if (Effect&FONT_BOLDY) Draw(Sx,1,Buffer); + + // 1文字のサイズを取得 + GetTextExtentPoint32(FontDC,Buffer,1,&size); + + // 奇数だった場合、偶数に変換 + if (size.cx%2) size.cx++; + if (size.cy%2) size.cy++; + + // 影をつける場合 + if (Effect&FONT_SHADOW) + { + size.cx+=2; + size.cy+=2; + } + + // 横に太字の場合 + if (Effect&FONT_BOLD) size.cx++; + + // 縦に太字の場合 + if (Effect&FONT_BOLDY) size.cy++; + } + + j=1; + } + + // フォント描画位置の保存 + TextPos[FontCount].X1=Dx+(Sx>>1); + TextPos[FontCount].Y1=Dy; + TextPos[FontCount].X2=TextPos[FontCount].X1+(size.cx>>1); + TextPos[FontCount].Y2=TextPos[FontCount].Y1+(size.cy>>1); + + FontCount++; + + // スプライト内座標の更新 + Sx+=size.cx; + if (size.cy>Sy) Sy=size.cy; + + // 描画範囲の幅かフォントスプライトの幅を超えたか、改行コードがあった場合 + if (Dx+(Sx>>1)>=X2 || Sx>=elDraw::Width || Str[i]==0x0A) + { + FontCount--; + + // 最後が禁則文字かどうかチェック + f=FALSE; + + if (Dx+(Sx>>1)>=X2) + { + for (k=0;kReleaseDC(FontDC); + + // 描画範囲の下側を超える場合、一部を未処理 + Sy2=Sy; + if (Dy+(Sy>>1)>Y2) Sy2-=((Dy+(Sy>>1)-Y2)<<1); + + // 右下の描画範囲を取得 + if (TextPos[0].X2>1)) TextPos[0].X2=Dx+(Sx>>1); + if (TextPos[0].Y2>1)) TextPos[0].Y2=Dy+(Sy2>>1); + + // 裏画面を参照しながらフォントスプライトにアンチエイリアス描画 + DrawAA2(Dx,Dy,0,0,Sx,Sy2); + + // フォントバッファスプライトのクリアー + elDraw::SpriteClear(FONTBUFFER_SPRITE); + + // 再ロック + NewFont=CreateFontIndirect(FontInfo); + Sprite[FONTBUFFER_SPRITE].Object->GetDC(&FontDC); + OldFont=(HFONT)SelectObject(FontDC,NewFont); + + SetBkMode(FontDC,TRANSPARENT); + + // 描画位置の更新 + Dx+=Sx>>1; + + // 処理可能な右端を超えたか、改行コードがあった場合 + if (Dx+(size.cx>>1)>=X2 || Str[i]==0x0A) + { + // 新たに左端から描画開始 + Dx=X1; + Dy+=Sy>>1; + } + + Sx=0; + Sy=FontHeight+(Effect&0xFF); + + // 描画範囲を超えた場合、終了 + if (Dy>=Y2) break; + } + } + + // まだ描画していないデータがある場合 + if (Sx!=0) + { + // 残りを描画 + SelectObject(FontDC,OldFont); + DeleteObject(NewFont); + Sprite[FONTBUFFER_SPRITE].Object->ReleaseDC(FontDC); + + Sy2=Sy; + if (Dy+(Sy>>1)>Y2) Sy2-=((Dy+(Sy>>1)-Y2)<<1); + + if (TextPos[0].X2>1)) TextPos[0].X2=Dx+(Sx>>1); + if (TextPos[0].Y2>1)) TextPos[0].Y2=Dy+(Sy2>>1); + + DrawAA2(Dx,Dy,0,0,Sx,Sy); + + NewFont=CreateFontIndirect(FontInfo); + Sprite[FONTBUFFER_SPRITE].Object->GetDC(&FontDC); + OldFont=(HFONT)SelectObject(FontDC,NewFont); + } + + // そのまま裏画面に描画する場合 + if (DrawAndShow) + { + // 1回で全てを表示 + elDraw::Layer(TextPos[0].X1,TextPos[0].Y1,FONT_SPRITE, + TextPos[0].X1,TextPos[0].Y1, + TextPos[0].X2,TextPos[0].Y2); + } + + // 表示カウントと表示ウェイトを初期化 + ShowCount=0; + ShowWait=F(0); + + // フォント描画後の表示フラグを初期化 + DrawAndShow=TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- アンチエイリアスをして文字列を描画2 ※ 内部で使用 -*/ +/*-   -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elFont::DrawAA2(int Px,int Py,int X1,int Y1,int X2,int Y2) +{ + static int i; // 汎用カウンター + static DWORD x,y,x2,Sx,Sy,Ex,Ey; // 汎用座標 + static DDSURFACEDESC ddsd1,ddsd2,ddsd3; // サーフェースロック用 + static LPWORD data161,data162,data163; // 16ビットサーフェースのポインター + static LPBYTE data241,data242,data243; // 24ビットサーフェースのポインター + static LPDWORD data321,data322,data323; // 32ビットサーフェースのポインター + static WORD AddPitch161; // 16ビットサーフェースの加算値 + static WORD AddPitch162; //       〃 + static WORD AddPitch163; //       〃 + static DWORD AddPitch241; // 24ビットサーフェースの加算値 + static DWORD AddPitch242; //       〃 + static DWORD AddPitch243; //       〃 + static DWORD AddPitch321; // 32ビットサーフェースの加算値 + static DWORD AddPitch322; //       〃 + static DWORD AddPitch323; //       〃 + static DWORD Buff,R1,G1,B1,R2,G2,B2; // RGB値 + static BYTE R,G,B; //       〃 + static int Count; // ピクセルのカウント + + // 描画領域の計算 + Sx=0; + Sy=0; + Ex=(X2-X1)>>1; + Ey=(Y2-Y1)>>1; + + if (Px+((int)Ex-(int)Sx)>elDraw::Vx2) + { + Ex-=(Px+(Ex-Sx)-elDraw::Vx2); + } + + if (Py+((int)Ey-(int)Sy)>elDraw::Vy2) + { + Ey-=(Py+(Ey-Sy)-elDraw::Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd3,0x00,sizeof(DDSURFACEDESC)); + ddsd3.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + if (Sprite[FONTBUFFER_SPRITE].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL) + !=DD_OK) + { + return FALSE; + } + + // 転送先スプライトのロック + if (Sprite[FONT_SPRITE].Object->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL)!=DD_OK) + { + DD_UNLOCK(Sprite[FONTBUFFER_SPRITE].Object,ddsd1.lpSurface); + + return FALSE; + } + + // 裏画面のロック + if (DDBack->Lock(NULL,&ddsd3,DDLOCK_WAIT,NULL)!=DD_OK) + { + DD_UNLOCK(Sprite[FONTBUFFER_SPRITE].Object,ddsd1.lpSurface); + DD_UNLOCK(Sprite[FONT_SPRITE].Object,ddsd2.lpSurface); + + return FALSE; + } + + // 16ビットカラーの場合 + if (elSystem::ColorBit()==16) + { + // Y方向への追加バイト数の取得 + AddPitch161=(WORD)(ddsd1.lPitch>>1); + AddPitch162=(WORD)(ddsd2.lPitch>>1); + AddPitch163=(WORD)(ddsd3.lPitch>>1); + + // スプライトの先頭位置を取得 + data161=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch161; + data162=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch162; + data163=(LPWORD)ddsd3.lpSurface+Px+Py*AddPitch163; + + // データ転送 + Ex<<=1; + Ey<<=1; + + for (y=Sy;y>elDraw::ShiftR2)&0x1F); + G1+=((Buff>>elDraw::ShiftG2)&0x1F); + B1+=((Buff>>elDraw::ShiftB2)&0x1F); + + Count++; + } + + if (x>Sx) + { + // 左 + Buff=*(data161+x-1); + + if (Buff!=0x0000) + { + R1+=((Buff>>elDraw::ShiftR2)&0x1F); + G1+=((Buff>>elDraw::ShiftG2)&0x1F); + B1+=((Buff>>elDraw::ShiftB2)&0x1F); + + Count++; + } + + if (y>Sy) + { + // 左上 + Buff=*(data161+x-1-AddPitch161); + + if (Buff!=0x0000) + { + R1+=((Buff>>elDraw::ShiftR2)&0x1F); + G1+=((Buff>>elDraw::ShiftG2)&0x1F); + B1+=((Buff>>elDraw::ShiftB2)&0x1F); + + Count++; + } + } + + if (y>elDraw::ShiftR2)&0x1F); + G1+=((Buff>>elDraw::ShiftG2)&0x1F); + B1+=((Buff>>elDraw::ShiftB2)&0x1F); + + Count++; + } + } + } + + if (x>elDraw::ShiftR2)&0x1F); + G1+=((Buff>>elDraw::ShiftG2)&0x1F); + B1+=((Buff>>elDraw::ShiftB2)&0x1F); + + Count++; + } + + if (y>Sy) + { + // 右上 + Buff=*(data161+x+1-AddPitch161); + + if (Buff!=0x0000) + { + R1+=((Buff>>elDraw::ShiftR2)&0x1F); + G1+=((Buff>>elDraw::ShiftG2)&0x1F); + B1+=((Buff>>elDraw::ShiftB2)&0x1F); + + Count++; + } + } + + if (y>elDraw::ShiftR2)&0x1F); + G1+=((Buff>>elDraw::ShiftG2)&0x1F); + B1+=((Buff>>elDraw::ShiftB2)&0x1F); + + Count++; + } + } + } + + if (y>Sy) + { + // 上 + Buff=*(data161+x-AddPitch161); + + if (Buff!=0x0000) + { + R1+=((Buff>>elDraw::ShiftR2)&0x1F); + G1+=((Buff>>elDraw::ShiftG2)&0x1F); + B1+=((Buff>>elDraw::ShiftB2)&0x1F); + + Count++; + } + } + + if (y>elDraw::ShiftR2)&0x1F); + G1+=((Buff>>elDraw::ShiftG2)&0x1F); + B1+=((Buff>>elDraw::ShiftB2)&0x1F); + + Count++; + } + } + + // ドットに色が存在した場合 + if (Count) + { + // 明度を1ドット分加算 + R1+=31; + G1+=31; + B1+=31; + + // 背景の色を取得 + Buff=*(data163+x2); + + R2=((Buff>>elDraw::ShiftR2)&0x1F); + G2=((Buff>>elDraw::ShiftG2)&0x1F); + B2=((Buff>>elDraw::ShiftB2)&0x1F); + + // 不足している数だけ背景の色を加算 + for (i=Count;i<9-1;i++) + { + R1+=R2; + G1+=G2; + B1+=B2; + } + + // 明度の調節 + R1>>=3; + G1>>=3; + B1>>=3; + + // 最大明度を超えないようにチェック + if (R1>31) R1=31; + if (G1>31) G1=31; + if (B1>31) B1=31; + + // フォントスプライトに描画 + *(data162+x2)=(WORD)((R1<>2); + AddPitch322=(DWORD)(ddsd2.lPitch>>2); + AddPitch323=(DWORD)(ddsd3.lPitch>>2); + + // スプライトの先頭位置を取得 + data321=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch321; + data322=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch322; + data323=(LPDWORD)ddsd3.lpSurface+Px+Py*AddPitch323; + + // データ転送 + Ex<<=1; + Ey<<=1; + + for (y=Sy;y>elDraw::ShiftR)&0xFF); + G1+=((Buff>>elDraw::ShiftG)&0xFF); + B1+=((Buff>>elDraw::ShiftB)&0xFF); + + Count++; + } + + if (x>Sx) + { + // 左 + Buff=*(data321+x-1); + + if (Buff!=0x00000000) + { + R1+=((Buff>>elDraw::ShiftR)&0xFF); + G1+=((Buff>>elDraw::ShiftG)&0xFF); + B1+=((Buff>>elDraw::ShiftB)&0xFF); + + Count++; + } + + if (y>Sy) + { + // 左上 + Buff=*(data321+x-1-AddPitch321); + + if (Buff!=0x00000000) + { + R1+=((Buff>>elDraw::ShiftR)&0xFF); + G1+=((Buff>>elDraw::ShiftG)&0xFF); + B1+=((Buff>>elDraw::ShiftB)&0xFF); + + Count++; + } + } + + if (y>elDraw::ShiftR)&0xFF); + G1+=((Buff>>elDraw::ShiftG)&0xFF); + B1+=((Buff>>elDraw::ShiftB)&0xFF); + + Count++; + } + } + } + + if (x>elDraw::ShiftR)&0xFF); + G1+=((Buff>>elDraw::ShiftG)&0xFF); + B1+=((Buff>>elDraw::ShiftB)&0xFF); + + Count++; + } + + if (y>Sy) + { + // 右上 + Buff=*(data321+x+1-AddPitch321); + + if (Buff!=0x00000000) + { + R1+=((Buff>>elDraw::ShiftR)&0xFF); + G1+=((Buff>>elDraw::ShiftG)&0xFF); + B1+=((Buff>>elDraw::ShiftB)&0xFF); + + Count++; + } + } + + if (y>elDraw::ShiftR)&0xFF); + G1+=((Buff>>elDraw::ShiftG)&0xFF); + B1+=((Buff>>elDraw::ShiftB)&0xFF); + + Count++; + } + } + } + + if (y>Sy) + { + // 上 + Buff=*(data321+x-AddPitch321); + + if (Buff!=0x00000000) + { + R1+=((Buff>>elDraw::ShiftR)&0xFF); + G1+=((Buff>>elDraw::ShiftG)&0xFF); + B1+=((Buff>>elDraw::ShiftB)&0xFF); + + Count++; + } + } + + if (y>elDraw::ShiftR)&0xFF); + G1+=((Buff>>elDraw::ShiftG)&0xFF); + B1+=((Buff>>elDraw::ShiftB)&0xFF); + + Count++; + } + } + + // ドットに色が存在した場合 + if (Count) + { + // 明度を1ドット分加算 + R1+=255; + G1+=255; + B1+=255; + + // 背景の色を取得 + Buff=*(data323+x2); + + R2=((Buff>>elDraw::ShiftR)&0xFF); + G2=((Buff>>elDraw::ShiftG)&0xFF); + B2=((Buff>>elDraw::ShiftB)&0xFF); + + // 不足している数だけ背景の色を加算 + for (i=Count;i<9-1;i++) + { + R1+=R2; + G1+=G2; + B1+=B2; + } + + // 明度の調節 + R1>>=3; + G1>>=3; + B1>>=3; + + // 最大明度を超えないようにチェック + if (R1>255) R1=255; + if (G1>255) G1=255; + if (B1>255) B1=255; + + // フォントスプライトに描画 + *(data322+x2)=(R1<Sx) + { + // 左 + R=*(data241+x-3); + G=*(data241+x+1-3); + B=*(data241+x+2-3); + + if (R!=0x00 || G!=0x00 || B!=0x00) + { + R1+=R; + G1+=G; + B1+=B; + + Count++; + } + + if (y>Sy) + { + // 左上 + R=*(data241+x-3-AddPitch241); + G=*(data241+x+1-3-AddPitch241); + B=*(data241+x+2-3-AddPitch241); + + if (R!=0x00 || G!=0x00 || B!=0x00) + { + R1+=R; + G1+=G; + B1+=B; + + Count++; + } + } + + if (ySy) + { + // 右上 + R=*(data241+x+3-AddPitch241); + G=*(data241+x+1+3-AddPitch241); + B=*(data241+x+2+3-AddPitch241); + + if (R!=0x00 || G!=0x00 || B!=0x00) + { + R1+=R; + G1+=G; + B1+=B; + + Count++; + } + } + + if (ySy) + { + // 上 + R=*(data241+x-AddPitch241); + G=*(data241+x+1-AddPitch241); + B=*(data241+x+2-AddPitch241); + + if (R!=0x00 || G!=0x00 || B!=0x00) + { + R1+=R; + G1+=G; + B1+=B; + + Count++; + } + } + + if (y>=3; + G1>>=3; + B1>>=3; + + // 最大明度を超えないようにチェック + if (R1>255) R1=255; + if (G1>255) G1=255; + if (B1>255) B1=255; + + // フォントスプライトに描画 + *(data242+x2)=(BYTE)R1; + *(data242+x2+1)=(BYTE)G1; + *(data242+x2+2)=(BYTE)B1; + } + } + + // Y方向に加算 + data241+=AddPitch241+AddPitch241; + data242+=AddPitch242; + data243+=AddPitch243; + } + } + + // スプライトのロック解除 + DD_UNLOCK(Sprite[FONTBUFFER_SPRITE].Object,ddsd1.lpSurface); + DD_UNLOCK(Sprite[FONT_SPRITE].Object,ddsd2.lpSurface); + DD_UNLOCK(DDBack,ddsd3.lpSurface); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- アンチエイリアスをして文字列を非表示状態で描画 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- char* Str : 描画する文字列 -*/ +/*- WORD Effect : 文字装飾 -*/ +/*- 省略 = なし -*/ +/*- FONT_SHADOW = 影 -*/ +/*- FONT_BOLD = 太字 -*/ +/*- FONT_BOLDY = 縦に太字 -*/ +/*- 1〜255 = 改行幅 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elFont::HideDrawAA(int X1,int Y1,int X2,int Y2,char* Str,WORD Effect=0x0000) +{ + DrawAndShow=FALSE; + + DrawAA(X1,Y1,X2,Y2,Str,Effect); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 非表示状態で描画された文字列の表示 -*/ +/*- -*/ +/*- float Wait : 次の文字を表示するまでの待ち時間 -*/ +/*- 省略/0 = 全てを表示 -*/ +/*- 1〜 = 1秒間を1.0として指定 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 表示終了 -*/ +/*- FALSE = 表示中 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elFont::Show(float Wait=F(0)) +{ + static int i; // 汎用カウンター + + // 待ち時間が0か、全ての文字を表示し終えた場合 + if (Wait==F(0) || ShowCount>FontCount) + { + // 1回で全てを表示 + elDraw::Layer(TextPos[0].X1,TextPos[0].Y1,FONT_SPRITE, + TextPos[0].X1,TextPos[0].Y1, + TextPos[0].X2,TextPos[0].Y2); + + // 表示位置を終端に設定 + ShowCount=FontCount+1; + } + else + { + // 1文字ずつ表示 + for (i=1;iFontCount) return TRUE; + + // 時間の経過 + ShowWait+=FrameTime; + + // 待ち時間を超えた場合 + if (ShowWait>=Wait) + { + // 次の文字を表示 + if (ShowCount<=FontCount) + { + ShowCount++; + } + + ShowWait=F(0); + } + + return FALSE; +} + +/*==============================================================================*/ +/*= =*/ +/*= メニュークラス定義 ( elMenu ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef MENU + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- メニュークラスの初期化 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMenu::Init(void) +{ + int i; + + // メニュー構造体の初期化 + for (i=0;i=MENU_MAXSIZE-1) Buffer[MENU_MAXSIZE-1]=NULL; + + strcpy(Menu[MenuMax].Str,Buffer); + + if (++MenuMax>MENU_MAX-1) MenuMax=MENU_MAX-1; + } + + fclose(_Fpt); + } + + // メニュー構造体処理 + for (i=0;i=3) + { + if (Menu[i].Str[Len-1]==')' && Menu[i].Str[Len-3]=='(') + { + Menu[i].ShortCut=(unsigned char)Menu[i].Str[Len-2]; + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- メニュー描画 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elMenu::Draw(void) +{ + static int i,j,No; + static LOGBRUSH LogBrush; + static HBRUSH NowBrush,OldBrush; + static HPEN NowPen,OldPen; + static SIZE Size; + + static BOOL SkipKey; + static int KeyUp,KeyDown,KeyLeft,KeyRight; + static int KeySelect1,KeySelect2,KeyCancel; + + if (MenuPosX==-1 && MenuPosY==-1) + { + // トップメニュー以外を非表示に設定 + for (i=0;i0) + { + if (--MenuPosY<1) + { + for (i=0;Menu[No].Level/10==Menu[No+i].Level/10;i++,MenuPosY++); + } + } + + // [↓] : カーソルを下に移動 + if ((KeyDown==PUSH_KEY || KeyDown==HOLD_KEY) && MenuPosY>0) + { + if (Menu[No].Level/10==Menu[No+1].Level/10) + { + MenuPosY++; + } + else + { + for (i=1;Menu[No].Level/10==Menu[No-i].Level/10 && + Menu[No-i].Level%10!=0;i++,MenuPosY--); + } + } + + // [←] : 右側のメニュー項目に移動 + if (KeyLeft==PUSH_KEY || KeyLeft==HOLD_KEY) + { + if (--MenuPosX<1) MenuPosX=MenuTopCount; + + MenuPosY=0; + + // トップメニュー以外を非表示に設定 + for (i=0;iMenuTopCount) MenuPosX=1; + + MenuPosY=0; + + // トップメニュー以外を非表示に設定 + for (i=0;i=Menu[i].Px && MousePY>=Menu[i].Py && + MousePX<=Menu[i].Px+Menu[i].Width+20 && + MousePY<=Menu[i].Py+12+10) + { + // 現在のカーソル位置と違うメニュー項目の場合 + if (MenuPosX!=Menu[i].Level/10 || MenuPosY!=Menu[i].Level%10) + { + // トップメニュー以外を非表示に設定 + if (MenuPosX!=Menu[i].Level/10) + { + for (j=0;j=0) + { + strcat(Buffer,FileName); + + for (Pos=strlen(Buffer);Buffer[Pos]!='\\';Pos--) + { + Buffer[Pos]=NULL; + } + } + + strcat(Buffer,MotionFileName); + + if ((_Fpt=fopen(Buffer,"rt"))!=NULL) + { + MotionNo=-1; + + while (TRUE) + { + // 最初の項目の読み込み + fscanf(_Fpt,"%s",Buffer); + + // 'END'が見つかるか、ファイルの終端ならばループ終了 + if (!strcmp(Buffer,"END")) break; + if (feof(_Fpt)) break; + + // 最初が'M'ならばモーションNo + if (Buffer[0]=='M') + { + // モーションNoを取得 + MotionTopNo=(Buffer[1]-'0')*10+(Buffer[2]-'0'); + + MotionDataNo[ListNo][MotionTopNo-1]=MotionNo+1; + + ReadyInitNo=0; + + // モーションのコメントの読み込み + fscanf(_Fpt,"%s",Buffer); + + continue; + } + + // モーションフレーム数に加算 + if (++MotionNo==FRAME_MAX) + { + return (D3SKT)elDraw::Error("elSkeleton::LoadObject", + "フレーム数が多過ぎます"); + } + + // モデルNoの読み込み + MotionData[ListNo][MotionNo].Model=atoi(Buffer); + + // モデルNoが最初ではない場合 + if (MotionNo>0) + { + // 前のモデルNoと違う場合 + if (MotionData[ListNo][MotionNo].Model!= + MotionData[ListNo][MotionNo-1].Model) + { + // 同時実行するフレームに加算 + if (++ReadyInitNo==MOTION_MAX) + { + return (D3SKT)elDraw::Error("elSkeleton::LoadObject", + "フレーム数が多過ぎます"); + } + } + } + + // モーション実行情報が初期化状態の場合 + if (MotionReady[ListNo][MotionTopNo-1][ReadyInitNo].Init==-1) + { + // 同時実行するフレームに、モーションNoを割り当て + MotionReady[ListNo][MotionTopNo-1][ReadyInitNo].Init=MotionNo; + } + + // 移動の読み込み + fscanf(_Fpt,"%s",Buffer); + Buffer[0]=' '; + Buffer[1]=' '; + Buffer[2]=' '; + MotionData[ListNo][MotionNo].MoveX=F(atof(Buffer)); + + fscanf(_Fpt,"%s",Buffer); + MotionData[ListNo][MotionNo].MoveY=F(atof(Buffer)); + + fscanf(_Fpt,"%s",Buffer); + MotionData[ListNo][MotionNo].MoveZ=F(atof(Buffer)); + + // 回転の読み込み + fscanf(_Fpt,"%s",Buffer); + Buffer[0]=' '; + Buffer[1]=' '; + Buffer[2]=' '; + MotionData[ListNo][MotionNo].RotateX=F(atof(Buffer)); + + fscanf(_Fpt,"%s",Buffer); + MotionData[ListNo][MotionNo].RotateY=F(atof(Buffer)); + + fscanf(_Fpt,"%s",Buffer); + MotionData[ListNo][MotionNo].RotateZ=F(atof(Buffer)); + + // ジャンプの読み込み + fscanf(_Fpt,"%s",Buffer); + Buffer[0]=' '; + Buffer[1]=' '; + Buffer[2]=' '; + MotionData[ListNo][MotionNo].JumpSpeed=F(atof(Buffer)); + + fscanf(_Fpt,"%s",Buffer); + MotionData[ListNo][MotionNo].JumpSpeedAdd=F(atof(Buffer)); + + // 時間の読み込み + fscanf(_Fpt,"%s",Buffer); + Buffer[0]=' '; + Buffer[1]=' '; + Buffer[2]=' '; + MotionData[ListNo][MotionNo].Time=F(atof(Buffer)); + + if (MotionData[ListNo][MotionNo].Time==F(0)) + { + MotionData[ListNo][MotionNo].Time=F(0.001); + } + + // 攻撃判定と当たり判定の読み込み + fscanf(_Fpt,"%s",Buffer); + + if (Buffer[0]=='Y') + { + MotionData[ListNo][MotionNo].Attack=TRUE; + } + else + { + MotionData[ListNo][MotionNo].Attack=FALSE; + } + + if (Buffer[1]=='Y') + { + MotionData[ListNo][MotionNo].Hit=TRUE; + } + else + { + MotionData[ListNo][MotionNo].Hit=FALSE; + } + } + + fclose(_Fpt); + } + } + + return ListNo; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モーションの設定 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- int MotionNo : モーションNo -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elSkeleton::SetMotion(D3SKT SktD3,int MotionNo) +{ + static int i; + + if (SkeletonData[SktD3][0].LinkModel==-1) + { + return elDraw::Error("elSkeleton::SetMotion", + "スケルトン情報が異常です"); + } + + if (MotionDataNo[SktD3][MotionNo-1]==-1) + { + return elDraw::Error("elSkeleton::SetMotion", + "モーション情報が異常です"); + } + + // モーション実行情報の設定 + MotionReadyNo[SktD3]=MotionNo; + + for (i=0;i0) + { + // 指定距離を超える場合 + if (Work+MotionReady[i][MotionReadyNo[i]-1][j].MoveX> + MotionData[i][StepNo].MoveX) + { + // 加算値の調整 + Work=MotionData[i][StepNo].MoveX- + MotionReady[i][MotionReadyNo[i]-1][j].MoveX; + } + } + else + { + // 指定距離を超える場合 + if (Work+MotionReady[i][MotionReadyNo[i]-1][j].MoveX< + MotionData[i][StepNo].MoveX) + { + // 減算値の調整 + Work=(-MotionData[i][StepNo].MoveX+ + MotionReady[i][MotionReadyNo[i]-1] + [j].MoveX)*-1; + } + } + + // 処理量に加減値を加算 + MotionReady[i][MotionReadyNo[i]-1][j].MoveX+=Work; + + // モデルNo.0の場合、モデル現在位置のX座標に加算 + if (j==0) MotionReadyMove[i].MoveX+=Work; + + // モデルのX方向移動 + el3D::DirectMoveModelX(SkeletonMDL[i][ModelNo],-Work); + } + + // Y方向への移動がある場合 + if (MotionData[i][StepNo].MoveY!=F(0)) + { + // 加減値を小数点以下第三位まで取得 + Work=MotionData[i][StepNo].MoveY/ + MotionData[i][StepNo].Time*FrameTime; + if (TimeFlag) Work=MotionData[i][StepNo].MoveY; + Work=F((int)(Work*F(1000)))/F(1000); + + if (Work>0) + { + // 指定距離を超える場合 + if (Work+MotionReady[i][MotionReadyNo[i]-1][j].MoveY> + MotionData[i][StepNo].MoveY) + { + // 加算値の調整 + Work=MotionData[i][StepNo].MoveY- + MotionReady[i][MotionReadyNo[i]-1][j].MoveY; + } + } + else + { + // 指定距離を超える場合 + if (Work+MotionReady[i][MotionReadyNo[i]-1][j].MoveY< + MotionData[i][StepNo].MoveY) + { + // 減算値の調整 + Work=(-MotionData[i][StepNo].MoveY+ + MotionReady[i][MotionReadyNo[i]-1] + [j].MoveY)*-1; + } + } + + // 処理量に加減値を加算 + MotionReady[i][MotionReadyNo[i]-1][j].MoveY+=Work; + + // モデルNo.0の場合、モデル現在位置のY座標に加算 + if (j==0) MotionReadyMove[i].MoveY+=Work; + + // モデルのY方向移動 + el3D::DirectMoveModelY(SkeletonMDL[i][ModelNo],Work); + } + + // Z方向への移動がある場合 + if (MotionData[i][StepNo].MoveZ!=F(0)) + { + // 加減値を小数点以下第三位まで取得 + Work=MotionData[i][StepNo].MoveZ/ + MotionData[i][StepNo].Time*FrameTime; + if (TimeFlag) Work=MotionData[i][StepNo].MoveZ; + Work=F((int)(Work*F(1000)))/F(1000); + + if (Work>0) + { + // 指定距離を超える場合 + if (Work+MotionReady[i][MotionReadyNo[i]-1][j].MoveZ> + MotionData[i][StepNo].MoveZ) + { + // 加算値の調整 + Work=MotionData[i][StepNo].MoveZ- + MotionReady[i][MotionReadyNo[i]-1][j].MoveZ; + } + } + else + { + // 指定距離を超える場合 + if (Work+MotionReady[i][MotionReadyNo[i]-1][j].MoveZ< + MotionData[i][StepNo].MoveZ) + { + // 減算値の調整 + Work=(-MotionData[i][StepNo].MoveZ+ + MotionReady[i][MotionReadyNo[i]-1] + [j].MoveZ)*-1; + } + } + + // 処理量に加減値を加算 + MotionReady[i][MotionReadyNo[i]-1][j].MoveZ+=Work; + + // モデルNo.0の場合、モデル現在位置のZ座標に加算 + if (j==0) MotionReadyMove[i].MoveZ+=Work; + + // モデルのZ方向移動 + el3D::DirectMoveModelZ(SkeletonMDL[i][ModelNo],Work); + } + + // X方向への回転がある場合 + if (MotionData[i][StepNo].RotateX!=F(0)) + { + // 加減値を小数点以下第三位まで取得 + Work=MotionData[i][StepNo].RotateX/ + MotionData[i][StepNo].Time*FrameTime; + if (TimeFlag) Work=MotionData[i][StepNo].RotateX; + Work=F((int)(Work*F(1000)))/F(1000); + + if (Work>0) + { + // 指定角度を超える場合 + if (Work+MotionReady[i][MotionReadyNo[i]-1] + [j].RotateX> + MotionData[i][StepNo].RotateX) + { + // 加算値の調整 + Work=MotionData[i][StepNo].RotateX- + MotionReady[i][MotionReadyNo[i]-1] + [j].RotateX; + } + } + else + { + // 指定角度を超える場合 + if (Work+MotionReady[i][MotionReadyNo[i]-1] + [j].RotateX< + MotionData[i][StepNo].RotateX) + { + // 減算値の調整 + Work=(-MotionData[i][StepNo].RotateX+ + MotionReady[i][MotionReadyNo[i]-1] + [j].RotateX)*-1; + } + } + + // 処理量に加減値を加算 + MotionReady[i][MotionReadyNo[i]-1][j].RotateX+=Work; + + // モデルNo.0の場合、モデル現在位置のX回転に加算 + if (j==0) MotionReadyMove[i].RotateX+=Work; + + // モデルのX方向回転 + el3D::DirectRotate360ModelX(SkeletonMDL[i][ModelNo],Work); + } + + // Y方向への回転がある場合 + if (MotionData[i][StepNo].RotateY!=F(0)) + { + // 加減値を小数点以下第三位まで取得 + Work=MotionData[i][StepNo].RotateY/ + MotionData[i][StepNo].Time*FrameTime; + if (TimeFlag) Work=MotionData[i][StepNo].RotateY; + Work=F((int)(Work*F(1000)))/F(1000); + + if (Work>0) + { + // 指定角度を超える場合 + if (Work+MotionReady[i][MotionReadyNo[i]-1] + [j].RotateY> + MotionData[i][StepNo].RotateY) + { + // 加算値の調整 + Work=MotionData[i][StepNo].RotateY- + MotionReady[i][MotionReadyNo[i]-1] + [j].RotateY; + } + } + else + { + // 指定角度を超える場合 + if (Work+MotionReady[i][MotionReadyNo[i]-1] + [j].RotateY< + MotionData[i][StepNo].RotateY) + { + // 減算値の調整 + Work=(-MotionData[i][StepNo].RotateY+ + MotionReady[i][MotionReadyNo[i]-1] + [j].RotateY)*-1; + } + } + + // 処理量に加減値を加算 + MotionReady[i][MotionReadyNo[i]-1][j].RotateY+=Work; + + // モデルNo.0の場合、モデル現在位置のY回転に加算 + if (j==0) MotionReadyMove[i].RotateY+=Work; + + // モデルのY方向回転 + el3D::DirectRotate360ModelY(SkeletonMDL[i][ModelNo], + Work); + } + + // Z方向への回転がある場合 + if (MotionData[i][StepNo].RotateZ!=F(0)) + { + // 加減値を小数点以下第三位まで取得 + Work=MotionData[i][StepNo].RotateZ/ + MotionData[i][StepNo].Time*FrameTime; + if (TimeFlag) Work=MotionData[i][StepNo].RotateZ; + Work=F((int)(Work*F(1000)))/F(1000); + + if (Work>0) + { + // 指定角度を超える場合 + if (Work+MotionReady[i][MotionReadyNo[i]-1] + [j].RotateZ> + MotionData[i][StepNo].RotateZ) + { + // 加算値の調整 + Work=MotionData[i][StepNo].RotateZ- + MotionReady[i][MotionReadyNo[i]-1] + [j].RotateZ; + } + } + else + { + // 指定角度を超える場合 + if (Work+MotionReady[i][MotionReadyNo[i]-1] + [j].RotateZ< + MotionData[i][StepNo].RotateZ) + { + // 減算値の調整 + Work=(-MotionData[i][StepNo].RotateZ+ + MotionReady[i][MotionReadyNo[i]-1] + [j].RotateZ)*-1; + } + } + + // 処理量に加減値を加算 + MotionReady[i][MotionReadyNo[i]-1][j].RotateZ+=Work; + + // モデルNo.0の場合、モデル現在位置のZ回転に加算 + if (j==0) MotionReadyMove[i].RotateZ+=Work; + + // モデルのZ方向回転 + el3D::DirectRotate360ModelZ(SkeletonMDL[i][ModelNo],Work); + } + + // ジャンプがある場合 + if (MotionData[i][StepNo].JumpSpeed!=F(0) && + !MotionReady[i][MotionReadyNo[i]-1][j].Jump) + { + elSkeleton::SetJump(i,MotionData[i][StepNo].JumpSpeed, + MotionData[i][StepNo].JumpSpeedAdd); + + MotionReady[i][MotionReadyNo[i]-1][j].Jump=TRUE; + } + + // 攻撃判定がある場合 + if (!MotionReady[i][MotionReadyNo[i]-1][j].Attack && + MotionData[i][StepNo].Attack) + { + for (k=0;k=F(0)) + { + Work=-MotionReadyMove[i].JumpY; + + // ジャンプ終了 + MotionReadyMove[i].Jump=0; + } + + // ジャンプの高さに加減値を加算 + MotionReadyMove[i].JumpY+=Work; + + // モデルのY方向ジャンプ + el3D::DirectMoveModelY(SkeletonMDL[i][0],Work); + } + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モーション状態の取得 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- -*/ +/*- 戻り値 : モーション状態 ( int型 ) -*/ +/* 0 = モーション終了 -*/ +/*- 1以上 = 実行中のモーションNo -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elSkeleton::GetMotion(D3SKT SktD3) +{ + if (MotionReadyNo[SktD3]==-1) + { + return 0; + } + else + { + return MotionReadyNo[SktD3]; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モーション経過時間の取得 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- -*/ +/*- 戻り値 : モーション経過時間 ( float型 ) -*/ +/* 0 = モーション終了 -*/ +/*- 0より大きい = モーション開始からの経過時間 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +float elSkeleton::GetMotionTime(D3SKT SktD3) +{ + if (MotionReadyNo[SktD3]==-1) + { + return F(0); + } + else + { + return MotionReadyMove[SktD3].Time; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- モーション状態の初期化 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- BOOL Flag : TRUE = 全てのモデルを初期化 -*/ +/*- FALSE = モデルNo.0以外を初期化 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSkeleton::InitMotion(D3SKT SktD3,BOOL Mode) +{ + static int i; + static int Start; + + if (Mode) + { + Start=0; + } + else + { + Start=1; + } + + // モーションの停止 + MotionReadyNo[SktD3]=-1; + + MotionReadyMove[SktD3].MoveX=F(0); + MotionReadyMove[SktD3].MoveY=F(0); + MotionReadyMove[SktD3].MoveZ=F(0); + MotionReadyMove[SktD3].RotateX=F(0); + MotionReadyMove[SktD3].RotateY=F(0); + MotionReadyMove[SktD3].RotateZ=F(0); + + for (i=Start;iGetPosition(SkeletonMDL[SktD3B][0],&Pos); + + return F(sqrt(Pos.x*Pos.x+Pos.y*Pos.y+Pos.z*Pos.z)); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 当たり判定の結果取得 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- -*/ +/*- 戻り値 : 当たり判定結果 -*/ +/*- 0〜 = スケルトン情報 ( D3SKT型 ) -*/ +/*- -1 = 当たり判定なし -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D3SKT elSkeleton::Hit(D3SKT SktD3) +{ + if (SkeletonAttack[SktD3].Parts!=-1) + { + return SkeletonAttack[SktD3].HitSkeleton; + } + else + { + return (D3SKT)-1; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 当たり判定の詳細結果取得 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- int* AttackParts : 攻撃判定があるモデルNo ( 戻り値 ) -*/ +/*- int* HitParts : 相手側の当たり判定があるモデルNo ( 戻り値 ) -*/ +/*- -*/ +/*- 戻り値 : 当たり判定結果 -*/ +/*- 0〜 = スケルトン情報 ( D3SKT型 ) -*/ +/*- -1 = 当たり判定なし -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D3SKT elSkeleton::HitModel(D3SKT SktD3,int* AttackParts,int* HitParts) +{ + if (SkeletonAttack[SktD3].Parts!=-1) + { + *AttackParts=SkeletonAttack[SktD3].Parts; + *HitParts=SkeletonAttack[SktD3].HitParts; + + return SkeletonAttack[SktD3].HitSkeleton; + } + else + { + return (D3SKT)-1; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スケルトン内のモデル取得 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- int ModelNo : SKTファイルに記述されたモデルNo -*/ +/*- -*/ +/*- 戻り値 : モデル情報 ( D3OBJ型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +D3OBJ elSkeleton::GetModel(D3SKT SktD3,int ModelNo) +{ + return SkeletonMDL[SktD3][ModelNo]; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スケルトンのX座標取得 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- -*/ +/*- 戻り値 : X座標 ( float型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +float elSkeleton::GetMoveX(D3SKT SktD3) +{ + return MotionReadyMove[SktD3].MoveX; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スケルトンのY座標取得 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- -*/ +/*- 戻り値 : Y座標 ( float型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +float elSkeleton::GetMoveY(D3SKT SktD3) +{ + return MotionReadyMove[SktD3].MoveY; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スケルトンのZ座標取得 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- -*/ +/*- 戻り値 : Z座標 ( float型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +float elSkeleton::GetMoveZ(D3SKT SktD3) +{ + return MotionReadyMove[SktD3].MoveZ; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スケルトンの座標取得 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- float* Px : X座標 ( 戻り値 ) -*/ +/*- float* Py : Y座標 ( 戻り値 ) -*/ +/*- float* Pz : Z座標 ( 戻り値 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSkeleton::GetMove(D3SKT SktD3,float* Px,float* Py,float* Pz) +{ + *Px=MotionReadyMove[SktD3].MoveX; + *Py=MotionReadyMove[SktD3].MoveY; + *Pz=MotionReadyMove[SktD3].MoveZ; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スケルトンのX回転取得 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- -*/ +/*- 戻り値 : X回転 ( float型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +float elSkeleton::GetRotateX(D3SKT SktD3) +{ + return MotionReadyMove[SktD3].RotateX; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スケルトンのY回転取得 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- -*/ +/*- 戻り値 : Y回転 ( float型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +float elSkeleton::GetRotateY(D3SKT SktD3) +{ + return MotionReadyMove[SktD3].RotateY; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スケルトンのZ回転取得 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- -*/ +/*- 戻り値 : Z回転 ( float型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +float elSkeleton::GetRotateZ(D3SKT SktD3) +{ + return MotionReadyMove[SktD3].RotateZ; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スケルトンの回転取得 -*/ +/*- -*/ +/*- D3SKT SktD3 : スケルトン情報 -*/ +/*- float* Px : X回転 ( 戻り値 ) -*/ +/*- float* Py : Y回転 ( 戻り値 ) -*/ +/*- float* Pz : Z回転 ( 戻り値 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSkeleton::GetRotate(D3SKT SktD3,float* Px,float* Py,float* Pz) +{ + *Px=MotionReadyMove[SktD3].RotateX; + *Py=MotionReadyMove[SktD3].RotateY; + *Pz=MotionReadyMove[SktD3].RotateZ; +} + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= ジョイスティッククラス定義 ( elJoystick ) =*/ +/*= =*/ +/*==============================================================================*/ + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ジョイスティッククラスの初期化 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elJoystick::Init(void) +{ + int i,j; + + joyConfigChanged(0); + + elJoystick::InitCenter(); + + for (i=0;i<2;i++) + { + Analog[i].X=F(0); + Analog[i].Y=F(0); + Analog[i].DefAddXY=F(0); + + for (j=0;j<4;j++) + { + Analog[i].B[j]=F(0); + Analog[i].InfoB[j]=FREE_BUTTON; + } + + Analog[i].DefAddB=F(0); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スティックの中央位置の初期化 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elJoystick::InitCenter(void) +{ + JoyInfo.dwSize=sizeof(JOYINFOEX); + JoyInfo.dwFlags=JOY_RETURNALL|JOY_USEDEADZONE; + + if (joyGetPosEx(JOY1,&JoyInfo)==JOYERR_NOERROR) + { + CenterX[JOY1]=JoyInfo.dwXpos; + CenterY[JOY1]=JoyInfo.dwYpos; + } + else + { + CenterX[JOY1]=0; + CenterY[JOY1]=0; + } + + if (joyGetPosEx(JOY2,&JoyInfo)==JOYERR_NOERROR) + { + CenterX[JOY2]=JoyInfo.dwXpos; + CenterY[JOY2]=JoyInfo.dwYpos; + } + else + { + CenterX[JOY2]=0; + CenterY[JOY2]=0; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- アナログデータの初期化 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elJoystick::InitAnalog(void) +{ + int i,j; + + for (i=0;i<2;i++) + { + Analog[i].X=F(0); + Analog[i].Y=F(0); + + for (j=0;j<4;j++) + { + Analog[i].B[j]=F(0); + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- アナログデータの感度の設定 -*/ +/*- -*/ +/*- int JoystickNo : ジョイスティックNo ( JOY1 か JOY2 ) -*/ +/*- float Stick : スティックの速度 -*/ +/*- float Button : ボタンの速度 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elJoystick::SetAnalog(int JoystickNo,float Stick,float Button) +{ + Analog[JoystickNo].DefAddXY=Stick; + Analog[JoystickNo].DefAddB=Button; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スティックの中央位置を数値で取得 -*/ +/*- -*/ +/*- int JoystickNo : ジョイスティックNo ( JOY1 か JOY2 ) -*/ +/*- int* PosX : X方向 ( 戻り値 ) -*/ +/*- int* PosY : Y方向 ( 戻り値 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elJoystick::CenterPos(int JoystickNo,int* PosX,int* PosY) +{ + *PosX=CenterX[JoystickNo]; + *PosY=CenterY[JoystickNo]; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 個々のボタン状態の取得 -*/ +/*- -*/ +/*- int JoystickNo : ジョイスティックNo ( JOY1 か JOY2 ) -*/ +/*- int ButtonNo : ボタンNo ( BUTTON1 から BUTTON4 ) -*/ +/*- -*/ +/*- 戻り値 : TRUE = 押されている状態 -*/ +/*- FALSE = 押されていない状態 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elJoystick::Button(int JoystickNo,int ButtonNo) +{ + JoyInfo.dwSize=sizeof(JOYINFOEX); + JoyInfo.dwFlags=JOY_RETURNBUTTONS; + + if (joyGetPosEx(JoystickNo,&JoyInfo)==JOYERR_NOERROR) + { + if ((JoyInfo.dwButtons>>(ButtonNo-1))&0x01==0x01) + { + return TRUE; + } + else + { + return FALSE; + } + } + + return FALSE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 個々のボタン状態の詳細情報を取得 -*/ +/*- -*/ +/*- int JoystickNo : ジョイスティックNo ( JOY1 か JOY2 ) -*/ +/*- int ButtonNo : ボタンNo ( BUTTON1 から BUTTON4 ) -*/ +/*- -*/ +/*- 戻り値 : ボタン状態 ( int型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elJoystick::ButtonInfo(int JoystickNo,int ButtonNo) +{ + static int Flag; + + JoyInfo.dwSize=sizeof(JOYINFOEX); + JoyInfo.dwFlags=JOY_RETURNBUTTONS; + + if (joyGetPosEx(JoystickNo,&JoyInfo)==JOYERR_NOERROR) + { + Flag=Analog[JoystickNo].InfoB[ButtonNo-1]; + + if ((JoyInfo.dwButtons>>(ButtonNo-1))&0x01==0x01) + { + if (Flag==FREE_BUTTON) + { + Flag=PUSH_BUTTON; + } + else + { + Flag=HOLD_BUTTON; + } + } + else + { + if (Flag==PUSH_BUTTON || Flag==HOLD_BUTTON) + { + Flag=PULL_BUTTON; + } + else + { + Flag=FREE_BUTTON; + } + } + + if (elDraw::FadeNo || elDraw::HelpOn || elSystem::KeyboardLock) + { + Flag=FREE_BUTTON; + } + + Analog[JoystickNo].InfoB[ButtonNo-1]=Flag; + + return Flag; + } + + return FREE_BUTTON; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 全てのボタン状態の取得 -*/ +/*- -*/ +/*- int JoystickNo : ジョイスティックNo ( JOY1 か JOY2 ) -*/ +/*- -*/ +/*- int* B1 : ボタン1の状態 ( 戻り値 ) -*/ +/*- int* B2 : ボタン2の状態 ( 戻り値 ) -*/ +/*- int* B3 : ボタン3の状態 ( 戻り値 ) -*/ +/*- int* B4 : ボタン4の状態 ( 戻り値 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// ボタン情報の無効化 ( 不要なボタン情報がある場合に指定 ) +#define NO_BUTTON &_BufferButton + +static int _BufferButton; + +void elJoystick::Buttons(int JoystickNo,int* B1,int* B2,int* B3,int* B4) +{ + JoyInfo.dwSize=sizeof(JOYINFOEX); + JoyInfo.dwFlags=JOY_RETURNBUTTONS; + + if (joyGetPosEx(JoystickNo,&JoyInfo)==JOYERR_NOERROR) + { + *B1=JoyInfo.dwButtons&0x01; + *B2=(JoyInfo.dwButtons>>1)&0x01; + *B3=(JoyInfo.dwButtons>>2)&0x01; + *B4=(JoyInfo.dwButtons>>3)&0x01; + } + else + { + *B1=NULL; + *B2=NULL; + *B3=NULL; + *B4=NULL; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 全てのボタン状態の詳細情報を取得 -*/ +/*- -*/ +/*- int JoystickNo : ジョイスティックNo ( JOY1 か JOY2 ) -*/ +/*- -*/ +/*- int* B1 : ボタン1の状態 ( 戻り値 ) -*/ +/*- int* B2 : ボタン2の状態 ( 戻り値 ) -*/ +/*- int* B3 : ボタン3の状態 ( 戻り値 ) -*/ +/*- int* B4 : ボタン4の状態 ( 戻り値 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elJoystick::ButtonsInfo(int JoystickNo,int* B1,int* B2,int* B3,int* B4) +{ + static int Flag; + static int i; + + JoyInfo.dwSize=sizeof(JOYINFOEX); + JoyInfo.dwFlags=JOY_RETURNBUTTONS; + + if (joyGetPosEx(JoystickNo,&JoyInfo)==JOYERR_NOERROR) + { + for (i=0;i<4;i++) + { + Flag=Analog[JoystickNo].InfoB[i]; + + if ((JoyInfo.dwButtons>>i)&0x01) + { + if (Flag==FREE_BUTTON) + { + Flag=PUSH_BUTTON; + } + else + { + Flag=HOLD_BUTTON; + } + } + else + { + if (Flag==PUSH_BUTTON || Flag==HOLD_BUTTON) + { + Flag=PULL_BUTTON; + } + else + { + Flag=FREE_BUTTON; + } + } + + if (elDraw::FadeNo || elDraw::HelpOn || elSystem::KeyboardLock) + { + Flag=FREE_BUTTON; + } + + Analog[JoystickNo].InfoB[i]=Flag; + + switch (i) + { + case 0: *B1=Flag; break; + case 1: *B2=Flag; break; + case 2: *B3=Flag; break; + case 3: *B4=Flag; break; + } + } + } + else + { + *B1=NULL; + *B2=NULL; + *B3=NULL; + *B4=NULL; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 個々のボタン状態をアナログデータとして取得 -*/ +/*- -*/ +/*- int JoystickNo : ジョイスティックNo ( JOY1 か JOY2 ) -*/ +/*- int ButtonNo : ボタンNo ( BUTTON1 から BUTTON4 ) -*/ +/*- -*/ +/*- 戻り値 : アナログデータ ( int型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elJoystick::AnalogButton(int JoystickNo,int ButtonNo) +{ + if (elJoystick::Button(JoystickNo,ButtonNo)) + { + Analog[JoystickNo].B[ButtonNo-1]+=Analog[JoystickNo].DefAddB*FrameTime; + + if (Analog[JoystickNo].B[ButtonNo-1]>=F(100)) + { + Analog[JoystickNo].B[ButtonNo-1]=F(100); + } + } + else + { + Analog[JoystickNo].B[ButtonNo-1]=F(0); + } + + return (int)Analog[JoystickNo].B[ButtonNo-1]; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 全てのボタン状態をアナログデータとして取得 -*/ +/*- -*/ +/*- int JoystickNo : ジョイスティックNo ( JOY1 か JOY2 ) -*/ +/*- -*/ +/*- int* B1 : ボタン1のアナログデータ ( 戻り値 ) -*/ +/*- int* B2 : ボタン2のアナログデータ ( 戻り値 ) -*/ +/*- int* B3 : ボタン3のアナログデータ ( 戻り値 ) -*/ +/*- int* B4 : ボタン4のアナログデータ ( 戻り値 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elJoystick::AnalogButtons(int JoystickNo,int* B1,int* B2,int* B3,int* B4) +{ + static int i; + + JoyInfo.dwSize=sizeof(JOYINFOEX); + JoyInfo.dwFlags=JOY_RETURNBUTTONS; + + if (joyGetPosEx(JoystickNo,&JoyInfo)==JOYERR_NOERROR) + { + for (i=0;i<4;i++) + { + if ((JoyInfo.dwButtons>>i)&0x01) + { + Analog[JoystickNo].B[i]+=Analog[JoystickNo].DefAddB*FrameTime; + + if (Analog[JoystickNo].B[i]>=F(100)) + { + Analog[JoystickNo].B[i]=F(100); + } + } + else + { + Analog[JoystickNo].B[i]=F(0); + } + + switch (i) + { + case 0: *B1=(int)Analog[JoystickNo].B[i]; break; + case 1: *B2=(int)Analog[JoystickNo].B[i]; break; + case 2: *B3=(int)Analog[JoystickNo].B[i]; break; + case 3: *B4=(int)Analog[JoystickNo].B[i]; break; + } + } + } + else + { + *B1=NULL; + *B2=NULL; + *B3=NULL; + *B4=NULL; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スティック状態の取得 -*/ +/*- -*/ +/*- int JoystickNo : ジョイスティックNo ( JOY1 か JOY2 ) -*/ +/*- int* PosX : X方向 ( 戻り値 ) -*/ +/*- -1 = 左 -*/ +/*- 0 = 中央 -*/ +/*- 1 = 右 -*/ +/*- int* PosY : Y方向 ( 戻り値 ) -*/ +/*- -1 = 上 -*/ +/*- 0 = 中央 -*/ +/*- 1 = 下 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elJoystick::Stick(int JoystickNo,int* PosX,int* PosY) +{ + static int GetX,GetY; + + JoyInfo.dwSize=sizeof(JOYINFOEX); + JoyInfo.dwFlags=JOY_RETURNX|JOY_RETURNY|JOY_USEDEADZONE; + + if (joyGetPosEx(JoystickNo,&JoyInfo)==JOYERR_NOERROR) + { + GetX=JoyInfo.dwXpos; + GetY=JoyInfo.dwYpos; + + *PosX=0; + *PosY=0; + + if (GetX<=CenterX[JoystickNo]/2) + { + *PosX=-1; + } + else + { + if (GetX>=CenterX[JoystickNo]+CenterX[JoystickNo]/2) + { + *PosX=1; + } + } + + if (GetY<=CenterY[JoystickNo]/2) + { + *PosY=-1; + } + else + { + if (GetY>=CenterY[JoystickNo]+CenterY[JoystickNo]/2) + { + *PosY=1; + } + } + } + else + { + *PosX=0; + *PosY=0; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スティック状態をテンキー方向として取得 -*/ +/*- -*/ +/*- int JoystickNo : ジョイスティックNo ( JOY1 か JOY2 ) -*/ +/*- -*/ +/*- 戻り値 : 押されている方向 ( テンキーの値と同様 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elJoystick::StickTenkey(int JoystickNo) +{ + static int GetX,GetY; + static int GetPos; + + GetPos=5; + + JoyInfo.dwSize=sizeof(JOYINFOEX); + JoyInfo.dwFlags=JOY_RETURNX|JOY_RETURNY|JOY_USEDEADZONE; + + if (joyGetPosEx(JoystickNo,&JoyInfo)==JOYERR_NOERROR) + { + GetX=JoyInfo.dwXpos; + GetY=JoyInfo.dwYpos; + + if (GetX<=CenterX[JoystickNo]/2) + { + if (GetY<=CenterY[JoystickNo]/2) + { + GetPos=7; + } + else + { + if (GetY>=CenterY[JoystickNo]+CenterY[JoystickNo]/2) + { + GetPos=1; + } + else + { + GetPos=4; + } + } + } + else + { + if (GetX>=CenterX[JoystickNo]+CenterX[JoystickNo]/2) + { + if (GetY<=CenterY[JoystickNo]/2) + { + GetPos=9; + } + else + { + if (GetY>=CenterY[JoystickNo]+CenterY[JoystickNo]/2) + { + GetPos=3; + } + else + { + GetPos=6; + } + } + } + else + { + if (GetY<=CenterY[JoystickNo]/2) + { + GetPos=8; + } + else + { + if (GetY>=CenterY[JoystickNo]+CenterY[JoystickNo]/2) + { + GetPos=2; + } + } + } + } + } + + return GetPos; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スティックの現在位置を数値で取得 -*/ +/*- -*/ +/*- int JoystickNo : ジョイスティックNo ( JOY1 か JOY2 ) -*/ +/*- int* PosX : X方向 ( 戻り値 ) -*/ +/*- int* PosY : Y方向 ( 戻り値 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elJoystick::StickPos(int JoystickNo,int* PosX,int* PosY) +{ + JoyInfo.dwSize=sizeof(JOYINFOEX); + JoyInfo.dwFlags=JOY_RETURNX|JOY_RETURNY|JOY_USEDEADZONE; + + if (joyGetPosEx(JoystickNo,&JoyInfo)==JOYERR_NOERROR) + { + *PosX=JoyInfo.dwXpos; + *PosY=JoyInfo.dwYpos; + } + else + { + *PosX=0; + *PosY=0; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スティック状態をアナログデータとして取得 -*/ +/*- -*/ +/*- int JoystickNo : ジョイスティックNo ( JOY1 か JOY2 ) -*/ +/*- int* PosX : X方向のアナログデータ ( 戻り値 ) -*/ +/*- int* PosY : Y方向のアナログデータ ( 戻り値 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elJoystick::AnalogStick(int JoystickNo,int* PosX,int* PosY) +{ + static int GetX,GetY; + static int DataX,DataY; + + JoyInfo.dwSize=sizeof(JOYINFOEX); + JoyInfo.dwFlags=JOY_RETURNX|JOY_RETURNY|JOY_USEDEADZONE; + + if (joyGetPosEx(JoystickNo,&JoyInfo)==JOYERR_NOERROR) + { + GetX=JoyInfo.dwXpos; + GetY=JoyInfo.dwYpos; + + DataX=0; + DataY=0; + + if (GetX<=CenterX[JoystickNo]/2) + { + DataX=-1; + } + else + { + if (GetX>=CenterX[JoystickNo]+CenterX[JoystickNo]/2) + { + DataX=1; + } + } + + if (GetY<=CenterY[JoystickNo]/2) + { + DataY=-1; + } + else + { + if (GetY>=CenterY[JoystickNo]+CenterY[JoystickNo]/2) + { + DataY=1; + } + } + + if (DataX) + { + Analog[JoystickNo].X+=Analog[JoystickNo].DefAddXY*DataX*FrameTime; + + if (Analog[JoystickNo].X>=F(100)) + { + Analog[JoystickNo].X=F(100); + } + + if (Analog[JoystickNo].X<=F(-100)) + { + Analog[JoystickNo].X=F(-100); + } + } + else + { + if (Analog[JoystickNo].X>F(0)) + { + Analog[JoystickNo].X-=Analog[JoystickNo].DefAddXY*FrameTime; + + if (Analog[JoystickNo].XF(0)) Analog[JoystickNo].X=F(0); + } + } + + if (DataY) + { + Analog[JoystickNo].Y+=Analog[JoystickNo].DefAddXY*DataY*FrameTime; + + if (Analog[JoystickNo].Y>=F(100)) + { + Analog[JoystickNo].Y=F(100); + } + + if (Analog[JoystickNo].Y<=F(-100)) + { + Analog[JoystickNo].Y=F(-100); + } + } + else + { + if (Analog[JoystickNo].Y>F(0)) + { + Analog[JoystickNo].Y-=Analog[JoystickNo].DefAddXY*FrameTime; + + if (Analog[JoystickNo].YF(0)) Analog[JoystickNo].Y=F(0); + } + } + + *PosX=(int)Analog[JoystickNo].X; + *PosY=(int)Analog[JoystickNo].Y; + } + else + { + *PosX=0; + *PosY=0; + } +} + +/*==============================================================================*/ +/*= =*/ +/*= ネットワーククラス定義 ( elNetwork ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef DIRECTPLAY + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ネットワーククラスの初期化 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elNetwork::Init(void) +{ + int i; + + for (i=0;i=0) + { + // ネットワークへの接続 + if (!elNetwork::Enter(NetNo)) UNLOCK_EXIT(ERROR_NET); + + // ゲーム選択モードへ切り替え + ReadyMode=2; + } + + // 「取り消し」が選択された場合 + if (NetNo==-2) UNLOCK_EXIT(ESCAPE_NET); + } + + // ゲーム接続モードの場合 + if (ReadyMode==2) + { + // 接続モードの選択 + ModeNo=elNetwork::SelectMode(); + + if (ModeNo==1) + { + // ゲームの作成 + if (!CreateGame()) UNLOCK_EXIT(ERROR_NET); + + // プレイヤーの作成 + if (!CreatePlayer()) UNLOCK_EXIT(ERROR_NET); + + // 相手プレイヤー接続待機モードへ切り替え + ReadyMode=4; + } + + if (ModeNo==2) + { + // ゲームの一覧 + if (!ListGame()) UNLOCK_EXIT(ERROR_NET); + + // ゲーム選択モードへ切り替え + ReadyMode=3; + } + + // 「取り消し」が選択された場合 + if (ModeNo==-2) + { + SelectPos1=0; + SelectPos2=0; + SelectPos3=0; + + // ネットワークからの脱出 + elNetwork::Exit(); + + ReadyMode=1; + } + } + + // ゲーム選択モードの場合 + if (ReadyMode==3) + { + // ゲームの選択 + GameNo=elNetwork::SelectGame(); + + if (GameNo>=0) + { + // ゲームの呼び出し + if (!CallGame(GameNo)) UNLOCK_EXIT(ERROR_NET); + + // プレイヤーの作成 + if (!CreatePlayer()) UNLOCK_EXIT(ERROR_NET); + + // キーボードのロックの解除 + elSystem::UnlockKey(); + + // 参加側なのでゲームマスターをOFF + GameMaster=FALSE; + + // 参加側なのでプレイヤー脱出フラグをOFF + PlayerOut=FALSE; + + // メンバー変数に退避 + ReadyReturn=READY_NET; + + return READY_NET; + } + + // 「取り消し」が選択された場合 + if (GameNo==-2) + { + SelectPos1=0; + SelectPos2=0; + SelectPos3=0; + + ReadyMode=2; + } + } + + // 相手プレイヤー接続待機モードの場合 + if (ReadyMode==4) + { + // 相手プレイヤーの接続待機 + PlayerNo=elNetwork::ReceivePlayer(); + + if (PlayerNo>=0) + { + // キーボードのロックの解除 + elSystem::UnlockKey(); + + // 作成側なのでゲームマスターをON + GameMaster=TRUE; + + // メンバー変数に退避 + ReadyReturn=READY_NET; + + return READY_NET; + } + + // 「取り消し」が選択された場合 + if (PlayerNo==-2) + { + SelectPos1=0; + SelectPos2=0; + SelectPos3=0; + + // ネットワークからの脱出 + elNetwork::Exit(); + + ReadyMode=1; + } + } + + // メニュー側でリフレッシュ処理 + if (DrawFlag) elDraw::Refresh(); + + // メンバー変数に退避 + ReadyReturn=SELECT_NET; + + return SELECT_NET; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ネットワーク接続手続きの再実行 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elNetwork::Retry(void) +{ + ReadyMode=1; + + SelectPos1=0; + SelectPos2=0; + SelectPos3=0; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 接続時と検索時のエラー表示フラグ -*/ +/*- -*/ +/*- 戻り値 : TRUE = エラー表示あり -*/ +/*- FALSE = エラー表示なし -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elNetwork::ErrorShow(BOOL Flag) +{ + ErrorShowFlag=Flag; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- メニュー処理時のクリアーとリフレッシュ -*/ +/*- -*/ +/*- 戻り値 : TRUE = 全てメニュー側で処理 -*/ +/*- FALSE = ユーザー側で処理 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elNetwork::Draw(BOOL Flag) +{ + DrawFlag=Flag; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ネットワークへの接続 ※ 内部で使用 -*/ +/*- -*/ +/*- int No : プロトコルNo -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elNetwork::Enter(int No) +{ + HRESULT dpret; + LPDIRECTPLAY dp=NULL; + + if (!NetOn) + { + if ((dpret=DirectPlayCreate(Service[No].Guid,&dp,NULL))==DP_OK) + { + if (dp) + { + dpret=IDirectPlay_QueryInterface(dp,IID_IDirectPlay2A, + (LPVOID*)&DPObject); + + IDirectPlay_Release(dp); + } + } + + if (dp==NULL) + { + if (ErrorShowFlag) + { + return elDraw::Error("elNetwork::Enter", + "DirectPlayが使用できません"); + } + else + { + return FALSE; + } + } + + NetOn=TRUE; + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ネットワークからの脱出 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elNetwork::Exit(void) +{ + char Buffer[NETMSG_SIZE2]; + + if (DPObject!=NULL) + { + // 相手プレイヤーが存在する場合 + if (!PlayerOut) + { + // ネットワーク脱出用にメッセージリスト保存 + MessageList[0].No=++SendNo; + MessageList[0].Type=1L; + MessageList[0].Message[0]=NULL; + + // 送信用に変換 + memcpy(Buffer,&MessageList[0],sizeof(MessageList[0])); + + // メッセージ送信 + DPObject->Send(PlayerID,DPID_ALLPLAYERS,0,Buffer,sizeof(Buffer)); + } + + // 終了処理 + DPObject->Close(); + DPObject->Release(); + DPObject=NULL; + + NetOn=FALSE; + PlayerOut=TRUE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- サービスの検索 ※ 内部で使用 -*/ +/*- -*/ +/*- パラメーター省略 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +CLBKB elNetwork::SearchService(LPGUID Guid,LPTSTR ServiceName,DWORD Version1, + DWORD Version2,LPVOID None) +{ + int i,j; + int No; + char Buffer[10]; + + No=-1; + + for (i=0;i60) j=60; + + for (i=0;ilpszSessionNameA); + if (j>30) j=30; + + for (i=0;ilpszSessionNameA[i]; + } + + Game[No].Name[i]=NULL; + + Game[No].Guid=Session->guidInstance; + + GameNo=No+1; + + return TRUE; + } + else + { + return FALSE; + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ゲームの作成 ※ 内部で使用 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elNetwork::CreateGame(void) +{ + static DPSESSIONDESC2 session; + + memset(&session,0x00,sizeof(DPSESSIONDESC2)); + session.dwSize=sizeof(DPSESSIONDESC2); + session.dwFlags=DPSESSION_MIGRATEHOST|DPSESSION_KEEPALIVE; + session.guidApplication=_ApplicationGuid; + session.dwMaxPlayers=2; + session.lpszSessionNameA="Network Game"; + + if (DPObject->Open(&session,DPOPEN_CREATE)!=DP_OK) + { + if (ErrorShowFlag) + { + return elDraw::Error("elNetwork::CreateGame", + "ゲームを作成できません"); + } + else + { + return FALSE; + } + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 稼動中ゲームの一覧 ※ 内部で使用 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elNetwork::ListGame(void) +{ + static DPSESSIONDESC2 session; + + memset(&session,0x00,sizeof(DPSESSIONDESC2)); + session.dwSize=sizeof(DPSESSIONDESC2); + session.guidApplication=_ApplicationGuid; + + if (DPObject->EnumSessions(&session,0,SearchGame,hwnd, + DPENUMSESSIONS_AVAILABLE)!=DP_OK) + { + if (ErrorShowFlag) + { + return elDraw::Error("elNetwork::ListGame", + "ゲームを検索できません"); + } + else + { + return FALSE; + } + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ゲームの呼び出し ※ 内部で使用 -*/ +/*- -*/ +/*- int GameNo : リスト内のゲームNo -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elNetwork::CallGame(int GameNo) +{ + static DPSESSIONDESC2 session; + + memset(&session,0x00,sizeof(DPSESSIONDESC2)); + session.dwSize=sizeof(DPSESSIONDESC2); + session.guidApplication=_ApplicationGuid; + session.guidInstance=Game[GameNo].Guid; + + if (DPObject->Open(&session,DPOPEN_JOIN)!=DP_OK) + { + if (ErrorShowFlag) + { + return elDraw::Error("elNetwork::CallGame", + "ゲームに接続できません"); + } + else + { + return FALSE; + } + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- プレイヤーの作成 ※ 内部で使用 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elNetwork::CreatePlayer(void) +{ + static DPNAME name; + + memset(&name,0x00,sizeof(DPNAME)); + name.dwSize=sizeof(DPNAME); + name.lpszShortNameA="Network Game User"; + name.lpszLongNameA=NULL; + + if (DPObject->CreatePlayer(&PlayerID,&name,NULL,NULL,0,0)!=DP_OK) + { + if (ErrorShowFlag) + { + return elDraw::Error("elNetwork::CreatePlayer", + "プレイヤーを作成できません"); + } + else + { + return FALSE; + } + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- サービスの選択 ※ 内部で使用 -*/ +/*- -*/ +/*- 戻り値 : 0〜 = 選択されたサービスNo -*/ +/*- -1 = 選択中 -*/ +/*- -2 = 取り消し -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elNetwork::SelectService(void) +{ + static int i; + static LOGBRUSH LogBrush; + static HBRUSH NowBrush,OldBrush; + static HPEN NowPen,OldPen; + static int KeyEnter,KeyEscape,KeyUp,KeyDown,KeyClick; + static int RetFlag; + static BOOL MouseOn; + + // メニュー表示中 + MenuOn=TRUE; + + // 最後に「取り消し」を追加 + if (Service[ServiceNo].Name[0]==NULL) + { + strcpy(Service[ServiceNo].Name,"取り消し"); + } + + // メニューの描画 + elFont::Begin(GOTHIC,12,0,FALSE,FALSE,FALSE); + + LogBrush.lbStyle=BS_HATCHED; + LogBrush.lbColor=RGB(0,0,80); + LogBrush.lbHatch=HS_DIAGCROSS; + + NowBrush=CreateBrushIndirect(&LogBrush); + OldBrush=(HBRUSH)SelectObject(elFont::FontDC,NowBrush); + + NowPen=CreatePen(PS_SOLID,1,RGB(0,96,192)); + OldPen=(HPEN)SelectObject(elFont::FontDC,NowPen); + + for (i=0;i=(elDraw::Width-400)/2 && + MousePX<=(elDraw::Width-400)/2+400 && + MousePY>=(elDraw::Height-(ServiceNo+1)*20)/2 && + MousePY<=(elDraw::Height-(ServiceNo+1)*20)/2+i*20+12+3+3) + { + SelectPos1=i; + + MouseOn=TRUE; + + break; + } + } + } + + // キーボード&マウス状態の取得 + elSystem::UnlockKey(); + + elSystem::GetKey(VK_RETURN,&KeyEnter); + elSystem::GetKey(VK_ESCAPE,&KeyEscape); + elSystem::GetKey(VK_UP,&KeyUp); + elSystem::GetKey(VK_DOWN,&KeyDown); + elSystem::GetKey(VK_LBUTTON,&KeyClick); + + elSystem::LockKey(); + + // [↑] : カーソルの上移動 + if (KeyUp==PULL_KEY && SelectPos1>0) + { + SelectPos1--; + } + + // [↓] : カーソルの下移動 + if (KeyDown==PULL_KEY && SelectPos1=(elDraw::Width-400)/2 && + MousePX<=(elDraw::Width-400)/2+400 && + MousePY>=(elDraw::Height-(GameNo+1)*20)/2 && + MousePY<=(elDraw::Height-(GameNo+1)*20)/2+i*20+12+3+3) + { + SelectPos2=i; + + MouseOn=TRUE; + + break; + } + } + } + + // キーボード&マウス状態の取得 + elSystem::UnlockKey(); + + elSystem::GetKey(VK_RETURN,&KeyEnter); + elSystem::GetKey(VK_ESCAPE,&KeyEscape); + elSystem::GetKey(VK_UP,&KeyUp); + elSystem::GetKey(VK_DOWN,&KeyDown); + elSystem::GetKey(VK_LBUTTON,&KeyClick); + + elSystem::LockKey(); + + // [↑] : カーソルの上移動 + if (KeyUp==PULL_KEY && SelectPos2>0) + { + SelectPos2--; + } + + // [↓] : カーソルの下移動 + if (KeyDown==PULL_KEY && SelectPos2=(elDraw::Width-400)/2 && + MousePX<=(elDraw::Width-400)/2+400 && + MousePY>=(elDraw::Height-(2+1)*20)/2 && + MousePY<=(elDraw::Height-(2+1)*20)/2+i*20+12+3+3) + { + SelectPos3=i; + + MouseOn=TRUE; + + break; + } + } + } + + // キーボード&マウス状態の取得 + elSystem::UnlockKey(); + + elSystem::GetKey(VK_RETURN,&KeyEnter); + elSystem::GetKey(VK_ESCAPE,&KeyEscape); + elSystem::GetKey(VK_UP,&KeyUp); + elSystem::GetKey(VK_DOWN,&KeyDown); + elSystem::GetKey(VK_LBUTTON,&KeyClick); + + elSystem::LockKey(); + + // [↑] : カーソルの上移動 + if (KeyUp==PULL_KEY && SelectPos3>0) + { + SelectPos3--; + } + + // [↓] : カーソルの下移動 + if (KeyDown==PULL_KEY && SelectPos3<2) + { + SelectPos3++; + } + + // [ENTER].[左クリック] : 決定 + if (KeyEnter==PULL_KEY || KeyClick==PULL_KEY && MouseOn) + { + if (SelectPos3==2) + { + RetFlag=-2; + } + else + { + GameNo=0; + + for (i=0;iFlipToGDISurface(); + } + + elSystem::WaitTime[WAIT_MAX-1]=999999999UL; + + return RetFlag; + } + + return -1; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 未接続プレイヤーからの接続メッセージ待ち ※ 内部で使用 -*/ +/*- -*/ +/*- 戻り値 : 0 = プレイヤー接続完了 -*/ +/*- -1 = 待機中 -*/ +/*- -2 = 取り消し -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elNetwork::ReceivePlayer(void) +{ + static int i; + static LOGBRUSH LogBrush; + static HBRUSH NowBrush,OldBrush; + static HPEN NowPen,OldPen; + static int KeyEscape; + static int RetFlag; + + static char Menu[]="相手プレイヤーの接続を待っています ( ESC : 取り消し )"; + + // メニュー表示中 + MenuOn=TRUE; + + // メニューの描画 + elFont::Begin(GOTHIC,12,0,FALSE,FALSE,FALSE); + + LogBrush.lbStyle=BS_HATCHED; + LogBrush.lbColor=RGB(116,56,0); + LogBrush.lbHatch=HS_DIAGCROSS; + + NowBrush=CreateBrushIndirect(&LogBrush); + OldBrush=(HBRUSH)SelectObject(elFont::FontDC,NowBrush); + + NowPen=CreatePen(PS_SOLID,1,RGB(96,128,0)); + OldPen=(HPEN)SelectObject(elFont::FontDC,NowPen); + + SetBkColor(elFont::FontDC,RGB(128,64,0)); + SetBkMode(elFont::FontDC,OPAQUE); + + RoundRect(elFont::FontDC,(elDraw::Width-400)/2, + (elDraw::Height-20)/2, + (elDraw::Width-400)/2+400, + (elDraw::Height-20)/2+12+3+3,7,7); + + if (Blink) + { + elFont::Color(RGB(255,255,64),0,TRUE); + + elFont::Draw((elDraw::Width-400)/2+10, + (elDraw::Height-20)/2+3,Menu); + } + + SelectObject(elFont::FontDC,OldPen); + DeleteObject(NowPen); + + SelectObject(elFont::FontDC,OldBrush); + DeleteObject(NowBrush); + + elFont::Before(); + + if (timeGetTime()Receive(&SendID,&ReceiveID,DPRECEIVE_ALL,Buffer,&DataSize)!= + DP_OK) + { + return FALSE; + } + + if (SendID==DPID_SYSMSG) + { + if (((LPDPMSG_GENERIC)(Buffer))->dwType==DPSYS_CREATEPLAYERORGROUP) + { + PlayerOut=FALSE; + + return TRUE; + } + } + + return FALSE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 自動メッセージ再送受信機能のON/OFF -*/ +/*- -*/ +/*- BOOL Flag : TRUE = 自動メッセージ再送受信あり -*/ +/*- FALSE = 通常のメッセージのみ     -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elNetwork::AutoRetry(BOOL Flag) +{ + MessageAutoRetry=Flag; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- bpsの描画 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elNetwork::ShowBPS(void) +{ + static char Buffer[256],Format[256]; + + if (timeGetTime()>=BpsTime) + { + BpsData=F(BpsCnt)/F(3); + if (BpsData>BpsDataMax) BpsDataMax=BpsData; + + BpsTime=timeGetTime()+3000L; + BpsCnt=0L; + } + + if (BpsCnt>999999L) BpsCnt=999999L; + + strcpy(Format,"%8.1f/%5d bps ( max %8.1f/%5d ) "); + strcat(Format,"( error send %d / receive %d ) : "); + + if (NetOn) + { + strcat(Format,"接続"); + } + else + { + strcat(Format,"未接続"); + } + + if (GameMaster) + { + strcat(Format," / GameMaster"); + } + + sprintf(Buffer,Format, + BpsData,(int)BpsData/8,BpsDataMax,(int)BpsDataMax/8, + SendError,ReceiveError); + + elFont::Begin(GOTHIC,12,0,FALSE,FALSE,FALSE); + elFont::Color(RGB(255,255,255),RGB(0,0,128),FALSE); + elFont::Draw(0,30,Buffer); + elFont::Before(); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- メッセージの送信 -*/ +/*- -*/ +/*- char* Message : メッセージ ( NETMSG_SIZE以内 ) -*/ +/*- int Size : メッセージのバイト数 -*/ +/*- 省略/文字列 = 0 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elNetwork::Send(char* Message,int Size=0) +{ + static char Buffer[NETMSG_SIZE2]; + + // バイト数が省略されている場合 + if (!Size) Size=strlen(Message); + + // メッセージリストに保存 + MessageList[SendListNo].No=++SendNo; + MessageList[SendListNo].Type=0L; + memset(MessageList[SendListNo].Message,0x00,NETMSG_SIZE); + memcpy(MessageList[SendListNo].Message,Message,Size); + + // 送信用に変換 + memcpy(Buffer,&MessageList[SendListNo],sizeof(MessageList[SendListNo])); + + // メッセージ送信 + DPObject->Send(PlayerID,DPID_ALLPLAYERS,0,Buffer,sizeof(Buffer)); + + // 送信ビット数に加算 + BpsCnt+=(long)(sizeof(Buffer)*8); + + if (MessageAutoRetry) + { + // メッセージリストNoのカウント + if (++SendListNo>LIST_MAX) SendListNo=1; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- メッセージの受信 -*/ +/*- -*/ +/*- char* Message : メッセージ ( NETMSG_SIZE以内 ) -*/ +/*- int Size : メッセージのバイト数 -*/ +/*- 省略/文字列 = 0 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 受信完了 -*/ +/*- FALSE = メッセージなし -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elNetwork::Receive(char* Message,int Size=0) +{ + static DPID SendID,ReceiveID; + static ULONG DataSize; + static char Buffer[NETMSG_SIZE2]; + static int i; + static BOOL Flag; + + // ネットワークからのメッセージ受信の場合 + if (!CallListData) + { + Buffer[0]=NULL; + DataSize=NETMSG_SIZE2; + + if (DPObject->Receive(&SendID,&ReceiveID,DPRECEIVE_ALL,Buffer, + &DataSize)!=DP_OK) + { + return FALSE; + } + + if (ReceiveID!=PlayerID) return FALSE; + + // 受信ビット数に加算 + BpsCnt+=(long)(DataSize*8); + + if (SendID!=DPID_SYSMSG) + { + while (TRUE) + { + // 受信用に変換 + memcpy(&MessageList[0],Buffer,sizeof(MessageList[0])); + + // 通常のメッセージの場合 + if (MessageList[0].Type==0L) + { + if (MessageAutoRetry) + { + // すでに受信済なメッセージNoの場合 + if (MessageList[0].NoReceiveNo+1) + { + // 初めての受信エラーの場合 + if (!ReceiveSave) + { + // メッセージNoの退避 + ReceiveLastNo=MessageList[0].No; + } + + // メッセージリストに保存 + MessageList[ReceiveListNo].No=MessageList[0].No; + MessageList[ReceiveListNo].Type=MessageList[0].Type; + memcpy(MessageList[ReceiveListNo].Message, + MessageList[0].Message, + sizeof(MessageList[0].Message)); + + // メッセージリストNoのカウント + if (++ReceiveListNo>LIST_MAX*2) ReceiveListNo=LIST_MAX+1; + + // 受信エラー多発で、メッセージ受信が不可能な場合 + if (++ReceiveSave>LIST_MAX) Warning=TRUE; + + // 受信エラー数のカウント + ReceiveError++; + + // メッセージ再送信要求用にメッセージリスト保存 + MessageList[0].Type=(MessageList[0].No-1+1)*10L; + MessageList[0].No=++SendNo; + MessageList[0].Message[0]=NULL; + + // 送信用に変換 + memcpy(Buffer,&MessageList[0],sizeof(MessageList[0])); + + // メッセージ送信 + DPObject->Send(PlayerID,DPID_ALLPLAYERS,0, + Buffer,sizeof(Buffer)); + + return FALSE; + } + else + { + if (MessageAutoRetry) + { + // 受信エラーが起きた直前まで復帰できた場合 + if (MessageList[0].No==ReceiveLastNo-1) + { + CallListData=TRUE; + } + + // メッセージNoの退避 + ReceiveNo=MessageList[0].No; + } + + // バイト数が省略されている場合 + if (!Size) + { + // 文字列として取得 + strcpy(Message,MessageList[0].Message); + } + else + { + // バイナリィとして取得 + memcpy(Message,MessageList[0].Message,Size); + } + } + + break; + } + + // 相手プレイヤーがネットワークから脱出した場合 + if (MessageList[0].Type==1L) + { + // メッセージNoの退避 + ReceiveNo=MessageList[0].No; + + PlayerOut=TRUE; + + Message[0]=NULL; + + break; + } + + #ifdef DIALOG + + // チャット開始が要求された場合 + if (MessageList[0].Type==2L) + { + // メッセージNoの退避 + ReceiveNo=MessageList[0].No; + + ChatOpen=TRUE; + + Message[0]=NULL; + + break; + } + + // チャット終了が要求された場合 + if (MessageList[0].Type==3L) + { + // メッセージNoの退避 + ReceiveNo=MessageList[0].No; + + ChatClose=TRUE; + + Message[0]=NULL; + + break; + } + + #endif + + // メッセージの再送信要求があった場合 + if (MessageAutoRetry && MessageList[0].Type>=10L) + { + // メッセージNoの退避 + ReceiveNo=MessageList[0].No; + + // 送信エラー数のカウント + SendError++; + + // メッセージリストから要求されたメッセージの検索 + Flag=FALSE; + + for (i=1;i<=LIST_MAX;i++) + { + // 見つかった場合 + if (MessageList[i].No==(MessageList[0].Type/10L)-1) + { + // メッセージ再送信要求用にメッセージリスト保存 + MessageList[0].No=(MessageList[0].Type/10L)-1; + MessageList[0].Type=0; + strcpy(MessageList[0].Message,MessageList[i].Message); + + // 送信用に変換 + memcpy(Buffer,&MessageList[0],sizeof(MessageList[0])); + + // メッセージ送信 + DPObject->Send(PlayerID,DPID_ALLPLAYERS,0, + Buffer,sizeof(Buffer)); + + Flag=TRUE; + + break; + } + } + + // 送信エラー多発で、メッセージ送信が不可能な場合 + if (Flag==FALSE) Warning=TRUE; + + return FALSE; + } + + break; + } + + return TRUE; + } + else + { + return FALSE; + } + } + else + { + for (i=LIST_MAX+1;i<=LIST_MAX*2;i++) + { + // 目的のメッセージが見つかった場合 + if (MessageList[ReceiveListNo].No) + { + // メッセージNoの退避 + ReceiveNo=MessageList[ReceiveListNo].No; + + // バイト数が省略されている場合 + if (!Size) + { + // 文字列として取得 + strcpy(Message,MessageList[ReceiveListNo].Message); + } + else + { + // バイナリィとして取得 + memcpy(Message,MessageList[ReceiveListNo].Message,Size); + } + + // 保存してあるメッセージリストをカウント + if (--ReceiveSave==0) CallListData=FALSE; + + // メッセージリストNoのカウント + if (++ReceiveListNo>LIST_MAX*2) ReceiveListNo=LIST_MAX+1; + + break; + } + + // メッセージリストNoのカウント + if (++ReceiveListNo>LIST_MAX*2) ReceiveListNo=LIST_MAX+1; + } + + // 全メッセージを処理した場合 + if (!ReceiveSave) + { + for (i=LIST_MAX+1;i<=LIST_MAX*2;i++) + { + MessageList[i].No=0; + } + } + + return TRUE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 送信前のデータ変換 -*/ +/*- -*/ +/*- void* Buffer : 送信用文字列バッファ -*/ +/*- const void* Data : 送信データ ( NETMSG_SIZE以内 ) -*/ +/*- size_t Size : 送信データのサイズ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elNetwork::SetSend(void* Buffer,const void* Data,size_t Size) +{ + memcpy(Buffer,Data,Size); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 受信後のデータ変換 -*/ +/*- -*/ +/*- void* Data : 受信データ -*/ +/*- const void* Buffer : 受信用文字列バッファ -*/ +/*- size_t Size : 受信データのサイズ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elNetwork::GetReceive(void* Data,const void* Buffer,size_t Size) +{ + memcpy(Data,Buffer,Size); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- メッセージ数の取得 -*/ +/*- -*/ +/*- 戻り値 : メッセージ数 ( int型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elNetwork::Count(void) +{ + static DWORD MsgCount; + + DPObject->GetMessageCount(PlayerID,&MsgCount); + + return (int)MsgCount; +} + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= セーバークラス定義 ( elSaver ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef SAVER + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- セーバークラスの初期化 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSaver::Init(void) +{ + CheckMouseFlag=TRUE; + CheckKeyboardFlag=TRUE; + AutoPreviewFlag=TRUE; + + MouseMoveCount=0; + + Config=FALSE; + Preview=FALSE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- マウスイベント監視の設定 -*/ +/*- -*/ +/*- BOOL Flag : TRUE = イベント監視あり -*/ +/*- FALSE = イベント監視なし -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSaver::CheckMouse(BOOL Flag) +{ + CheckMouseFlag=Flag; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- キーボードイベント監視の設定 -*/ +/*- -*/ +/*- BOOL Flag : TRUE = イベント監視あり -*/ +/*- FALSE = イベント監視なし -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSaver::CheckKeyboard(BOOL Flag) +{ + CheckKeyboardFlag=Flag; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- プレビュー時の自動拡大縮小の設定 -*/ +/*- -*/ +/*- BOOL Flag : TRUE = 自動的にプレビューサイズに拡大縮小する -*/ +/*- FALSE = 手動で描画する -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elSaver::AutoPreview(BOOL Flag) +{ + AutoPreviewFlag=Flag; +} + +#endif + +/*==============================================================================*/ +/*= =*/ +/*= ダイアログクラス定義 ( elDialog ) =*/ +/*= =*/ +/*==============================================================================*/ + +#ifdef DIALOG + +#ifdef DIRECTPLAY + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ダイアログクラスの初期化 ※ 内部で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::Init(void) +{ + int i; + + for (i=0;i<=CHAT_MAX;i++) + { + ChatData[i][0]=NULL; + } +} + +#endif + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ダイアログの表示 -*/ +/*- -*/ +/*- int ResID : リソースID -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDialog::Show(int ResID) +{ + if (_DialogActive) return FALSE; + + // IME状態の退避 + BackupIME=elSystem::StatusIME; + + // IMEの表示 + elSystem::IME(TRUE); + + // ダイアログの表示 + hdlg=CreateDialog(_Instance,MAKEINTRESOURCE(ResID),hwnd, + (DLGPROC)elDialogProc); + + ShowWindow(hdlg,SW_SHOW); + + // ダイアログ生成関数の呼び出し + elDialogCreate(); + + _DialogActive=TRUE; + _WindowActive=FALSE; + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ダイアログの消去 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::Hide(void) +{ + #ifdef DIRECTPLAY + + // 自分からチャットを開始した場合 + if (!elNetwork::ChatOpen) + + #endif + + { + // IME状態の復元 + if (!elDialog::BackupIME) + { + elSystem::IME(FALSE); + } + + ShowWindow(hdlg,SW_HIDE); + + _WindowActive=TRUE; + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- エディットテキストの設定 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- char* Data : 文字列 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::SetEdit(int ID,char* Data) +{ + SendDlgItemMessage(hdlg,ID,WM_SETTEXT,0,(LPARAM)(LPCTSTR)Data); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- エディットテキストの取得 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- char* Data : 文字列バッファ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::GetEdit(int ID,char* Data) +{ + int Size; + + Size=SendDlgItemMessage(hdlg,ID,WM_GETTEXTLENGTH,0,0); + + SendDlgItemMessage(hdlg,ID,WM_GETTEXT,Size+1,(LPARAM)Data); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スタティックテキストの設定 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- char* Data : 文字列 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::SetStatic(int ID,char* Data) +{ + SendDlgItemMessage(hdlg,ID,WM_SETTEXT,0,(LPARAM)(LPCTSTR)Data); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スタティックテキストの取得 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- char* Data : 文字列バッファ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::GetStatic(int ID,char* Data) +{ + int Size; + + Size=SendDlgItemMessage(hdlg,ID,WM_GETTEXTLENGTH,0,0); + + SendDlgItemMessage(hdlg,ID,WM_GETTEXT,Size+1,(LPARAM)Data); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- チェックボタンの設定 ( ラジオボタン ) -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- int Status : ボタン状態 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// ボタン状態 +static const int CHECK_OFF=0; // OFF +static const int CHECK_ON=1; // ON +static const int CHECK_GRAY=2; // 使用不可 + +void elDialog::SetCheck(int ID,int Status) +{ + SendDlgItemMessage(hdlg,ID,BM_SETCHECK,Status,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- チェックボタンの取得 ( ラジオボタン ) -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- -*/ +/*- 戻り値 : ボタン状態 ( int型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elDialog::GetCheck(int ID) +{ + return SendDlgItemMessage(hdlg,ID,BM_GETCHECK,0,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ラジオボタンの設定 -*/ +/*- -*/ +/*- int StartID : グループの最初のコントロールID -*/ +/*- int EndID : グループの最後のコントロールID -*/ +/*- int SetID : 設定するコントロールID -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::SetRadio(int StartID,int EndID,int SetID) +{ + CheckRadioButton(hdlg,StartID,EndID,SetID); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ラジオボタンの取得 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- -*/ +/*- 戻り値 : ボタン状態 ( int型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// ボタン状態 +static const int RADIO_OFF=0; // OFF +static const int RADIO_ON=1; // ON +static const int RADIO_GRAY=2; // 使用不可 + +int elDialog::GetRadio(int ID) +{ + return SendDlgItemMessage(hdlg,ID,BM_GETCHECK,0,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- コンボボックスに追加 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- char* Data : 文字列 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::AddCombo(int ID,char* Data) +{ + SendDlgItemMessage(hdlg,ID,CB_ADDSTRING,0,(LPARAM)(LPCTSTR)Data); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- コンボボックスから削除 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- int Line : 行 ( 0〜 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::DeleteCombo(int ID,int Line) +{ + SendDlgItemMessage(hdlg,ID,CB_DELETESTRING,Line,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- コンボボックスの初期化 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::ClearCombo(int ID) +{ + SendDlgItemMessage(hdlg,ID,CB_RESETCONTENT,0,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- コンボボックスの取得 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- char* Data : 文字列バッファ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::GetCombo(int ID,char* Data) +{ + int Line; + + Line=SendDlgItemMessage(hdlg,ID,CB_GETCURSEL,0,0); + + SendDlgItemMessage(hdlg,ID,CB_GETLBTEXT,Line,(LPARAM)(LPCSTR)Data); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- リストボックスに追加 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- char* Data : 文字列 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::AddList(int ID,char* Data) +{ + SendDlgItemMessage(hdlg,ID,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)Data); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- リストボックスから削除 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- int Line : 行 ( 0〜 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::DeleteList(int ID,int Line) +{ + SendDlgItemMessage(hdlg,ID,LB_DELETESTRING,Line,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- リストボックスの初期化 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::ClearList(int ID) +{ + SendDlgItemMessage(hdlg,ID,LB_RESETCONTENT,0,0); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- リストボックスの取得 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- int Line : 行 ( 0〜 ) -*/ +/*- char* Data : 文字列バッファ -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::GetList(int ID,int Line,char* Data) +{ + if (SendDlgItemMessage(hdlg,ID,LB_GETTEXT,Line,(LPARAM)(LPCSTR)Data)==LB_ERR) + { + strcpy(Data,""); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- リストボックスの項目数の取得 -*/ +/*- -*/ +/*- int ID : コントロールID -*/ +/*- -*/ +/*- 戻り値 : 項目数 ( int型 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +int elDialog::GetListCount(int ID) +{ + return SendDlgItemMessage(hdlg,ID,LB_GETCOUNT,0,0); +} + +#ifdef DIRECTPLAY + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- チャットの開始 ※ elNetworkクラスでネットワーク接続完了後に使用 -*/ +/*- -*/ +/*- int Time : 受信待ち時間 ( 秒 ) -*/ +/*- int EditID : エディットテキストのコントロールID ( 送信メッセージ ) -*/ +/*- int ListID : リストボックスのコントロールID ( 送受信メッセージ格納 ) -*/ +/*- int StaticID : スタティックテキストのコントロールID ( システム通知 ) -*/ +/*- int Count : リストボックスの行数 -*/ +/*- BOOL LoadFlag : TRUE = メッセージの復元あり -*/ +/*- FALSE = メッセージの復元なし -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::OpenChat(int Time,int EditID,int ListID,int StaticID, + int Count,BOOL LoadFlag) +{ + char Buffer[NETMSG_SIZE2]; + + ChatEditID=EditID; + ChatListID=ListID; + ChatStaticID=StaticID; + + if (Count<=CHAT_MAX) + { + ChatListCount=Count; + } + else + { + ChatListCount=CHAT_MAX; + } + + // スタティックテキストに通知 + elDialog::SetStatic(ChatStaticID," チャットを開始しました。"); + + if (LoadFlag) + { + // チャットメッセージの復元 + LoadChat(); + } + + // 自分からチャットを開始した場合 + if (!elNetwork::ChatOpen) + { + // チャット開始用にメッセージリスト保存 + MessageList[0].No=++elNetwork::SendNo; + MessageList[0].Type=2L; + MessageList[0].Message[0]=NULL; + + // 送信用に変換 + memcpy(Buffer,&MessageList[0],sizeof(MessageList[0])); + + // メッセージ送信 + DPObject->Send(elNetwork::PlayerID,DPID_ALLPLAYERS,0, + Buffer,sizeof(Buffer)); + } + + // タイマーの設定 + SetTimer(hdlg,1,Time*1000,NULL); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- チャットの終了 -*/ +/*- -*/ +/*- BOOL SaveFlag : TRUE = メッセージの退避あり -*/ +/*- FALSE = メッセージの退避なし -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::CloseChat(BOOL SaveFlag) +{ + char Buffer[NETMSG_SIZE2]; + + // 自分からチャットを開始した場合 + if (!elNetwork::ChatOpen) + { + // タイマーの削除 + KillTimer(hdlg,1); + + // スタティックテキストに通知 + elDialog::SetStatic(ChatStaticID," チャットを終了しました。"); + + // 相手に終了メッセージを送信する場合 + if (elNetwork::ChatCloseMsg) + { + // チャット終了用にメッセージリスト保存 + MessageList[0].No=++elNetwork::SendNo; + MessageList[0].Type=3L; + MessageList[0].Message[0]=NULL; + + // 送信用に変換 + memcpy(Buffer,&MessageList[0],sizeof(MessageList[0])); + + // メッセージ送信 + DPObject->Send(elNetwork::PlayerID,DPID_ALLPLAYERS,0, + Buffer,sizeof(Buffer)); + } + + // フラグの初期化 + elNetwork::ChatOpen=FALSE; + elNetwork::ChatClose=FALSE; + elNetwork::ChatCloseMsg=TRUE; + + if (SaveFlag) + { + // チャットメッセージの退避 + SaveChat(); + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- チャットメッセージの復元 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::LoadChat(void) +{ + int i; + + if (ChatData[0][0]!=NULL) + { + // エディットテキストに代入 + elDialog::SetEdit(ChatEditID,ChatData[0]); + } + + for (i=1;i<=ChatListCount;i++) + { + if (ChatData[i][0]!=NULL) + { + // リストボックスに追加 + elDialog::AddList(ChatListID,ChatData[i]); + } + else + { + break; + } + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- チャットメッセージの退避 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDialog::SaveChat(void) +{ + int i; + char Buffer[256]; + + // エディットテキストの内容を取得 + elDialog::GetEdit(ChatEditID,Buffer); + + if (strlen(Buffer)>100) Buffer[100]=NULL; + + strcpy(ChatData[0],Buffer); + + // リストボックスの内容を取得 + for (i=1;i<=ChatListCount;i++) + { + elDialog::GetList(ChatListID,i-1,Buffer); + + if (strlen(Buffer)>100) Buffer[100]=NULL; + + strcpy(ChatData[i],Buffer); + } +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- チャットにメッセージ送信 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDialog::SendChat(void) +{ + char Buffer[256]; + + if (!elNetwork::PlayerOut) + { + // エディットテキストの内容を取得 + elDialog::GetEdit(ChatEditID,Buffer); + + if (Buffer[0]==NULL) return FALSE; + + if (strlen(Buffer)>100) Buffer[100]=NULL; + + // データ送信 + elNetwork::Send(Buffer,strlen(Buffer)); + + // エディットテキストを初期化 + elDialog::SetEdit(ChatEditID,""); + + // リストボックスに追加 + elDialog::AddList(ChatListID,Buffer); + + // スタティックテキストに通知 + elDialog::SetStatic(ChatStaticID," メッセージを送信しました。"); + } + else + { + if (!elNetwork::NetOn) + { + // スタティックテキストに通知 + elDialog::SetStatic(ChatStaticID, + " ネットワークに接続していません。"); + } + else + { + // スタティックテキストに通知 + elDialog::SetStatic(ChatStaticID, + " 相手が接続していません。"); + } + } + + // リストボックスが最大行を超えた場合 + if (elDialog::GetListCount(ChatListID)>ChatListCount) + { + // 先頭行を削除 + elDialog::DeleteList(ChatListID,0); + } + + return TRUE; +} + +#endif + +#endif + +/* +// ファイルオープンダイアログの例 +int i,j; +OPENFILENAME ofn; +char ft[]="WAVEファイル(*.wav) *.wav "; +char fn[256]="",lfn[256]=""; + +j=(int)strlen(ft); +for (i=0;i + +BROWSEINFO bi; +LPITEMIDLIST id; + +memset(&bi,0x00,sizeof(BROWSEINFO)); +bi.hwndOwner=hwnd; +bi.lpszTitle=(LPCSTR)"検索"; +bi.ulFlags=BIF_BROWSEFORCOMPUTER|BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS; + +id=SHBrowseForFolder(&bi); + +if (id) +{ + if (SHGetPathFromIDList(id,Buffer)) + { + MESG(Buffer); + } +} +*/ + +/* +// アセンブラでの描画例 +xx=(640-0)/4; +yy=480-0; +AddPitch1=ddsd1.lPitch-xx*8; +AddPitch2=ddsd2.lPitch-xx*8; +data1=(LPDWORD)ddsd1.lpSurface+0+0*AddPitch1; +data2=(LPDWORD)ddsd2.lpSurface+0+0*AddPitch2; + +__asm +{ + push esi + push edi + + mov ecx,yy + mov esi,data1 + mov edi,data2 + + loop1: + mov edx,xx + + loop2: + mov eax,[esi] + mov ebx,[esi+4] + sub eax, + dec ebx + mov [edi],eax + mov [edi+4],ebx + lea esi,[esi+8] + lea edi,[edi+8] + dec edx + jnz loop2 + + add esi,AddPitch1 + add edi,AddPitch2 + dec ecx + jnz loop1 + + pop edi + pop esi +} +*/ + +/* +// 32ビットアクセスの例 +BOOL elDraw::BlendLayer2(int Px,int Py,DDOBJ ObjDD,int X1,int Y1,int X2,int Y2) +{ + static HRESULT ddret; + static DDSURFACEDESC ddsd1,ddsd2; + static LPDWORD data1,data2; + static long AddPitch1,AddPitch2; + static ULONG Get1,Get2; + static DWORD x,y,Sx,Sy,Ex,Ey; + + // 描画領域の計算 + Sx=0; + Sy=0; + Ex=X2-X1; + Ey=Y2-Y1; + + if (Px+((int)Ex-(int)Sx)>Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>2; + AddPitch2=ddsd2.lPitch>>2; + + // スプライトの先頭位置を取得 + data1=(LPDWORD)ddsd1.lpSurface+(X1>>1)+Y1*AddPitch1; + data2=(LPDWORD)ddsd2.lpSurface+(Px>>1)+Py*AddPitch2; + + // データ転送 + for (y=Sy;y>1;x++) + { + Get1=*(data1+x); + + if (Get1!=0x00000000) + { + Get1>>=1; + Get1&=MaskRGB2; + Get2=*(data2+x)>>1; + Get2&=MaskRGB2; + + *(data2+x)=Get1+Get2; + } + } + + // Y方向に加算 + data1+=AddPitch1; + data2+=AddPitch2; + } + + // スプライトのロック解除 + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + DD_UNLOCK(DDBack,ddsd2.lpSurface); + } + + return TRUE; +} +*/ + +/* +// タスク切り換え(ALT+TAB、CTRL+ESC)阻止の例 +if (msg.message==WM_SYSKEYUP && _FullScreen)\ +{\ + if (msg.wParam==VK_ESCAPE || msg.wParam==VK_TAB) continue;\ +}\ + +// ※ PeekMessageループ内の、msg.message==WM_QUITの後あたりに記述すればOK +*/ + +/* +// Direct3D RMでのテクスチャーコールバックの例 +HRESULT TextureCallback(char* TextureName,void*,LPDIRECT3DRMTEXTURE* RMTexture) +{ + // テクスチャーの読み込み + *RMTexture=el3D::LoadTexture(TextureName); + + // 透明色を白に設定 + (*RMTexture)->SetDecalTransparency(TRUE); + (*RMTexture)->SetDecalTransparentColor(D3DRGB(F(1),F(1),F(1))); + + return D3DRM_OK; +} + + // el3D::LoadObject関数の中 + if (D3RMBuilder->Load(Buffer,NULL,D3DRMLOAD_FROMFILE, + (D3DRMLOADTEXTURECALLBACK)TextureCallback, + NULL)!=D3DRM_OK) +*/ diff --git a/PROJECT/elDraw32.h b/PROJECT/elDraw32.h new file mode 100644 index 0000000..709ca81 --- /dev/null +++ b/PROJECT/elDraw32.h @@ -0,0 +1,7898 @@ +// 2000.6.18 +// フルカラー版 elDraw +// 元ファイル = el.h (1999.11.22) + +// Borland C++ Builder,Borland C++ Compilerでコンパイルする際には +// このファイルをインクルードする前に #define BCC と書く必要があります。 + +// 最新版はこちら http://www.ky.xaxon.ne.jp/~hitoshi/index.htm +// 何かありましたら こちらまで hitoshi@ky.xaxon.ne.jp (小林 均) + + +// DirectX7以降の新しいコード +#ifdef NEWCODE + +//#define LPDIRECTDRAW LPDIRECTDRAW7 +//#define LPDIRECTDRAWSURFACE LPDIRECTDRAWSURFACE7 +#define DDSURFACEDESC DDSURFACEDESC2 +//#define DDSCAPS DDSCAPS2 +//#define IDirectDraw IDirectDraw7 +//#define IDirectDrawSurface IDirectDrawSurface7 + +#define DD_UNLOCK(Surface,Para)\ +\ + Surface->Unlock(NULL); + +#else + +#define DD_UNLOCK(Surface,Para)\ +\ + Surface->Unlock(Para); + +#endif + + +// MMXをコンパイルした時の警告表示回避(elDraw32.hの最後で元に戻しています) +#pragma warning( disable : 4799 ) + + +class elDraw32 +{ + public: + + static void Init(void); + + static BOOL MMX_CHECK(void); // MMXがあるかどうか チェックをする関数 + static BOOL MMX_CHECKED; // MMXがあるかどうか チェックをしたか のフラグ + static BOOL USE_MMX; // MMXを使うかどうかのフラグ + + static void ColorFill(int,int,int,int,COLORREF); + static BOOL ColorBlend(int,int,int,int,COLORREF); + static BOOL MirrorLayer(int,int,int,DDOBJ,int,int,int,int); + + static BOOL BlendLayer(int,int,DDOBJ,int,int,int,int); + static BOOL BlendLayer(int,int,float,DDOBJ,int,int,int,int); //(MMX対応) + static BOOL BlendLayer(int,int,float,float,float,DDOBJ,int,int,int,int); //(MMX対応) +// static BOOL BlendLayer(int,int,int,DDOBJ,int,int,int,int); +// static BOOL BlendLayer(int,int,int,int,int,DDOBJ,int,int,int,int); +// static BOOL BlendLayer(int,int,float,float,float,int,int,int, +// DDOBJ,int,int,int,int); +// static BOOL BlendLayer(int,int,int,int,int,int,int,int, +// DDOBJ,int,int,int,int); + static BOOL AddBlendLayer(int,int,DDOBJ,int,int,int,int); //(MMX対応) +// static BOOL AddBlendLayer(int,int,float,DDOBJ,int,int,int,int); + static BOOL DelBlendLayer(int,int,DDOBJ,int,int,int,int); //(MMX対応) + static BOOL EdgeBlendLayer(int,int,DDOBJ,int,int,int,int); + static BOOL PlainLayer(int,int,BOOL,BOOL,BOOL,DDOBJ,int,int,int,int); + static BOOL BrightLayer(int,int,float,DDOBJ,int,int,int,int); //(MMX対応) + static BOOL BrightLayer(int,int,float,float,float,DDOBJ,int,int,int,int); //(MMX対応) + static BOOL BrightLayer(int,int,int,DDOBJ,int,int,int,int); + static BOOL BrightLayer(int,int,int,int,int,DDOBJ,int,int,int,int); + static BOOL ShadeLayer(int,int,int,DDOBJ,int,int,int,int); + static BOOL GrayLayer(int,int,DDOBJ,int,int,int,int); + static BOOL MeshLayer(int,int,int,int,int,float,float,DDOBJ,int,int,int,int); + static BOOL RotateLayer(int,int,int,int,int,DDOBJ,int,int,int,int); + static BOOL TileRotateLayer(int,int,int,int,int,DDOBJ,int,int,int,int); + static BOOL ZoomRotateLayer(int,int,int,int,int,float,DDOBJ,int,int,int,int); + static BOOL TileZoomRotateLayer(int,int,int,int,int,float,DDOBJ, + int,int,int,int); + static BOOL MysteryLayer(int,int,int,int,int,float,float,float,float, + float,float,float,DDOBJ,int,int,int,int); + static BOOL PickLayer(int,int,int,int,DDOBJ,int,int,int,int); + static BOOL ShiftLayer(int,int,float,DDOBJ,int,int,int,int); +// static void CreateTunnel(int,int,int,int,int,int,int,int,int,int); // 32ビット化 必要なし + static BOOL TunnelLayer(int,int,int,int,DDOBJ); + static BOOL LightLayer(int,int,int,int,int,WORD,BOOL,DDOBJ,int,int,int,int); + + // ハイカラー・MMX対応版(elDraw32の内部で使用) + static BOOL BlendLayer16MMX(int,int,float,DDOBJ,int,int,int,int); //(MMX対応) + static BOOL BlendLayer16MMX(int,int,float,float,float,DDOBJ,int,int,int,int); //(MMX対応) + static BOOL BrightLayer16MMX(int,int,float,DDOBJ,int,int,int,int); //(MMX対応) + static BOOL BrightLayer16MMX(int,int,float,float,float,DDOBJ,int,int,int,int); //(MMX対応) + + // 以下の5つは 元のelにはありません(独自拡張版) + static BOOL DelBlendLayerEx(int,int,DDOBJ,int,int,int,int); // RGBを使った減算ブレンド(MMX対応) + static BOOL GrayLayerEx(int,int,DDOBJ,int,int,int,int); // (R+G+B)/3 ではないグレースケール + static BOOL RotateLayerEx(int,int,int,int,int,DDOBJ,int,int,int,int); // 回転+アンチエイリアス・ほっしーさん作 +// static BOOL ShiftLayerEx(int,int,int,float,DDOBJ,int,int,int,int); // 角度指定付きピクセルシフト + static BOOL LimitLayer(int,int,int,DDOBJ,int,int,int,int); // シャドー部を切り捨てて描画 + + // 独自拡張版のハイカラー版(elDraw32の内部で使用) + static BOOL DelBlendLayerEx16(int,int,DDOBJ,int,int,int,int); // RGBを使った減算ブレンド + static BOOL GrayLayerEx16(int,int,DDOBJ,int,int,int,int); // (R+G+B)/3 ではないグレースケール + static BOOL RotateLayerEx16(int,int,int,int,int,DDOBJ,int,int,int,int); // 回転+アンチエイリアス・ほっしーさん作 +// static BOOL ShiftLayerEx16(int,int,int,float,DDOBJ,int,int,int,int); // 角度指定付きピクセルシフト + static BOOL LimitLayer16(int,int,int,DDOBJ,int,int,int,int); // シャドー部を切り捨てて描画 + + static BOOL Initialized; + static unsigned char AddBlendList[]; + static unsigned char DelBlendList[]; + static unsigned char GrayList[]; + static unsigned char GrayListExR[]; + static unsigned char GrayListExG[]; + static unsigned char GrayListExB[]; + + union Buff32 + { + UINT Buff; + unsigned char BuffRGB[4]; + }; +}; + +// リスト情報 +BOOL elDraw32::Initialized=FALSE; +//unsigned short elDraw::BlendList[3*32*32*32]; +unsigned char elDraw32::AddBlendList[512]; +unsigned char elDraw32::DelBlendList[256*256]; +unsigned char elDraw32::GrayList[256+256+256]; +unsigned char elDraw32::GrayListExR[256]; +unsigned char elDraw32::GrayListExG[256]; +unsigned char elDraw32::GrayListExB[256]; + + +// MMXチェック用フラグ +BOOL elDraw32::MMX_CHECKED=FALSE; // MMXがあるかどうか チェックをしたか のフラグ +BOOL elDraw32::USE_MMX=FALSE; // MMXを使うかどうかのフラグ + +// VC++にはない インラインアセンブラの命令(MMX用) +#ifndef BCC +#define CPUID\ + _asm _emit 0x0f\ + _asm _emit 0xa2 + +#define EMMS\ + _asm _emit 0x0f\ + _asm _emit 0x77 +#endif // #ifndef BCC + +// BCB Learning Edition と Borland C++ Compiler5.5用 +// 『インテル・アーキテクチャ・ソフトウェア・ディベロッパーズ・マニュアル 中巻』より参照 +#ifdef BCC + +#define CPUID __emit__(0x0f,0xa2); +#define EMMS __emit__(0x0f,0x77); + +#define mm0 0 +#define mm1 1 +#define mm2 2 +#define mm3 3 +#define mm4 4 +#define mm5 5 +#define mm6 6 +#define mm7 7 +#define mm8 8 + +// メモリ位置の表現には、アドレス、BPからの1バイト値のオフセット、BPからの4バイト値のオフセット、レジスタ値、があります。 +// ここでは、アドレスを前提としています。 +// そのため、変数memは遠い位置にあるか、staticで宣言しておかなければいけません。 +// 例: +// static __int64 Src,Dest; +// MOVQ_mm_mem(mm0,Src) +// MOVQ_mem_mm(Dest,mm0) +#define MOVD_mm_mem(mm,mem) __emit__(0x0f,0x6e,mm*8|0x05,&mem); // Mod=00 REG R/M=101 +#define MOVD_mem_mm(mem,mm) __emit__(0x0f,0x7e,mm*8|0x05,&mem); // Mod=00 REG R/M=101 +#define MOVQ_mm_mem(mm,mem) __emit__(0x0f,0x6f,mm*8|0x05,&mem); // Mod=00 REG R/M=101 +#define MOVQ_mem_mm(mem,mm) __emit__(0x0f,0x7f,mm*8|0x05,&mem); // Mod=00 REG R/M=101 + +#define PACKUSWB_mm_mm(mm_1,mm_2) __emit__(0x0f,0x67,0xc0|mm_1*8|mm_2); // Mod=11 REG=mm_1 R/M=mm_2 +#define PAND_mm_mm(mm_1,mm_2) __emit__(0x0f,0xdb,0xc0|mm_1*8|mm_2); // Mod=11 REG=mm_1 R/M=mm_2 +#define PADDUSB_mm_mm(mm_1,mm_2) __emit__(0x0f,0xdc,0xc0|mm_1*8|mm_2); // Mod=11 REG=mm_1 R/M=mm_2 +#define PADDUSW_mm_mm(mm_1,mm_2) __emit__(0x0f,0xdd,0xc0|mm_1*8|mm_2); // Mod=11 REG=mm_1 R/M=mm_2 +#define PADDW_mm_mm(mm_1,mm_2) __emit__(0x0f,0xfd,0xc0|mm_1*8|mm_2); // Mod=11 REG=mm_1 R/M=mm_2 +#define PMULHW_mm_mm(mm_1,mm_2) __emit__(0x0f,0xe5,0xc0|mm_1*8|mm_2); // Mod=11 REG=mm_1 R/M=mm_2 +#define PSUBUSB_mm_mm(mm_1,mm_2) __emit__(0x0f,0xd8,0xc0|mm_1*8|mm_2); // Mod=11 REG=mm_1 R/M=mm_2 +#define PUNPCKLBW_mm_mm(mm_1,mm_2) __emit__(0x0f,0x60,0xc0|mm_1*8|mm_2); // Mod=11 REG=mm_1 R/M=mm_2 +#define PUNPCKLWD_mm_mem(mm,mem) __emit__(0x0f,0x61,mm*8|0x05,&mem); // Mod=00 REG R/M=101 +#define PUNPCKLDQ_mm_mm(mm_1,mm_2) __emit__(0x0f,0x62,0xc0|mm_1*8|mm_2); // Mod=11 REG=mm_1 R/M=mm_2 +#define PXOR_mm_mm(mm_1,mm_2) __emit__(0x0f,0xef,0xc0|mm_1*8|mm_2); // Mod=11 REG=mm_1 R/M=mm_2 + +#endif // #ifdef BCC + + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- ルックアップテーブルの作成 ※ elDraw32で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +void elDraw32::Init(void) +{ + int i,j; + unsigned char x; + + // フルカラー用 ブレンド合成結果リストの作成 +/* for (c=0;c<3;c++) + { + for (b=0;b<32;b++) + { + for (i=0;i<32;i++) + { + for (j=0;j<32;j++) + { + x=0; + + if (i-b>=0) + { + x+=i-b; + } + + if (j-(31-b)>=0) + { + x+=j-(31-b); + } + + switch (c) + { + case 0: x<<=sr; break; + case 1: x<<=sg; break; + case 2: x<<=sb; break; + } + + BlendList[(c<<15)+(b<<10)+(i<<5)+j]=x; + } + } + } + } +*/ + // フルカラー用 加算ブレンド合成結果リストの作成 + for (i=0;i<256;i++) + { + elDraw32::AddBlendList[i]=i; + elDraw32::AddBlendList[i+256]=0xff; + } + + // フルカラー用 減算ブレンド合成結果リストの作成 + for (i=0;i<256;i++) + { + for (j=0;j<256;j++) + { + x=0; + + if (i-j>0) + { + x=i-j; + } + + elDraw32::DelBlendList[i*256+j]=x; + } + } + + // グレースケール計算結果リストの作成 + for (i=0;i<256*3;i++) + { + elDraw32::GrayList[i]=(unsigned int)((double)i/(double)3); + } + + // グレースケール計算結果リストの作成(独自拡張版 用) + for (i=0;i<256;i++) + { + // ↓この式は 1999.10月号の 月刊Cマガジンを参考にしました。 + elDraw32::GrayListExR[i]=(unsigned int)((double)i*0.3); + elDraw32::GrayListExG[i]=(unsigned int)((double)i*0.59); + elDraw32::GrayListExB[i]=(unsigned int)((double)i*0.11); + } + + elDraw32::Initialized=TRUE; + + if (elDraw32::MMX_CHECKED==FALSE) + { + elDraw32::MMX_CHECK(); + } + + return; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- MMXの検出 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw32::MMX_CHECK(void) +{ + static bool _CPUID; // CPUIDを使用できるかどうか + static int FeatureFlags; // 検出時に使用 + + // CPUIDの検出 + #ifndef BCC + _asm + { + pushfd + pop eax + xor eax,00200000h + push eax + popfd + pushfd + pop ebx + cmp eax,ebx + mov _CPUID,1 + je support_CPUID + mov _CPUID,0 + support_CPUID: + } + #else // #ifndef BCC + { + __emit__(0x9c); // pushfd + __emit__(0x58); // pop eax + __emit__(0x35,0x00200000u); // xor eax,00200000h + __emit__(0x50); // push eax + __emit__(0x9d); // popfd + __emit__(0x9c); // pushfd + __emit__(0x5b); // pop ebx + __emit__(0x3b,0xc3); // cmp eax,ebx + __emit__(0xc6,0x05,&_CPUID,0x01); // mov _CPUID,1 + __emit__(0x74,0x07); // je support_CPUID + __emit__(0xc6,0x05,&_CPUID,0x00); // mov _CPUID,0 +// // support_CPUID: + } + #endif // #ifndef BCC + + if (!_CPUID) // CPUID がサポートされていない (==80386以下なのでMMXもなし) + { + elDraw32::MMX_CHECKED=TRUE; + elDraw32::USE_MMX=FALSE; + return FALSE; + } + + // MMXの検出 + #ifndef BCC + _asm + { + mov eax,0 + CPUID + mov FeatureFlags,eax + } + #else // #ifndef BCC + { + __emit__(0xb8,0u); // mov eax,0 + CPUID // CPUID + __emit__(0xa3,&FeatureFlags); // mov FeatureFlags,eax + } + #endif // #ifndef BCC + + // MMXがあるかどうかチェックできなかった場合 + if (FeatureFlags==0) + { + MMX_CHECKED=TRUE; + USE_MMX=FALSE; + return FALSE; + } + + if (FeatureFlags>0) + { + #ifndef BCC + _asm + { + mov eax,1 + CPUID + mov FeatureFlags,edx + } + #else // #ifndef BCC + { + __emit__(0xb8,1u); // mov eax,1 + CPUID // CPUID + __emit__(0x89,0x15,&FeatureFlags); // mov FeatureFlags,edx + } + #endif // #ifndef BCC + + // MMXが検出された場合 + if (FeatureFlags&0x00800000) + { + MMX_CHECKED=TRUE; + USE_MMX=TRUE; + } + // MMXが検出されなかった場合 + else + { + MMX_CHECKED=TRUE; + USE_MMX=FALSE; + return FALSE; + } + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 指定された領域を任意の色で初期化 -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- COLORREF Color : 色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +//void elDraw::ColorFill(int X1,int Y1,int X2,int Y2,WORD Color) +void elDraw32::ColorFill(int X1,int Y1,int X2,int Y2,COLORREF Color)// +{ + if (elSystem::ColorBit()<24) { + elDraw::ColorFill(X1,Y1,X2,Y2,RGB16(GetRValue(Color)>>3,GetGValue(Color)>>3,GetBValue(Color)>>3));return;} + + static DDBLTFX ddbltfx; + static RECT rect; + + rect.left=X1; + rect.top=Y1; + rect.right=X2; + rect.bottom=Y2; + + ddbltfx.dwSize=sizeof(ddbltfx); +// ddbltfx.dwFillColor=Color; + ddbltfx.dwFillColor=GetRValue(Color)<Blt(&rect,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx); +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- カラーブレンド ( 50% ) ※ フルカラー -*/ +/*- -*/ +/*- int X1 : 左上X座標 -*/ +/*- int Y1 : 左上Y座標 -*/ +/*- int X2 : 右下X座標 -*/ +/*- int Y2 : 右下Y座標 -*/ +/*- COLORREF Color : 色 ( RGB(赤,緑,青)で指定 ) -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- : FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +//BOOL elDraw::ColorBlend(int X1,int Y1,int X2,int Y2,WORD Color) +BOOL elDraw32::ColorBlend(int X1,int Y1,int X2,int Y2,COLORREF Color)// +{ + if (elSystem::ColorBit()<24) return elDraw::ColorBlend(X1,Y1,X2,Y2,RGB16(GetRValue(Color)>>3,GetGValue(Color)>>3,GetBValue(Color)>>3)); + + static HRESULT ddret; + static DDSURFACEDESC ddsd; +// static LPWORD data; + static LPDWORD data;// + static long AddPitch; + static int x,y; + static UINT Buff,Buff2; + + // 描画領域の計算 + if (X2>elDraw::Vx2) X2-=X2-elDraw::Vx2; + if (Y2>elDraw::Vy2) Y2-=Y2-elDraw::Vy2; + if (X1=X1 && Y2>=Y1) + { + // 構造体の初期化 + memset(&ddsd,0x00,sizeof(DDSURFACEDESC)); + ddsd.dwSize=sizeof(DDSURFACEDESC); + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // Y方向への追加バイト数の取得 +// AddPitch=ddsd.lPitch>>1; + AddPitch=ddsd.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data=(LPWORD)ddsd.lpSurface+Y1*AddPitch; + data=(LPDWORD)ddsd.lpSurface+Y1*AddPitch;// + + // Colorの変換(elDraw32にて付け足し)// + Color= GetRValue(Color)<>1; + Buff2&=elDraw::MaskRGB; + + // データ転送 + for (y=Y1;y>=1; + Buff&=elDraw::MaskRGB; + + *(data+x)=Buff+Buff2; + } + + // Y方向に加算 + data+=AddPitch; + } + + // スプライトのロック解除 + DD_UNLOCK(DDBack,ddsd.lpSurface); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- これより以後の 変数の置き換え ※ elDraw32で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +#define Vx1 elDraw::Vx1 +#define Vy1 elDraw::Vy1 +#define Vx2 elDraw::Vx2 +#define Vy2 elDraw::Vy2 + +#define MaskR elDraw::MaskR +#define MaskG elDraw::MaskG +#define MaskB elDraw::MaskB +#define MaskRGB elDraw::MaskRGB +#define BitR elDraw::BitR +#define BitG elDraw::BitG +#define BitB elDraw::BitB +#define ShiftR elDraw::ShiftR +#define ShiftG elDraw::ShiftG +#define ShiftB elDraw::ShiftB +#define ShiftR2 elDraw::ShiftR2 +#define ShiftG2 elDraw::ShiftG2 +#define ShiftB2 elDraw::ShiftB2 +#define BlendList elDraw::BlendList + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( 反転 ) -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- int Mirror : 反転タイプ -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +// 反転タイプ +//static const int NORMAL=0; // 反転なし +//static const int MIRROR_X=1; // 左右反転 +//static const int MIRROR_Y=2; // 上下反転 +//static const int MIRROR_XY=3; // 上下左右反転 + +BOOL elDraw32::MirrorLayer(int Px,int Py,int Mirror,DDOBJ ObjDD, + int X1,int Y1,int X2,int Y2) +{ + if (elSystem::ColorBit()<24) return elDraw::MirrorLayer(Px,Py,Mirror,ObjDD,X1,Y1,X2,Y2);// + + static HRESULT ddret; + static DDSURFACEDESC ddsd1,ddsd2; +// static LPWORD data1,data2; + static LPDWORD data1,data2;// + static long AddPitch1,AddPitch2; + static int Px2,Py2; + static UINT x,y,Sx,Sy,Ex,Ey; + static UINT Buff; + + // 描画領域の計算 + Sx=0; + Sy=0; + Ex=X2-X1; + Ey=Y2-Y1; + Px2=Px; + Py2=Py; + + if (Px2+((int)Ex-(int)Sx)>Vx2) + { + Ex-=(Px2+(Ex-Sx)-Vx2); + } + + if (Py2+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py2+(Ey-Sy)-Vy2); + } + + if (Px2=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + if (Mirror==NORMAL) + { + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px2+Py2*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px2+Py2*AddPitch2;// + + // データ転送 + for (y=Sy;y=Vx1 && Py>=Vy1) + { +// data1=(LPWORD)ddsd1.lpSurface+X1+(X2-(Ex-Sx))+ + data1=(LPDWORD)ddsd1.lpSurface+X1+(X2-(Ex-Sx))+ + (Y1+Ey-Sy-1+Y2-(Ey-Sy))*AddPitch1; + } + else + { + if (PxVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // データ転送 + for (y=Sy;y>=1; + Buff&=MaskRGB; + Buff2=*(data2+x)>>1; + Buff2&=MaskRGB; + + *(data2+x)=Buff+Buff2; + } + } + + // Y方向に加算 + data1+=AddPitch1; + data2+=AddPitch2; + } + + // スプライトのロック解除 + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + DD_UNLOCK(DDBack,ddsd2.lpSurface); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( 値指定ブレンド ) ※ フルカラー -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- float Blend : 混合率 ( 0.0 〜 1.0 ) -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- : FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw32::BlendLayer(int Px,int Py,float Blend,DDOBJ ObjDD, + int X1,int Y1,int X2,int Y2) +{ + if (elSystem::ColorBit()<24) return elDraw32::BlendLayer16MMX(Px,Py,Blend,ObjDD,X1,Y1,X2,Y2);// + + if (elDraw32::Initialized==FALSE) elDraw32::Init();// + + static HRESULT ddret; + static DDSURFACEDESC ddsd1,ddsd2; +// static LPWORD data1,data2; + static LPDWORD data1,data2;// + static long AddPitch1,AddPitch2; + static unsigned int x,y,Sx,Sy,Ex,Ey; +// static unsigned int Buff,R1,G1,B1,R2,G2,B2; + static unsigned int R1,G1,B1,R2,G2,B2;// + static float Bd; + + static elDraw32::Buff32 Buff1,Buff2; + static int RGB_R,RGB_G,RGB_B; + + // 描画領域の計算 + Sx=0; + Sy=0; + Ex=X2-X1; + Ey=Y2-Y1; + + if (Px+((int)Ex-(int)Sx)>Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch/2; +// AddPitch2=ddsd2.lPitch/2; + AddPitch1=ddsd1.lPitch/4;// + AddPitch2=ddsd2.lPitch/4;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // ブレンド値の算出 + Bd=F(1)-Blend; + + // データ転送 + // MMXを使わない場合 + if (!elDraw32::USE_MMX) + { + for (y=Sy;y>ShiftR)&BitR; +// G1=(Buff>>ShiftG)&BitG; +// B1=(Buff>>ShiftB)&BitB; + +// Buff=*(data2+x); + Buff2.Buff=*(data2+x);// + +// R2=(Buff>>ShiftR)&BitR; +// G2=(Buff>>ShiftG)&BitG; +// B2=(Buff>>ShiftB)&BitB; + +// R1=(unsigned int)(F(R1)*Blend+F(R2)*Bd); +// G1=(unsigned int)(F(G1)*Blend+F(G2)*Bd); +// B1=(unsigned int)(F(B1)*Blend+F(B2)*Bd); + Buff1.BuffRGB[RGB_R]=(unsigned char)(F(Buff1.BuffRGB[RGB_R])*Blend+F(Buff2.BuffRGB[RGB_R])*Bd);// + Buff1.BuffRGB[RGB_G]=(unsigned char)(F(Buff1.BuffRGB[RGB_G])*Blend+F(Buff2.BuffRGB[RGB_G])*Bd);// + Buff1.BuffRGB[RGB_B]=(unsigned char)(F(Buff1.BuffRGB[RGB_B])*Blend+F(Buff2.BuffRGB[RGB_B])*Bd);// + +// *(data2+x)=(R1<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch/2; +// AddPitch2=ddsd2.lPitch/2; + AddPitch1=ddsd1.lPitch/4;// + AddPitch2=ddsd2.lPitch/4;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // ブレンド値の算出 + BdR=F(1)-BlendR; + BdG=F(1)-BlendG; + BdB=F(1)-BlendB; + + // データ転送 + // MMXを使わない場合 + if (!elDraw32::USE_MMX) + { + for (y=Sy;y>ShiftR)&BitR; +// G1=(Buff>>ShiftG)&BitG; +// B1=(Buff>>ShiftB)&BitB; + +// Buff=*(data2+x); + Buff2.Buff=*(data2+x);// + +// R2=(Buff>>ShiftR)&BitR; +// G2=(Buff>>ShiftG)&BitG; +// B2=(Buff>>ShiftB)&BitB; + +// R1=(unsigned int)(F(R1)*BlendR+F(R2)*BdR); +// G1=(unsigned int)(F(G1)*BlendG+F(G2)*BdG); +// B1=(unsigned int)(F(B1)*BlendB+F(B2)*BdB); + Buff1.BuffRGB[RGB_R]=(unsigned char)(F(Buff1.BuffRGB[RGB_R])*BlendR+F(Buff2.BuffRGB[RGB_R])*BdR);// + Buff1.BuffRGB[RGB_G]=(unsigned char)(F(Buff1.BuffRGB[RGB_G])*BlendG+F(Buff2.BuffRGB[RGB_G])*BdG);// + Buff1.BuffRGB[RGB_B]=(unsigned char)(F(Buff1.BuffRGB[RGB_B])*BlendB+F(Buff2.BuffRGB[RGB_B])*BdB);// + +// *(data2+x)=(R1<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch/2; +// AddPitch2=ddsd2.lPitch/2; + AddPitch1=ddsd1.lPitch/4;// + AddPitch2=ddsd2.lPitch/4;// + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ブレンド値の算出 + Bd=(31-Blend)<<10; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // データ転送 + //MMXを使わない場合 + if (!elDraw32::USE_MMX) + { + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ブレンド値の算出 + Bd=((int)(F(31)-Blend*F(31)))<<10; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // データ転送 + if (!elDraw32::USE_MMX) // MMXを使わない場合 + { + for (y=Sy;y>ShiftR)&BitR; + R1=(R1<<16)+(R1<<8)+R1; + + BuffDest1=*(data2+x); + + #ifndef BCC + _asm + { + movd mm1,R1 // mm1レジスタの 0-31ビットに R1を入れる + movd mm0,BuffDest1 // mm0レジスタの 0-31ビットに BuffDest1を入れる + psubusb mm0,mm1 // サチュレーション(飽和)付きで mm0=mm0-mm1 の 演算をする (8ビット境界、unsigned) + pand mm0,mm7 // 念のためマスクをする + movd BuffDest1,mm0 // BuffDest1に mm0レジスタの 0-31ビットを入れる + } + #else // #ifndef BCC + MOVD_mm_mem(mm1,R1) // mm1レジスタの 0-31ビットに R1を入れる + MOVD_mm_mem(mm0,BuffDest1) // mm0レジスタの 0-31ビットに BuffDest1を入れる + PSUBUSB_mm_mm(mm0,mm1) // サチュレーション(飽和)付きで mm0=mm0-mm1 の 演算をする (8ビット境界、unsigned) + PAND_mm_mm(mm0,mm7) // 念のためマスクをする + MOVD_mem_mm(BuffDest1,mm0) // BuffDest1に mm0レジスタの 0-31ビットを入れる + #endif // #ifndef BCC + + *(data2+x)=BuffDest1; + } + } + + // Y方向に加算 + data1+=AddPitch1; + data2+=AddPitch2; + } + + EMMS + + } + + // スプライトのロック解除 + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + DD_UNLOCK(DDBack,ddsd2.lpSurface); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( エッジブレンド ) ※ フルカラー -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- : FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw32::EdgeBlendLayer(int Px,int Py,DDOBJ ObjDD,int X1,int Y1,int X2,int Y2) +{ + if (elSystem::ColorBit()<24) return elDraw::EdgeBlendLayer(Px,Py,ObjDD,X1,Y1,X2,Y2);// + + static HRESULT ddret; + static DDSURFACEDESC ddsd1,ddsd2; +// static LPWORD data1,data2; + static LPDWORD data1,data2;// + static long AddPitch1,AddPitch2; + static UINT x,y,Sx,Sy,Ex,Ey; +// static UINT Buff,Buff2,R,G,B; + static UINT R,G,B;// + static int Count; + + static union elDraw32::Buff32 Buff1,Buff2;// + static int RGB_R,RGB_G,RGB_B; + + // 描画領域の計算 + Sx=0; + Sy=0; + Ex=X2-X1; + Ey=Y2-Y1; + + if (Px+((int)Ex-(int)Sx)>Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // データ転送 + for (y=Sy;ySx && Buff2==0x0000) + if (x>Sx && Buff2.Buff==0x00000000)// + { +// Buff2=*(data2+x-1); + Buff2.Buff=*(data2+x-1);// + +// R+=GetRGB[Buff2].r; +// G+=GetRGB[Buff2].g; +// B+=GetRGB[Buff2].b; + R+=Buff2.BuffRGB[RGB_R];// + G+=Buff2.BuffRGB[RGB_G];// + B+=Buff2.BuffRGB[RGB_B];// + + Count++; + } + +// Buff2=*(data1+x+1); + Buff2.Buff=*(data1+x+1);// + +// if (xSy && Buff2==0x0000) + if (y>Sy && Buff2.Buff==0x00000000)// + { +// Buff2=*(data2+x-AddPitch2); + Buff2.Buff=*(data2+x-AddPitch2);// + +// R+=GetRGB[Buff2].r; +// G+=GetRGB[Buff2].g; +// B+=GetRGB[Buff2].b; + R+=Buff2.BuffRGB[RGB_R];// + G+=Buff2.BuffRGB[RGB_G];// + B+=Buff2.BuffRGB[RGB_B];// + + Count++; + } + +// Buff2=*(data1+x+AddPitch1); + Buff2.Buff=*(data1+x+AddPitch1);// + +// if (y1) + { +// R/=Count; +// G/=Count; +// B/=Count; + Buff2.BuffRGB[RGB_R]=R/Count;// + Buff2.BuffRGB[RGB_G]=G/Count;// + Buff2.BuffRGB[RGB_B]=B/Count;// + +// *(data2+x)=(R<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // マスクの作成 +// Color=0x0000; + Color=0x00000000;// + if (PlainR) Color|=MaskR; + if (PlainG) Color|=MaskG; + if (PlainB) Color|=MaskB; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える // + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch/2; +// AddPitch2=ddsd2.lPitch/2; + AddPitch1=ddsd1.lPitch/4;// + AddPitch2=ddsd2.lPitch/4;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // データ転送 + if (!elDraw32::USE_MMX) // MMXを使わない場合 + { + for (y=Sy;y>ShiftR)&BitR; +// G=(Buff>>ShiftG)&BitG; +// B=(Buff>>ShiftB)&BitB; + +// R=(unsigned int)(F(R)*Bright); +// G=(unsigned int)(F(G)*Bright); +// B=(unsigned int)(F(B)*Bright); + Buff.BuffRGB[RGB_R]=(unsigned char)(F(Buff.BuffRGB[RGB_R])*Bright);// + Buff.BuffRGB[RGB_G]=(unsigned char)(F(Buff.BuffRGB[RGB_G])*Bright);// + Buff.BuffRGB[RGB_B]=(unsigned char)(F(Buff.BuffRGB[RGB_B])*Bright);// + +// *(data2+x)=(R<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える // + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch/2; +// AddPitch2=ddsd2.lPitch/2; + AddPitch1=ddsd1.lPitch/4; + AddPitch2=ddsd2.lPitch/4; + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // データ転送 + if (!elDraw32::USE_MMX) // MMXを使わない場合 + { + for (y=Sy;y>ShiftR)&BitR; +// G=(Buff>>ShiftG)&BitG; +// B=(Buff>>ShiftB)&BitB; + +// R=(unsigned int)(F(R)*BrightR); +// G=(unsigned int)(F(G)*BrightG); +// B=(unsigned int)(F(B)*BrightB); + Buff.BuffRGB[RGB_R]=(unsigned char)(F(Buff.BuffRGB[RGB_R])*BrightR);// + Buff.BuffRGB[RGB_G]=(unsigned char)(F(Buff.BuffRGB[RGB_G])*BrightG);// + Buff.BuffRGB[RGB_B]=(unsigned char)(F(Buff.BuffRGB[RGB_B])*BrightB);// + +// *(data2+x)=(R<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える // + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2; + AddPitch2=ddsd2.lPitch>>2; + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // ブライト値の算出 +// Bt=31-Bright; + Bt=255-(int)(Bright<<3|Bright>>2);//5→8ビットに拡張 + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える // + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // ブライト値の算出 +// BtR=31-BrightR; +// BtG=31-BrightG; +// BtB=31-BrightB; + BtR=255-(int)(BrightR<<3|BrightR>>2);//5→8ビットに拡張 + BtG=255-(int)(BrightG<<3|BrightG>>2);//5→8ビットに拡張 + BtB=255-(int)(BrightB<<3|BrightB>>2);//5→8ビットに拡張 + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える // + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // ぼかし値の算出 + Sd=Shade*Shade; + + // データ転送 + for (y=Sy;yEy) + { + Sy2-=y+Ey2-Ey; + Ey2-=y+Ey2-Ey; + } + + for (x=Sx;xEx) + { + Sx2-=x+Ex2-Ex; + Ex2-=x+Ex2-Ex; + } + + if (Shade==2) + { +// Buff=*(data1+x+Sx2+Sy2*AddPitch1); + Buff.Buff=*(data1+x+Sx2+Sy2*AddPitch1);// + +// R+=GetRGB[Buff].r; +// G+=GetRGB[Buff].g; +// B+=GetRGB[Buff].b; + R+=Buff.BuffRGB[RGB_R];// + G+=Buff.BuffRGB[RGB_G];// + B+=Buff.BuffRGB[RGB_B];// + +// Buff=*(data1+x+Sx2+1+Sy2*AddPitch1); + Buff.Buff=*(data1+x+Sx2+1+Sy2*AddPitch1);// + +// R+=GetRGB[Buff].r; +// G+=GetRGB[Buff].g; +// B+=GetRGB[Buff].b; + R+=Buff.BuffRGB[RGB_R];// + G+=Buff.BuffRGB[RGB_G];// + B+=Buff.BuffRGB[RGB_B];// + +// Buff=*(data1+x+Sx2+(Sy2+1)*AddPitch1); + Buff.Buff=*(data1+x+Sx2+(Sy2+1)*AddPitch1);// + +// R+=GetRGB[Buff].r; +// G+=GetRGB[Buff].g; +// B+=GetRGB[Buff].b; + R+=Buff.BuffRGB[RGB_R];// + G+=Buff.BuffRGB[RGB_G];// + B+=Buff.BuffRGB[RGB_B];// + +// Buff=*(data1+x+Sx2+1+(Sy2+1)*AddPitch1); + Buff.Buff=*(data1+x+Sx2+1+(Sy2+1)*AddPitch1);// + +// R+=GetRGB[Buff].r; +// G+=GetRGB[Buff].g; +// B+=GetRGB[Buff].b; + R+=Buff.BuffRGB[RGB_R];// + G+=Buff.BuffRGB[RGB_G];// + B+=Buff.BuffRGB[RGB_B];// + + R>>=2; + G>>=2; + B>>=2; + } + else + { + for (xx=Sx2;xxVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える // + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // データ転送 + for (y=Sy;y=Vx1 && Px+Dx=Vy1 && Py+DyVx2) + { + Ex-=(Px1+Ex-Vx2); + } + + if (Py1+Ey>Vy2) + { + Ey-=(Py1+Ey-Vy2); + } + + if (Px1=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/2; +// data2=(LPWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/4; // + data2=(LPDWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/4; // + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // 回転の中心点を取得 + cx1=(Px2-Px1)>>1; + cy1=(Py2-Py1)>>1; + cx2=((Px2-Px1)-(X2-X1))>>1; + cy2=((Py2-Py1)-(Y2-Y1))>>1; +// tx1=cx1*360-cx1*RotateData[Angle+90]+cy1*RotateData[Angle]; +// ty1=cy1*360-cx1*RotateData[Angle]-cy1*RotateData[Angle+90]; + tx1=cx1*360-cx1*elDraw::RotateData[Angle+90]+cy1*elDraw::RotateData[Angle];// + ty1=cy1*360-cx1*elDraw::RotateData[Angle]-cy1*elDraw::RotateData[Angle+90];// + + for (y=0;y=0 && rx=0 && ry=Sx && x=Sy && yVx2) + { + Ex-=(Px1+Ex-Vx2); + } + + if (Py1+Ey>Vy2) + { + Ey-=(Py1+Ey-Vy2); + } + + if (Px1=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/2; +// data2=(LPWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/4;// + data2=(LPDWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/4;// + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // 回転の中心点を取得 + cx1=(Px2-Px1)>>1; + cy1=(Py2-Py1)>>1; + cx2=((Px2-Px1)-(X2-X1))>>1; + cy2=((Py2-Py1)-(Y2-Y1))>>1; +// tx1=cx1*360-cx1*RotateData[Angle+90]+cy1*RotateData[Angle]; +// ty1=cy1*360-cx1*RotateData[Angle]-cy1*RotateData[Angle+90]; + tx1=cx1*360-cx1*elDraw::RotateData[Angle+90]+cy1*elDraw::RotateData[Angle];// + ty1=cy1*360-cx1*elDraw::RotateData[Angle]-cy1*elDraw::RotateData[Angle+90];// + + for (y=0;y=Sx && x=Sy && yVx2) + { + Ex-=(Px1+Ex-Vx2); + } + + if (Py1+Ey>Vy2) + { + Ey-=(Py1+Ey-Vy2); + } + + if (Px1=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/2; +// data2=(LPWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/4;// + data2=(LPDWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/4;// + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // 回転の中心点を取得 + cx1=(Px2-Px1)>>1; + cy1=(Py2-Py1)>>1; + cx2=((Px2-Px1)-(X2-X1))>>1; + cy2=((Py2-Py1)-(Y2-Y1))>>1; +// tx1=cx1*360-cx1*RotateData[Angle+90]+cy1*RotateData[Angle]; +// ty1=cy1*360-cx1*RotateData[Angle]-cy1*RotateData[Angle+90]; + tx1=cx1*360-cx1*elDraw::RotateData[Angle+90]+cy1*elDraw::RotateData[Angle];// + ty1=cy1*360-cx1*elDraw::RotateData[Angle]-cy1*elDraw::RotateData[Angle+90];// + + for (y=0;y=0 && rx=0 && ry=Sx && x=Sy && yVx2) + { + Ex-=(Px1+Ex-Vx2); + } + + if (Py1+Ey>Vy2) + { + Ey-=(Py1+Ey-Vy2); + } + + if (Px1=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/2; +// data2=(LPWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/4;// + data2=(LPDWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/4;// + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // 回転の中心点を取得 + cx1=(Px2-Px1)>>1; + cy1=(Py2-Py1)>>1; + cx2=((Px2-Px1)-(X2-X1))>>1; + cy2=((Py2-Py1)-(Y2-Y1))>>1; +// tx1=cx1*360-cx1*RotateData[Angle+90]+cy1*RotateData[Angle]; +// ty1=cy1*360-cx1*RotateData[Angle]-cy1*RotateData[Angle+90]; + tx1=cx1*360-cx1*elDraw::RotateData[Angle+90]+cy1*elDraw::RotateData[Angle];// + ty1=cy1*360-cx1*elDraw::RotateData[Angle]-cy1*elDraw::RotateData[Angle+90];// + + for (y=0;y=Sx && x=Sy && yVx2) + { + Ex-=(Px1+Ex-Vx2); + } + + if (Py1+Ey>Vy2) + { + Ey-=(Py1+Ey-Vy2); + } + + if (Px1=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える // + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/2; +// data2=(LPWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/4;// + data2=(LPDWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/4;// + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2; + AddPitch2=ddsd2.lPitch>>2; + + // 回転の中心点を取得 + cx1=(Px2-Px1)>>1; + cy1=(Py2-Py1)>>1; + cx2=((Px2-Px1)-(X2-X1))>>1; + cy2=((Py2-Py1)-(Y2-Y1))>>1; +// tx1=cx1*360-cx1*RotateData[Angle+90]+cy1*RotateData[Angle]; +// ty1=cy1*360-cx1*RotateData[Angle]-cy1*RotateData[Angle+90]; + tx1=cx1*360-cx1*elDraw::RotateData[Angle+90]+cy1*elDraw::RotateData[Angle];// + ty1=cy1*360-cx1*elDraw::RotateData[Angle]-cy1*elDraw::RotateData[Angle+90];// + + // 拡大率の初期化 + ZoomX=ZoomStartX; + ZoomY=ZoomStartY; + + for (y=0;y=Sx && x=Sy && yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2; + AddPitch2=ddsd2.lPitch>>2; + + if (Mode==PICK_LEFT) + { + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える // + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // シフト値の算出 + St=(int)(F(31)-Shift*F(31)); + + // データ転送 + for (y=Sy;y>=3;// + +// if ((int)Buff-St>0) + if ((int)Buff.BuffRGB[RGB_R]-St>0)// + { +// Buff-=St; + Buff.BuffRGB[RGB_R]-=St;// + } + else + { +// Buff=0; + Buff.BuffRGB[RGB_R]=0;// + } + +// if (Buff>=Ey-y) Buff=0; + if (Buff.BuffRGB[RGB_R]>=Ey-y) Buff.BuffRGB[RGB_R]=0;// + +// *(data2+x)=*(data2+x+Buff*AddPitch2); + *(data2+x)=*(data2+x+Buff.BuffRGB[RGB_R]*AddPitch2);// + } + } + + // Y方向に加算 + data1+=AddPitch1; + data2+=AddPitch2; + } + + // スプライトのロック解除 + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + DD_UNLOCK(DDBack,ddsd2.lpSurface); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( トンネル ) ※ フルカラー -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- int Rotate : 回転 ( 0 〜 スプライトのXサイズ ) -*/ +/*- int Dist : 距離 ( 0 〜 スプライトのYサイズ ) -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- : FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw32::TunnelLayer(int Px,int Py,int Rotate,int Dist,DDOBJ ObjDD) +{ + if (elSystem::ColorBit()<24) return elDraw::TunnelLayer(Px,Py,Rotate,Dist,ObjDD);// + + static HRESULT ddret; + static DDSURFACEDESC ddsd1,ddsd2; +// static LPWORD data1,data2; + static LPDWORD data1,data2;// + static long AddPitch1,AddPitch2; + static int x,y,y2; + static UINT Buff; + static int Gx,Gy; + + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface; + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 +// for (y=0,y2=0;y=TunnelSpriteX) Gx-=TunnelSpriteX; +// if (Gy>=TunnelSpriteY) Gy-=TunnelSpriteY; + if (Gx>=elDraw::TunnelSpriteX) Gx-=elDraw::TunnelSpriteX;// + if (Gy>=elDraw::TunnelSpriteY) Gy-=elDraw::TunnelSpriteY;// + + *(data2+x)=*(data1+Gx+Gy*AddPitch1); + } + + // Y方向に加算 + data2+=AddPitch2; + } + + // スプライトのロック解除 + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + DD_UNLOCK(DDBack,ddsd2.lpSurface); + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( ライト ) ※ フルカラー -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- int Red : 赤の減退 ( 0〜 ) -*/ +/*- int Green : 緑の減退 ( 0〜 ) -*/ +/*- int Blue : 青の減退 ( 0〜 ) -*/ +/*- WORD Dir : 光の方向 -*/ +/*- ( CREATE_DIR(左下,下,右下,左,右,左上,上,右上)で指定 ) -*/ +/*- BOOL Show : スプライトの表示 -*/ +/*- TRUE = スプライトとライトを表示 -*/ +/*- FALSE = ライトのみ表示 -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- : FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw32::LightLayer(int Px,int Py,int Red,int Green,int Blue,WORD Dir, + BOOL Show,DDOBJ ObjDD,int X1,int Y1,int X2,int Y2) +{ + if (elSystem::ColorBit()<24) return elDraw::LightLayer(Px,Py,Red,Green,Blue,Dir, + Show,ObjDD,X1,Y1,X2,Y2); + + static HRESULT ddret; + static DDSURFACEDESC ddsd1,ddsd2; +// static LPWORD data1,data2,data3,data4; + static LPDWORD data1,data2,data3,data4;// + static long AddPitch1,AddPitch2; + static UINT i,x,y,Sx,Sy,Ex,Ey; +// static UINT Buff,Buff2; + static UINT R,G,B,R2,G2,B2; + static int Count=0; + + static union elDraw32::Buff32 Buff,Buff2;// + static int RGB_R,RGB_G,RGB_B;// + + // 描画領域の計算 + Sx=0; + Sy=0; + Ex=X2-X1; + Ey=Y2-Y1; + + if (Px+((int)Ex-(int)Sx)>Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える // + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // データ転送 + for (y=Sy;y>=Red; + G>>=Green; + B>>=Blue; + +// i=elEffect::FireRandomList[Count]; + i=(rand()%3)*8; + if (++Count==10000) Count=0; + + if (R>=i) + { + R-=i; + } + else + { + R=0; + } + + if (G>=i) + { + G-=i; + } + else + { + G=0; + } + + if (B>=i) + { + B-=i; + } + else + { + B=0; + } + + data3=data2; + data4=data2; + + for (i=0;i<31;i++) + { +// if (R) R--; +// if (G) G--; +// if (B) B--; + if (((int)R-8)>=0) R-=8; else R=0;// + if (((int)G-8)>=0) G-=8; else G=0;// + if (((int)B-8)>=0) B-=8; else B=0;// + +// if (R+G+B==0x0000) break; + if (R+G+B==0x0000) break;// + +// if ((int)(Py+y)-(int)i>=Vy1) + if ((int)(Py+y)-(int)i>Vy1) //??i>Vy1 にするとアクセス違反がなくなる。el.hのバグ?? + { + data3-=AddPitch2; + + if (Dir&0x40) + { +// Buff=*(data3+x); + Buff.Buff=*(data3+x);// + +// R2=R+GetRGB[Buff].r; +// G2=G+GetRGB[Buff].g; +// B2=B+GetRGB[Buff].b; + R2=R+Buff.BuffRGB[RGB_R];// + G2=G+Buff.BuffRGB[RGB_G];// + B2=B+Buff.BuffRGB[RGB_B];// + +// if (R2>31) R2=31; +// if (G2>31) G2=31; +// if (B2>31) B2=31; + if (R2>255) R2=255;// + if (G2>255) G2=255;// + if (B2>255) B2=255;// + +// *(data3+x)=(R2<=Vx1) + { +// Buff=*(data3+x-i); + Buff.Buff=*(data3+x-i);// + +// R2=R+GetRGB[Buff].r; +// G2=G+GetRGB[Buff].g; +// B2=B+GetRGB[Buff].b; + R2=R+Buff.BuffRGB[RGB_R];// + G2=G+Buff.BuffRGB[RGB_G];// + B2=B+Buff.BuffRGB[RGB_B];// + +// if (R2>31) R2=31; +// if (G2>31) G2=31; +// if (B2>31) B2=31; + if (R2>255) R2=255;// + if (G2>255) G2=255;// + if (B2>255) B2=255;// + +// *(data3+x-i)=(R2<31) R2=31; +// if (G2>31) G2=31; +// if (B2>31) B2=31; + if (R2>255) R2=255;// + if (G2>255) G2=255;// + if (B2>255) B2=255;// + +// *(data3+x+i)=(R2<31) R2=31; +// if (G2>31) G2=31; +// if (B2>31) B2=31; + if (R2>255) R2=255;// + if (G2>255) G2=255;// + if (B2>255) B2=255;// + +// *(data4+x)=(R2<=Vx1) + { +// Buff=*(data4+x-i); + Buff.Buff=*(data4+x-i);// + +// R2=R+GetRGB[Buff].r; +// G2=G+GetRGB[Buff].g; +// B2=B+GetRGB[Buff].b; + R2=R+Buff.BuffRGB[RGB_R];// + G2=G+Buff.BuffRGB[RGB_G];// + B2=B+Buff.BuffRGB[RGB_B];// + +// if (R2>31) R2=31; +// if (G2>31) G2=31; +// if (B2>31) B2=31; + if (R2>255) R2=255;// + if (G2>255) G2=255;// + if (B2>255) B2=255;// + +// *(data4+x-i)=(R2<31) R2=31; +// if (G2>31) G2=31; +// if (B2>31) B2=31; + if (R2>255) R2=255;// + if (G2>255) G2=255;// + if (B2>255) B2=255;// + +// *(data4+x+i)=(R2<=Vx1) + { +// Buff=*(data2+x-i); + Buff.Buff=*(data2+x-i);// + +// R2=R+GetRGB[Buff].r; +// G2=G+GetRGB[Buff].g; +// B2=B+GetRGB[Buff].b; + R2=R+Buff.BuffRGB[RGB_R];// + G2=G+Buff.BuffRGB[RGB_G];// + B2=B+Buff.BuffRGB[RGB_B];// + +// if (R2>31) R2=31; +// if (G2>31) G2=31; +// if (B2>31) B2=31; + if (R2>255) R2=255;// + if (G2>255) G2=255;// + if (B2>255) B2=255;// + +// *(data2+x-i)=(R2<31) R2=31; +// if (G2>31) G2=31; +// if (B2>31) B2=31; + if (R2>255) R2=255;// + if (G2>255) G2=255;// + if (B2>255) B2=255;// + +// *(data2+x+i)=(R2<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch/2; + AddPitch2=ddsd2.lPitch/2; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ブレンド値の算出 + Bd=F(1)-Blend; + + // データ転送 + // MMXを使う場合 + static unsigned __int32 Blend32; + static unsigned __int32 Bd32; + static unsigned __int64 ONE; + static unsigned __int64 MaskBit64; + static unsigned __int32 BuffSrc1; // MMXを使う時のバッファ Srcは転送元 + static unsigned __int32 BuffDest1; // Destは転送先 + + //↓ホントは 0x10000 にしたいんだけど、16ビット以内、符号付きでないといけないので、やむなくその最大値(==0x7fff)を使う + Blend32=((unsigned __int32)((float)0x7fff*(float)Blend)); // ブレンド値を整数にする + Bd32=((unsigned __int32)((float)0x7fff*(float)Bd)); // ブレンド値を整数にする + + EMMS // 浮動小数点レジスタをクリアする + + #ifndef BCC + _asm movd mm2,Blend32 // mm2レジスタに転送元のブレンド値を入れる + _asm punpcklwd mm2,Blend32 // mm2レジスタの 0-31ビットにブレンド値(計2つ)を入れる + _asm punpckldq mm2,mm2 // mm2レジスタの 0-63ビットにブレンド値(計4つ)を入れる + _asm movd mm3,Bd32 // mm3レジスタに転送先のブレンド値を入れる + _asm punpcklwd mm3,Bd32 // mm3レジスタの 0-31ビットにブレンド値(計2つ)を入れる + _asm punpckldq mm3,mm3 // mm3レジスタの 0-63ビットにブレンド値(計4つ)を入れる + _asm pxor mm7,mm7 // mm7を 0にクリアする + ONE=0x0000000100010001; // 四捨五入に使う + _asm movq mm6,ONE // mm6レジスタに ONEを入れる + MaskBit64=0x0000ffffffffffff; // マスク用データ + _asm movq mm5,MaskBit64 // mm5 レジスタに MaskBit64を入れる + #else // #ifndef BCC + MOVD_mm_mem(mm2,Blend32) // mm2レジスタに転送元のブレンド値を入れる + PUNPCKLWD_mm_mem(mm2,Blend32) // mm2レジスタの 0-31ビットにブレンド値(計2つ)を入れる + PUNPCKLDQ_mm_mm(mm2,mm2) // mm2レジスタの 0-63ビットにブレンド値(計4つ)を入れる + MOVD_mm_mem(mm3,Bd32) // mm3レジスタに転送先のブレンド値を入れる + PUNPCKLWD_mm_mem(mm3,Bd32) // mm3レジスタの 0-31ビットにブレンド値(計2つ)を入れる + PUNPCKLDQ_mm_mm(mm3,mm3) // mm3レジスタの 0-63ビットにブレンド値(計4つ)を入れる + PXOR_mm_mm(mm7,mm7) // mm7を 0にクリアする + ONE=0x0000000100010001; // 四捨五入に使う + MOVQ_mm_mem(mm6,ONE) // mm6レジスタに ONEを入れる + MaskBit64=0x0000ffffffffffff; // マスク用データ + MOVQ_mm_mem(mm5,MaskBit64) // mm5 レジスタに MaskBit64を入れる + #endif // #ifndef BCC + + // データ転送 + for (y=Sy;y>ShiftR)&BitR; + Buff1.BuffRGB[1]=(Buff>>ShiftG)&BitG; + Buff1.BuffRGB[2]=(Buff>>ShiftB)&BitB; + + Buff=*(data2+x); + + Buff2.BuffRGB[0]=(Buff>>ShiftR)&BitR; + Buff2.BuffRGB[1]=(Buff>>ShiftG)&BitG; + Buff2.BuffRGB[2]=(Buff>>ShiftB)&BitB; + + #ifndef BCC + _asm + { + movd mm0,Buff1.Buff // mm0レジスタの 0-31ビットに Buff1を入れる + punpcklbw mm0,mm7 // 0x00と画像データを1バイトづつ交互に入れる(これで画像データの R・G・B それぞれがバイト値からワード値になる) + paddw mm0,mm0 // 倍にする(ブレンド値が半分になっているので こっちを倍にするのと、四捨五入をしたいため) + paddw mm0,mm6 // RGBそれぞれに1を足す(四捨五入のため) + pmulhw mm0,mm2 // 掛け算(出てくる答は 計算結果の 32ビットのうち 上位16ビット) + + movd mm1,Buff2.Buff // mm1レジスタの 0-31ビットに Buff2を入れる + punpcklbw mm1,mm7 // 0x00と画像データを1バイトづつ交互に入れる(これで画像データの R・G・B それぞれがバイト値からワード値になる) + paddw mm1,mm1 // 倍にする(ブレンド値が半分になっているので こっちを倍にするのと、四捨五入をしたいため) + paddw mm1,mm6 // RGBそれぞれに1を足す(四捨五入のため) + pmulhw mm1,mm3 // 掛け算(出てくる答は 計算結果の 32ビットのうち 上位16ビット) + + paddusw mm0,mm1 // mm0レジスタと mm1レジスタを足す +// pand mm0,mm5 // マスクをする(必要なし?) + packuswb mm0,mm7 // mm0レジスタの 0-31ビットに RGB値を取り出す(ワード値をバイト値にもどす。mm7はダミー) + + movd Buff1.Buff,mm0 // BuffDest1に mm0レジスタの 0-31ビットを入れる + } + #else // #ifndef BCC + MOVD_mm_mem(mm0,Buff1.Buff) // mm0レジスタの 0-31ビットに Buff1を入れる + PUNPCKLBW_mm_mm(mm0,mm7) // 0x00と画像データを1バイトづつ交互に入れる(これで画像データの R・G・B それぞれがバイト値からワード値になる) + PADDW_mm_mm(mm0,mm0) // 倍にする(ブレンド値が半分になっているので こっちを倍にするのと、四捨五入をしたいため) + PADDW_mm_mm(mm0,mm6) // RGBそれぞれに1を足す(四捨五入のため) + PMULHW_mm_mm(mm0,mm2) // 掛け算(出てくる答は 計算結果の 32ビットのうち 上位16ビット) + + MOVD_mm_mem(mm1,Buff2.Buff) // mm1レジスタの 0-31ビットに Buff2を入れる + PUNPCKLBW_mm_mm(mm1,mm7) // 0x00と画像データを1バイトづつ交互に入れる(これで画像データの R・G・B それぞれがバイト値からワード値になる) + PADDW_mm_mm(mm1,mm1) // 倍にする(ブレンド値が半分になっているので こっちを倍にするのと、四捨五入をしたいため) + PADDW_mm_mm(mm1,mm6) // RGBそれぞれに1を足す(四捨五入のため) + PMULHW_mm_mm(mm1,mm3) // 掛け算(出てくる答は 計算結果の 32ビットのうち 上位16ビット) + + PADDUSW_mm_mm(mm0,mm1) // mm0レジスタと mm1レジスタを足す +// PAND_mm_mm(mm0,mm5) // マスクをする(必要なし?) + PACKUSWB_mm_mm(mm0,mm7) // mm0レジスタの 0-31ビットに RGB値を取り出す(ワード値をバイト値にもどす。mm7はダミー) + + MOVD_mem_mm(Buff1.Buff,mm0) // BuffDest1に mm0レジスタの 0-31ビットを入れる + #endif // #ifndef BCC + + *(data2+x)=(Buff1.BuffRGB[0]<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch/2; + AddPitch2=ddsd2.lPitch/2; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // ブレンド値の算出 + BdR=F(1)-BlendR; + BdG=F(1)-BlendG; + BdB=F(1)-BlendB; + + // データ転送 + // MMXを使う場合 + static unsigned __int32 Blend32R,Blend32G,Blend32B; + static unsigned __int32 Bd32R,Bd32G,Bd32B; + static unsigned __int64 Blend64,Bd64; + static unsigned __int64 ONE; + static unsigned __int64 MaskBit64; + + //↓ホントは 0x10000 にしたいんだけど、16ビット以内、符号付きでないといけないので、やむなくその最大値(==0x7fff)を使う + Blend32R=((unsigned __int32)((float)0x7fff*(float)BlendR)); // ブレンド値を整数にする + Blend32G=((unsigned __int32)((float)0x7fff*(float)BlendG)); // ブレンド値を整数にする + Blend32B=((unsigned __int32)((float)0x7fff*(float)BlendB)); // ブレンド値を整数にする + Blend64=(unsigned __int64)Blend32R|(unsigned __int64)Blend32G<<16|(unsigned __int64)Blend32B<<32; // ブレンド値を64ビットに入れる + Bd32R=((unsigned __int32)((float)0x7fff*(float)BdR)); // ブレンド値を整数にする + Bd32G=((unsigned __int32)((float)0x7fff*(float)BdG)); // ブレンド値を整数にする + Bd32B=((unsigned __int32)((float)0x7fff*(float)BdB)); // ブレンド値を整数にする + Bd64=(unsigned __int64)Bd32R|(unsigned __int64)Bd32G<<16|(unsigned __int64)Bd32B<<32; // ブレンド値を64ビットに入れる + + EMMS // 浮動小数点レジスタをクリアする + + #ifndef BCC + _asm movq mm2,Blend64 // mm2レジスタに転送元のブレンド値を入れる + _asm movq mm3,Bd64 // mm3レジスタに転送先のブレンド値を入れる + _asm pxor mm7,mm7 // mm7を 0にクリアする + ONE=0x0000000100010001; // 四捨五入に使う + _asm movq mm6,ONE // mm6レジスタに ONEを入れる + MaskBit64=0x0000ffffffffffff; // マスク用データ + _asm movq mm5,MaskBit64 // mm5 レジスタに MaskBit64を入れる + #else // #ifndef BCC + MOVQ_mm_mem(mm2,Blend64) // mm2レジスタに転送元のブレンド値を入れる + MOVQ_mm_mem(mm3,Bd64) // mm3レジスタに転送先のブレンド値を入れる + PXOR_mm_mm(mm7,mm7) // mm7を 0にクリアする + ONE=0x0000000100010001; // 四捨五入に使う + MOVQ_mm_mem(mm6,ONE) // mm6レジスタに ONEを入れる + MaskBit64=0x0000ffffffffffff; // マスク用データ + MOVQ_mm_mem(mm5,MaskBit64) // mm5 レジスタに MaskBit64を入れる + #endif // #ifndef BCC + + // データ転送 + for (y=Sy;y>ShiftR)&BitR; + Buff1.BuffRGB[1]=(Buff>>ShiftG)&BitG; + Buff1.BuffRGB[2]=(Buff>>ShiftB)&BitB; + + Buff=*(data2+x); + + Buff2.BuffRGB[0]=(Buff>>ShiftR)&BitR; + Buff2.BuffRGB[1]=(Buff>>ShiftG)&BitG; + Buff2.BuffRGB[2]=(Buff>>ShiftB)&BitB; + + #ifndef BCC + _asm + { + movd mm0,Buff1.Buff // mm0レジスタの 0-31ビットに Buff1.Buffを入れる + punpcklbw mm0,mm7 // 0x00と画像データを1バイトづつ交互に入れる(これで画像データの R・G・B それぞれがバイト値からワード値になる) + paddw mm0,mm0 // 倍にする(ブレンド値が半分になっているので こっちを倍にするのと、四捨五入をしたいため) + paddw mm0,mm6 // RGBそれぞれに1を足す(四捨五入のため) + pmulhw mm0,mm2 // 掛け算(出てくる答は 計算結果の 32ビットのうち 上位16ビット) + + movd mm1,Buff2.Buff // mm1レジスタの 0-31ビットに Buff2.Buffを入れる + punpcklbw mm1,mm7 // 0x00と画像データを1バイトづつ交互に入れる(これで画像データの R・G・B それぞれがバイト値からワード値になる) + paddw mm1,mm1 // 倍にする(ブレンド値が半分になっているので こっちを倍にするのと、四捨五入をしたいため) + paddw mm1,mm6 // RGBそれぞれに1を足す(四捨五入のため) + pmulhw mm1,mm3 // 掛け算(出てくる答は 計算結果の 32ビットのうち 上位16ビット) + + paddusw mm0,mm1 // mm0レジスタと mm1レジスタを足す +// pand mm0,mm5 // マスクをする(必要なし?) + packuswb mm0,mm7 // mm0レジスタの 0-31ビットに RGB値を取り出す(ワード値をバイト値にもどす。mm7はダミー) + + movd Buff1.Buff,mm0 // Buff1.Buffに mm0レジスタの 0-31ビットを入れる + } + #else // #ifndef BCC + MOVD_mm_mem(mm0,Buff1.Buff) // mm0レジスタの 0-31ビットに Buff1.Buffを入れる + PUNPCKLBW_mm_mm(mm0,mm7) // 0x00と画像データを1バイトづつ交互に入れる(これで画像データの R・G・B それぞれがバイト値からワード値になる) + PADDW_mm_mm(mm0,mm0) // 倍にする(ブレンド値が半分になっているので こっちを倍にするのと、四捨五入をしたいため) + PADDW_mm_mm(mm0,mm6) // RGBそれぞれに1を足す(四捨五入のため) + PMULHW_mm_mm(mm0,mm2) // 掛け算(出てくる答は 計算結果の 32ビットのうち 上位16ビット) + + MOVD_mm_mem(mm1,Buff2.Buff) // mm1レジスタの 0-31ビットに Buff2.Buffを入れる + PUNPCKLBW_mm_mm(mm1,mm7) // 0x00と画像データを1バイトづつ交互に入れる(これで画像データの R・G・B それぞれがバイト値からワード値になる) + PADDW_mm_mm(mm1,mm1) // 倍にする(ブレンド値が半分になっているので こっちを倍にするのと、四捨五入をしたいため) + PADDW_mm_mm(mm1,mm6) // RGBそれぞれに1を足す(四捨五入のため) + PMULHW_mm_mm(mm1,mm3) // 掛け算(出てくる答は 計算結果の 32ビットのうち 上位16ビット) + + PADDUSW_mm_mm(mm0,mm1) // mm0レジスタと mm1レジスタを足す +// PAND_mm_mm(mm0,mm5) // マスクをする(必要なし?) + PACKUSWB_mm_mm(mm0,mm7) // mm0レジスタの 0-31ビットに RGB値を取り出す(ワード値をバイト値にもどす。mm7はダミー) + + MOVD_mem_mm(Buff1.Buff,mm0) // Buff1.Buffに mm0レジスタの 0-31ビットを入れる + #endif // #ifndef BCC + + *(data2+x)=(Buff1.BuffRGB[0]<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch/2; + AddPitch2=ddsd2.lPitch/2; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + // MMXを使う場合 + static unsigned __int32 Bright32; + static unsigned __int64 ONE; + static unsigned __int64 MaskBit64; + + //↓ホントは 0x10000 にしたいんだけど、16ビット以内、符号付きでないといけないので、やむなくその最大値(==0x7fff)を使う + Bright32=((unsigned __int32)((float)0x7fff*(float)Bright)); // 明度値を整数にする + + EMMS + + #ifndef BCC + _asm movd mm1,Bright32 // mm1レジスタに明度値を入れる + _asm punpcklwd mm1,Bright32 // mm1レジスタの 0-31ビットに明度値(2つ)を入れる + _asm punpckldq mm1,mm1 // mm1レジスタの 0-63ビットに明度値(4つ)を入れる + _asm pxor mm7,mm7 // mm7を 0にクリアする + ONE=0x0000000100010001; // 四捨五入に使う + _asm movq mm6,ONE // mm6レジスタに ONEを入れる + MaskBit64=0x0000ffffffffffff; // マスク用データ + _asm movq mm5,MaskBit64 // mm5レジスタにMaskBit64を入れる + #else // #ifndef BCC + MOVD_mm_mem(mm1,Bright32) // mm1レジスタに明度値を入れる + PUNPCKLWD_mm_mem(mm1,Bright32) // mm1レジスタの 0-31ビットに明度値(2つ)を入れる + PUNPCKLDQ_mm_mm(mm1,mm1) // mm1レジスタの 0-63ビットに明度値(4つ)を入れる + PXOR_mm_mm(mm7,mm7) // mm7を 0にクリアする + ONE=0x0000000100010001; // 四捨五入に使う + MOVQ_mm_mem(mm6,ONE) // mm6レジスタに ONEを入れる + MaskBit64=0x0000ffffffffffff; // マスク用データ + MOVQ_mm_mem(mm5,MaskBit64) // mm5レジスタにMaskBit64を入れる + #endif // #ifndef BCC + + for (y=Sy;y>ShiftR)&BitR; + Buff2.BuffRGB[1]=(Buff1>>ShiftG)&BitG; + Buff2.BuffRGB[2]=(Buff1>>ShiftB)&BitB; + + #ifndef BCC + _asm + { + movd mm0,Buff2.Buff // mm0レジスタの 0-31ビットに Buff2.Buffを入れる + punpcklbw mm0,mm7 // 0x00と画像データを1バイトづつ交互に入れる(これで画像データの R・G・B それぞれがバイト値からワード値になる) + paddw mm0,mm0 // 倍にする(明度値が半分になっているので こっちを倍にするのと、四捨五入をするため) + paddw mm0,mm6 // 1を足す(四捨五入のため) + + pmulhw mm0,mm1 // 掛け算(出てくるのは 計算結果の 32ビットのうち 上位16ビット) +// pand mm0,mm5 // マスクをする(必要なし?) + packuswb mm0,mm7 // mm0レジスタの 0-31ビットに RGB値を取り出す(mm7はダミー) + + movd Buff2.Buff,mm0 // Buff2.Buffに mm0レジスタの 0-31ビットを入れる + } + #else // #ifndef BCC + MOVD_mm_mem(mm0,Buff2.Buff) // mm0レジスタの 0-31ビットに Buff2.Buffを入れる + PUNPCKLBW_mm_mm(mm0,mm7) // 0x00と画像データを1バイトづつ交互に入れる(これで画像データの R・G・B それぞれがバイト値からワード値になる) + PADDW_mm_mm(mm0,mm0) // 倍にする(明度値が半分になっているので こっちを倍にするのと、四捨五入をするため) + PADDW_mm_mm(mm0,mm6) // 1を足す(四捨五入のため) + + PMULHW_mm_mm(mm0,mm1) // 掛け算(出てくるのは 計算結果の 32ビットのうち 上位16ビット) +// PAND_mm_mm(mm0,mm5) // マスクをする(必要なし?) + PACKUSWB_mm_mm(mm0,mm7) // mm0レジスタの 0-31ビットに RGB値を取り出す(mm7はダミー) + + MOVD_mem_mm(Buff2.Buff,mm0) // Buff2.Buffに mm0レジスタの 0-31ビットを入れる + #endif // #ifndef BCC + + *(data2+x)=(Buff2.BuffRGB[0]<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch/2; + AddPitch2=ddsd2.lPitch/2; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + // MMXを使う場合 + static unsigned __int32 Bright32R,Bright32G,Bright32B; + static unsigned __int64 Bright64; + static unsigned __int64 ONE; + static unsigned __int64 MaskBit64; + + //↓ホントは 0x10000 にしたいんだけど、16ビット以内、符号付きでないといけないので、やむなくその最大値(==0x7fff)を使う + Bright32R=((unsigned __int32)((float)0x7fff*(float)BrightR)); // 明度値を整数にする + Bright32G=((unsigned __int32)((float)0x7fff*(float)BrightG)); // 明度値を整数にする + Bright32B=((unsigned __int32)((float)0x7fff*(float)BrightB)); // 明度値を整数にする + Bright64=(unsigned __int64)Bright32R|(unsigned __int64)Bright32G<<16|(unsigned __int64)Bright32B<<32; // 明度値を64ビットに入れる + + EMMS // 浮動小数点レジスタをクリアする + + #ifndef BCC + _asm movq mm2,Bright64 // mm2レジスタに明度値を入れる + _asm pxor mm7,mm7 // mm7を 0にクリアする + ONE=0x0000000100010001; // 四捨五入に使う + _asm movq mm6,ONE // mm6レジスタに ONEを入れる + MaskBit64=0x0000ffffffffffff; // マスク用データ + _asm movq mm5,MaskBit64 // mm5 レジスタに MaskBit64を入れる + #else // #ifndef BCC + MOVQ_mm_mem(mm2,Bright64) // mm2レジスタに明度値を入れる + PXOR_mm_mm(mm7,mm7) // mm7を 0にクリアする + ONE=0x0000000100010001; // 四捨五入に使う + MOVQ_mm_mem(mm6,ONE) // mm6レジスタに ONEを入れる + MaskBit64=0x0000ffffffffffff; // マスク用データ + MOVQ_mm_mem(mm5,MaskBit64) // mm5 レジスタに MaskBit64を入れる + #endif // #ifndef BCC + + for (y=Sy;y>ShiftR)&BitR; + Buff2.BuffRGB[1]=(Buff1>>ShiftG)&BitG; + Buff2.BuffRGB[2]=(Buff1>>ShiftB)&BitB; + + #ifndef BCC + _asm + { + movd mm0,Buff2.Buff // mm0レジスタの 0-31ビットに Buff2.Buffを入れる + punpcklbw mm0,mm7 // 0x00と画像データを1バイトづつ交互に入れる(これで画像データの R・G・B それぞれがバイト値からワード値になる) + paddw mm0,mm0 // 倍にする(明度値が半分になっているので こっちを倍にするのと、四捨五入をしたいため) + paddw mm0,mm6 // RGBそれぞれに1を足す(四捨五入のため) + pmulhw mm0,mm2 // 掛け算(出てくる答は 計算結果の 32ビットのうち 上位16ビット) + +// pand mm0,mm5 // マスクをする(必要なし?) + packuswb mm0,mm7 // mm0レジスタの 0-31ビットに RGB値を取り出す(ワード値をバイト値にもどす。mm7はダミー) + + movd Buff2.Buff,mm0 // Buff2.Buffに mm0レジスタの 0-31ビットを入れる + } + #else // #ifndef BCC + MOVD_mm_mem(mm0,Buff2.Buff) // mm0レジスタの 0-31ビットに Buff2.Buffを入れる + PUNPCKLBW_mm_mm(mm0,mm7) // 0x00と画像データを1バイトづつ交互に入れる(これで画像データの R・G・B それぞれがバイト値からワード値になる) + PADDW_mm_mm(mm0,mm0) // 倍にする(明度値が半分になっているので こっちを倍にするのと、四捨五入をしたいため) + PADDW_mm_mm(mm0,mm6) // RGBそれぞれに1を足す(四捨五入のため) + PMULHW_mm_mm(mm0,mm2) // 掛け算(出てくる答は 計算結果の 32ビットのうち 上位16ビット) + +// PAND_mm_mm(mm0,mm5) // マスクをする(必要なし?) + PACKUSWB_mm_mm(mm0,mm7) // mm0レジスタの 0-31ビットに RGB値を取り出す(ワード値をバイト値にもどす。mm7はダミー) + + MOVD_mem_mm(Buff2.Buff,mm0) // Buff2.Buffに mm0レジスタの 0-31ビットを入れる + #endif // #ifndef BCC + + *(data2+x)=(Buff2.BuffRGB[0]<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える // + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // データ転送 + if (!USE_MMX) // MMXを使わない場合 + { + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える // + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch>>1; +// AddPitch2=ddsd2.lPitch>>1; + AddPitch1=ddsd1.lPitch>>2;// + AddPitch2=ddsd2.lPitch>>2;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+((int)Ey-(int)Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=(int)Sx && (int)Ey>=(int)Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch>>1; + AddPitch2=ddsd2.lPitch>>1; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // データ転送 + for (y=Sy;yVx2) + { + Ex-=(Px1+Ex-Vx2); + } + + if (Py1+Ey>Vy2) + { + Ey-=(Py1+Ey-Vy2); + } + + if (Px1=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0x00,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0x00,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える // + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/2; +// data2=(LPWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/4;// + data2=(LPDWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/4;// + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch/2; +// AddPitch2=ddsd2.lPitch/2; + AddPitch1=ddsd1.lPitch/4;// + AddPitch2=ddsd2.lPitch/4;// + + // 回転の中心点を取得 + cx1=(Px2-Px1)/2; + cy1=(Py2-Py1)/2; + cx2=((Px2-Px1)-(X2-X1))/2; + cy2=((Py2-Py1)-(Y2-Y1))/2; +// tx1=cx1*360-cx1*RotateData[Angle+90]+cy1*RotateData[Angle]; +// ty1=cy1*360-cx1*RotateData[Angle]-cy1*RotateData[Angle+90]; + tx1=cx1*360-cx1*elDraw::RotateData[Angle+90]+cy1*elDraw::RotateData[Angle ];// + ty1=cy1*360-cx1*elDraw::RotateData[Angle ]-cy1*elDraw::RotateData[Angle+90];// + + for (y=0;y=0 && rx1=0 && ry1=0 && rx2=0 && ry2=Sx && x=Sy && y>ShiftR)&BitR; +// G =(Buff>>ShiftG)&BitG; +// B =(Buff>>ShiftB)&BitB; + R =Buff.BuffRGB[RGB_R]; + G =Buff.BuffRGB[RGB_G]; + B =Buff.BuffRGB[RGB_B]; + +// Buff = *(data1+rx1+ry2*AddPitch1); +// if (Buff==0x00000000) Buff=*(data2+x+y*AddPitch2); + Buff.Buff = *(data1+rx1+ry2*AddPitch1); + if (Buff.Buff==0x00000000) Buff.Buff=*(data2+x+y*AddPitch2); +// R+=(Buff>>ShiftR)&BitR; +// G+=(Buff>>ShiftG)&BitG; +// B+=(Buff>>ShiftB)&BitB; + R+=Buff.BuffRGB[RGB_R]; + G+=Buff.BuffRGB[RGB_G]; + B+=Buff.BuffRGB[RGB_B]; + +// Buff = *(data1+rx2+ry1*AddPitch1); +// if (Buff==0x00000000) Buff=*(data2+x+y*AddPitch2); + Buff.Buff = *(data1+rx2+ry1*AddPitch1); + if (Buff.Buff==0x00000000) Buff.Buff=*(data2+x+y*AddPitch2); +// R+=(Buff>>ShiftR)&BitR; +// G+=(Buff>>ShiftG)&BitG; +// B+=(Buff>>ShiftB)&BitB; + R+=Buff.BuffRGB[RGB_R]; + G+=Buff.BuffRGB[RGB_G]; + B+=Buff.BuffRGB[RGB_B]; + +// Buff = *(data1+rx2+ry2*AddPitch1); +// if (Buff==0x00000000) Buff=*(data2+x+y*AddPitch2); + Buff.Buff = *(data1+rx2+ry2*AddPitch1); + if (Buff.Buff==0x00000000) Buff.Buff=*(data2+x+y*AddPitch2); +// R+=(Buff>>ShiftR)&BitR; +// G+=(Buff>>ShiftG)&BitG; +// B+=(Buff>>ShiftB)&BitB; + R+=Buff.BuffRGB[RGB_R]; + G+=Buff.BuffRGB[RGB_G]; + B+=Buff.BuffRGB[RGB_B]; + +// Buff=((R/4)<Vx2) + { + Ex-=(Px1+Ex-Vx2); + } + + if (Py1+Ey>Vy2) + { + Ey-=(Py1+Ey-Vy2); + } + + if (Px1=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*ddsd1.lPitch/2; + data2=(LPWORD)ddsd2.lpSurface+Px1+Py1*ddsd2.lPitch/2; + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch/2; + AddPitch2=ddsd2.lPitch/2; + + // 回転の中心点を取得 + cx1=(Px2-Px1)/2; + cy1=(Py2-Py1)/2; + cx2=((Px2-Px1)-(X2-X1))/2; + cy2=((Py2-Py1)-(Y2-Y1))/2; + tx1=cx1*360-cx1*elDraw::RotateData[Angle+90]+cy1*elDraw::RotateData[Angle ]; + ty1=cy1*360-cx1*elDraw::RotateData[Angle ]-cy1*elDraw::RotateData[Angle+90]; + + for (y=0;y=0 && rx1=0 && ry1=0 && rx2=0 && ry2=Sx && x=Sy && y>ShiftR)&BitR; + G =(Buff>>ShiftG)&BitG; + B =(Buff>>ShiftB)&BitB; + + Buff = *(data1+rx1+ry2*AddPitch1); + if (Buff==0x0000) Buff=*(data2+x+y*AddPitch2); + R+=(Buff>>ShiftR)&BitR; + G+=(Buff>>ShiftG)&BitG; + B+=(Buff>>ShiftB)&BitB; + + Buff = *(data1+rx2+ry1*AddPitch1); + if (Buff==0x0000) Buff=*(data2+x+y*AddPitch2); + R+=(Buff>>ShiftR)&BitR; + G+=(Buff>>ShiftG)&BitG; + B+=(Buff>>ShiftB)&BitB; + + Buff = *(data1+rx2+ry2*AddPitch1); + if (Buff==0x0000) Buff=*(data2+x+y*AddPitch2); + R+=(Buff>>ShiftR)&BitR; + G+=(Buff>>ShiftG)&BitG; + B+=(Buff>>ShiftB)&BitB; + + Buff=((R/4)<Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+(Ey-Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // RGBのフォーマットによってアクセスするアドレスを変える // + if (MaskR==0xff0000) + { + RGB_R=2; + RGB_G=1; + RGB_B=0; + } + else + { + RGB_R=0; + RGB_G=1; + RGB_B=2; + } + + // Y方向への追加バイト数の取得 +// AddPitch1=ddsd1.lPitch/2; +// AddPitch2=ddsd2.lPitch/2; + AddPitch1=ddsd1.lPitch/4;// + AddPitch2=ddsd2.lPitch/4;// + + // スプライトの先頭位置を取得 +// data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; +// data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + data1=(LPDWORD)ddsd1.lpSurface+X1+Y1*AddPitch1;// + data2=(LPDWORD)ddsd2.lpSurface+Px+Py*AddPitch2;// + + // データ転送 + for (y=Sy;yLimit)|| + (Buff.BuffRGB[RGB_G]>Limit)|| + (Buff.BuffRGB[RGB_B]>Limit)) + { + *(data2+x)=Buff.Buff; + } + + } + } + + // Y方向に加算 + data1+=AddPitch1; + data2+=AddPitch2; + } + + // スプライトのロック解除 + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + DD_UNLOCK(DDBack,ddsd2.lpSurface); + } + + return TRUE; +} + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- スプライトの描画 ( 独自拡張・シャドー部の切り捨て ) ※ ハイカラー専用 -*/ +/*- -*/ +/*- int Px : 描画X座標 -*/ +/*- int Py : 描画Y座標 -*/ +/*- int Limit : しきい値 ( 0 〜 255 ) -*/ +/*- DDOBJ ObjDD : スプライト情報 -*/ +/*- int X1 : スプライト左上X座標 -*/ +/*- int Y1 : スプライト左上Y座標 -*/ +/*- int X2 : スプライト右下X座標 -*/ +/*- int Y2 : スプライト右下Y座標 -*/ +/*- -*/ +/*- 戻り値 : TRUE = 正常終了 -*/ +/*- : FALSE = エラー発生 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +BOOL elDraw32::LimitLayer16(int Px,int Py,int Limit,DDOBJ ObjDD,int X1,int Y1,int X2,int Y2) +{ + static HRESULT ddret; + static DDSURFACEDESC ddsd1,ddsd2; + static LPWORD data1,data2; + static long AddPitch1,AddPitch2; + static int x,y,Sx,Sy,Ex,Ey; + static unsigned int Buff,R,G,B; + + // 描画領域の計算 + Sx=0; + Sy=0; + Ex=X2-X1; + Ey=Y2-Y1; + + if (Px+(Ex-Sx)>Vx2) + { + Ex-=(Px+(Ex-Sx)-Vx2); + } + + if (Py+(Ey-Sy)>Vy2) + { + Ey-=(Py+(Ey-Sy)-Vy2); + } + + if (Px=Sx && Ey>=Sy) + { + // 構造体の初期化 + memset(&ddsd1,0,sizeof(DDSURFACEDESC)); + ddsd1.dwSize=sizeof(DDSURFACEDESC); + memset(&ddsd2,0,sizeof(DDSURFACEDESC)); + ddsd2.dwSize=sizeof(DDSURFACEDESC); + + // スプライトのロック + ddret=Sprite[ObjDD].Object->Lock(NULL,&ddsd1,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + return FALSE; + } + + // 画面スプライトのロック + ddret=DDBack->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL); + + if (ddret!=DD_OK) + { + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + + return FALSE; + } + + // Y方向への追加バイト数の取得 + AddPitch1=ddsd1.lPitch/2; + AddPitch2=ddsd2.lPitch/2; + + // スプライトの先頭位置を取得 + data1=(LPWORD)ddsd1.lpSurface+X1+Y1*AddPitch1; + data2=(LPWORD)ddsd2.lpSurface+Px+Py*AddPitch2; + + // 8ビット->5ビットにする + Limit>>=3; + + // データ転送 + for (y=Sy;yLimit)|| + (GetRGB[Buff].g>Limit)|| + (GetRGB[Buff].b>Limit)) + { + *(data2+x)=Buff; + } + } + } + + // Y方向に加算 + data1+=AddPitch1; + data2+=AddPitch2; + } + + // スプライトのロック解除 + DD_UNLOCK(Sprite[ObjDD].Object,ddsd1.lpSurface); + DD_UNLOCK(DDBack,ddsd2.lpSurface); + } + + return TRUE; +} + + +/*------------------------------------------------------------------------------*/ +/*- -*/ +/*- 変数の置き換え(元へ戻す) ※ elDraw32で使用 -*/ +/*- -*/ +/*------------------------------------------------------------------------------*/ + +#undef Vx1 +#undef Vy1 +#undef Vx2 +#undef Vy2 + +#undef MaskR +#undef MaskG +#undef MaskB +#undef MaskRGB +#undef BitR +#undef BitG +#undef BitB +#undef ShiftR +#undef ShiftG +#undef ShiftB +#undef ShiftR2 +#undef ShiftG2 +#undef ShiftB2 +#undef BlendList + + +// MMXをコンパイルした時の警告表示回避を元に戻す +#pragma warning( default : 4799 ) + + diff --git a/PROJECT/game.cpp b/PROJECT/game.cpp new file mode 100644 index 0000000..b60fff3 --- /dev/null +++ b/PROJECT/game.cpp @@ -0,0 +1,732 @@ +/*** *************************************************************************** +ピクセルのゲット、セットのサンプルプログラムです。 + +画面(裏画面)、画像情報と両方からピクセルのゲット、セットができます。 +******************************************************************************/ +#include // for getch(); +#include +#include + +#include "el.h" //最新版el.h +#include "elDraw32.h" //21/12/08追加 + +#include "data.cpp" +#include "sub.cpp" + +extern char szPath[_MAX_PATH]; //¥mydocuments¥新しいフォルダ(7)¥test¥test.exe +extern char szDrive[_MAX_DRIVE]; //c: +extern char szDir[_MAX_DIR]; //¥mydocuments¥新しいフォルダ(7)¥test¥ +extern char szFileName[_MAX_FNAME]; //test +extern char szExt[_MAX_EXT]; //.exe +extern char szDrvPath[_MAX_PATH]; //c:¥mydocuments¥新しいフォルダ(7)¥test¥test.exe +extern char szOutput[_MAX_PATH * 5 + 1024];//(^^; +void makefullpath(); +void ini_GetStr(char *section,char *koumoku, char *szAppName,char *buf); +int ini_GetInt(char *section,char *koumoku,char *szAppName); +void ini_SetStr(char *section,char *koumoku,char *szAppName,char *str); +void ini_SetInt(char *section,char *koumoku,char *szAppName,int val); + +int pce_Read(); +void pce_rom_Disp(); +void pce_adr_updn(int val); +void mouse_fnc(); +void mouse_box_disp(); +void make_paletwindow(); + +int bitmap_palet_Read(char *fname); +void bitmap_palet_Wright(); +void text_disp(); +void GameScreen(void); + +#define WINDOWX 1000 +#define WINDOWY 480 + +#define PAL_L 50 +#define PAL_U 40 +#define PAL_R 50+260 +#define PAL_D 40+260 + +#define GAGE_X 140 +#define GAGE_R_Y (400-60) +#define GAGE_G_Y (420-60) +#define GAGE_B_Y (440-60) + +#define ROMBTN_X 320 +#define ROMBTN_Y (310) + + +//テキストを表示する位置です +#define Y_step 15 +#define Y_000 0 +#define Y_001 Y_step-10 +#define Y_002 Y_step*2 +#define Y_003 Y_step*3 +#define Y_004 Y_step*4 +#define Y_005 Y_step*5 +#define Y_006 Y_step*6 +#define Y_007 Y_step*7 +#define Y_008 Y_step*8 +#define Y_009 Y_step*9 +#define Y_010 Y_step*10 +#define Y_011 Y_step*11 +#define Y_012 Y_step*12 +#define Y_013 Y_step*13 +#define Y_014 Y_step*14 +#define Y_015 Y_step*15 +#define Y_016 Y_step*16 +#define Y_017 Y_step*17 +#define Y_018 Y_step*18 +#define Y_019 Y_step*19 +#define Y_020 Y_step*20 +#define Y_021 Y_step*21 +#define Y_022 Y_step*22 +#define Y_023 Y_step*23 +#define Y_024 Y_step*24 +#define Y_025 Y_step*25 +#define Y_026 Y_step*26 +#define Y_027 Y_step*27 +#define Y_028 Y_step*28 +#define Y_029 Y_step*29 +#define Y_030 Y_step*30 + +/********************************************************************************/ +/* */ +/* メイン関数 */ +/* */ +/********************************************************************************/ +#define GAME_SCREEN 1 // タイトル画面です。タイトルのデモです。 + +int elMain("PCEビューアー") +{ + elWindow(WINDOWX,WINDOWY,FALSE); //ウインドウモードです。 + elSetWindow( RUN_NOTOP ); //他のウインドウが重なれるように設定(メッセージウインドウのため) + _ShowDialog=TRUE; //マウスを表示するため + + elLoop() + { + elSetScreen(GAME_SCREEN,GameScreen()); // + } + elExitMain(); +} +/********************************************************************************/ +/* */ +/* ウィンドウ生成関数 */ +/* */ +/********************************************************************************/ +//状態処理の前に無条件に最初に呼ばれるモジュールです。 +//DDOBJ GamenBMP; +//DDOBJ MouseBMP; +//DDOBJ MousewokBMP; + +void elCreate(void) +{ + // いまどきのパソコンならフルカラーにしているので。 + // @@@@@@@ 21/12/08 + elDraw::SetFullColor(); + + // 仮想画面 + //elDraw::Screen(WINDOWX,WINDOWY); + //たしか二階のパソコンでは、RAMにしたほうが高速だったような。 + //ドットごとにカラーでぬりつぶす処理がものすごく遅いです。(21/12/09) + elDraw::Screen(WINDOWX,WINDOWY, CREATE_RAM ); + + // 仮想画面の設定 + elDraw::VirtualScreen(0,0,WINDOWX,WINDOWY); + + elCallScreen(GAME_SCREEN); //EL状態遷移 メインのスレッドへ +} +/********************************************************************************/ +/* */ +/* キーボード関数 */ +/* */ +/********************************************************************************/ +void elKeyboard(void) +{ + case VK_ESCAPE: + elDraw::Exit(); + break; + elExitKeyboard(); +} + +/********************************************************************************/ +/* */ +/* イベント関数 */ +/* */ +/********************************************************************************/ +long elEvent(void) +{ + elExitEvent(); +} + +/********************************************************************************/ +/* */ +/* メインループ */ +/* */ +/********************************************************************************/ + +void pal_1_disp(){ + //カーソル位置ニ、paletヲ表示 + elDraw32::ColorFill(PAL_L+4+((select_Pal%16))*16, + PAL_U+4+((select_Pal/16))*16, + PAL_L+4+((select_Pal%16))*16+14, + PAL_U+4+((select_Pal/16))*16+14, + RGB( + windows_paltbl[ palet[select_Pal].red ], + windows_paltbl[ palet[select_Pal].green ], + windows_paltbl[ palet[select_Pal].blue ]) + ); +} + +void cur_disp(){ + //カーソル位置ニ、カーソルヲ表示 + elDraw32::ColorFill(PAL_L+4+((select_Pal%16))*16-1, + PAL_U+4+((select_Pal/16))*16-1, + PAL_L+4+((select_Pal%16))*16+16-1, + PAL_U+4+((select_Pal/16))*16+16-1, + RGB(255,255,255)); + pal_1_disp(); +} +void cur_clr(){ + //カーソル位置ノカーソルを消去 + elDraw32::ColorFill(PAL_L+4+((select_Pal%16))*16-1, + PAL_U+4+((select_Pal/16))*16-1, + PAL_L+4+((select_Pal%16))*16+16-1, + PAL_U+4+((select_Pal/16))*16+16-1, + RGB(128,128,128)); + pal_1_disp(); +} + +void mode_help_disp() +{ + //カーソル位置ニ、paletヲ表示 + elDraw32::ColorFill(0,0,640,300,RGB(0,0,0)); + + elFont::Begin(GOTHIC,14,0,FALSE,FALSE,FALSE); + elFont::Color(RGB(255,255,255),0,FALSE); + elFont::Draw( 200,Y_001,"PC Engine Viewer"); + + elFont::Draw( 40,Y_002,"<<<<< PALET >>>>>"); + elFont::Draw( 40,Y_003,"Z Key---RED +1LEVEL X Key---RED -1LEVEL"); + elFont::Draw( 40,Y_004,"A Key---GREEN +1 S Key---GREEN -1"); + elFont::Draw( 40,Y_005,"Q Key---BLUE +1 W Key---BLUE -1"); + elFont::Draw( 40,Y_006,"CURSOL Key-----Select Color"); + elFont::Draw( 40,Y_007,"C Key---Color COPY V Key---PASTE"); + elFont::Draw( 40,Y_008,"F1Key---Palet load "); + elFont::Draw( 40,Y_009,"F5Key---Palet save "); + + elFont::Draw( 40,Y_011,"<<<<< ROM >>>>>"); + elFont::Draw( 40,Y_012,"NUM1---ROMADR+1 NUM7---ADR -1"); + elFont::Draw( 40,Y_013,"NUM2---ROMADR+200h NUM8---ADR -200h"); + elFont::Draw( 40,Y_014,"NUM3---ROMADR+2000 NUM9---ADR -2000h"); + + elFont::Draw( 340,Y_002,"PCE Palet..."); + elFont::Draw( 340,Y_003,"Sprite = 16Palet. BG = 16Palet."); + elFont::Draw( 340,Y_004,"1Palet = 16Color."); + elFont::Draw( 340,Y_005,"1Color = R(3bit),G(3bit),B(3bit)."); + elFont::Draw( 340,Y_006,"3bit = 8Level ((min)0,1,2...6,7(max))"); + elFont::Draw( 340,Y_007,"(Sprite = 256Color. BG = 256Color.)"); + elFont::Before(); +} + +void gamen_rewrite(){ + int lp,lpx,lpy; + + elDraw32::ColorFill( + PAL_L, + PAL_U, + PAL_R, + PAL_D, + RGB(128,128,128)); + lp=0; + for(lpy=0; lpy<16;lpy++){ + for(lpx=0; lpx<16;lpx++){ + elDraw32::ColorFill(PAL_L+4+lpx*16, + PAL_U+4+lpy*16, + PAL_L+4+lpx*16+14, + PAL_U+4+lpy*16+14, + RGB( + windows_paltbl[ palet[lp].red ], + windows_paltbl[ palet[lp].green ], + windows_paltbl[ palet[lp].blue ]) + ); + lp++; + } + } + + //pceビューアー画面 + pce_rom_Disp(); + + //void mouse_box_disp(); + //mouse_box_disp(); + + //カーソル位置ニ、カーソルヲ表示 + cur_disp(); +} + +void GameScreen(void) +{ + int lp; +// WORD Color; + + // 画面が切り換わった直後の場合 + if (elChangeScreen()) + { + exitflg=0; + elDraw::Clear(); +// elDraw::LineLayer(0,0,1,GamenBMP,0,0,640,480); + //配列クリア + for(lp=0;lp<256;lp++){ + palet[lp].red=0; + palet[lp].green=0; + palet[lp].blue=0; + } + //配列にパレット読み込み + if(bitmap_palet_Read("001.bmp")== -1) + { + elDraw::Exit(); + return; + } + + //pceロム読み込み + if(pce_Read()== -1) + { + elDraw::Exit(); + return; + } + + //全画面表示 + gamen_rewrite(); + text_disp(); + } + + elSystem::GetKey('Z',&z_key); //RED palet value ++ + elSystem::GetKey('X',&x_key); //RED palet value -- + elSystem::GetKey('A',&a_key); //GRN palet value ++ + elSystem::GetKey('S',&s_key); //GRN palet value -- + elSystem::GetKey('Q',&q_key); //BLE palet value ++ + elSystem::GetKey('W',&w_key); //BLE palet value -- + elSystem::GetKey('C',&c_key); //copy + elSystem::GetKey('V',&v_key); //past + elSystem::GetKey(VK_UP,&up_key); //カーソル移動 + elSystem::GetKey(VK_DOWN,&dn_key); + elSystem::GetKey(VK_LEFT,<_key); + elSystem::GetKey(VK_RIGHT,&rt_key); + + elSystem::GetKey(VK_NUMPAD0,&num_0key); //disp adr = 0h + + elSystem::GetKey(VK_NUMPAD7,&num_7key); //disp adr -= 10000h + //elSystem::GetKey(VK_NUMPAD8,&num_8key); //disp adr -= 200h + elSystem::GetKey(VK_NUMPAD9,&num_9key); //disp adr -= 10000h + + //elSystem::GetKey(VK_NUMPAD4,&num_4key); //表示幅縮小 + //elSystem::GetKey(VK_NUMPAD6,&num_6key); //表示幅拡大 + elSystem::GetKey(VK_NUMPAD4,&num_4key); //disp adr -= 2000h + elSystem::GetKey(VK_NUMPAD6,&num_6key); //disp adr += 2000h + + elSystem::GetKey(VK_NUMPAD1,&num_1key); //disp adr -= 800h + //elSystem::GetKey(VK_NUMPAD2,&num_2key); //disp adr += 200h + elSystem::GetKey(VK_NUMPAD3,&num_3key); //disp adr += 800h + + mouse_fnc(); + + if(help_flg==0){ + + if(num_0key==PUSH_KEY){ + pce_adr_updn(-0x200000); //計算結果がマイナスのとき、0x0000になります + gamen_rewrite(); //全画面表示 + } + + if(num_1key==PUSH_KEY){ + pce_adr_updn(-0x800); + gamen_rewrite(); //全画面表示 + } + if(num_3key==PUSH_KEY){ + pce_adr_updn(0x800); + gamen_rewrite(); //全画面表示 + } + + if(num_4key==PUSH_KEY){ //表示幅縮小 + pce_adr_updn(-0x2000); + //rom_BG_High =16; //BGモード時の表示の大きさ + //rom_BG_Width--; + gamen_rewrite(); //全画面表示 + } + if(num_6key==PUSH_KEY){ //表示幅拡大 + pce_adr_updn(0x2000); + //rom_BG_High =16; //BGモード時の表示の大きさ + //rom_BG_Width++; + gamen_rewrite(); //全画面表示 + } + + if(num_7key==PUSH_KEY){ + pce_adr_updn(-0x10000); + gamen_rewrite(); //全画面表示 + } + if(num_9key==PUSH_KEY){ + pce_adr_updn(0x10000); + gamen_rewrite(); //全画面表示 + } + + //load + elSystem::GetKey(VK_F1,&f1_key); + if(f1_key==PUSH_KEY){ + bitmap_palet_Read( NULL ); + //全画面表示 + gamen_rewrite(); + } + //save + elSystem::GetKey(VK_F5,&f5_key); + if(f5_key==PUSH_KEY){ + bitmap_palet_Wright(); + //全画面表示 + gamen_rewrite(); + } + + if(up_key==PUSH_KEY){ + cur_clr(); //カーソル位置ノカーソルを消去 + if((select_Pal-16)<0){select_Pal=select_Pal-16+256;} + else{ select_Pal=select_Pal-16;} + cur_disp(); //カーソル位置ニ、カーソルヲ表示 + make_paletwindow(); + } + else if(dn_key==PUSH_KEY){ + cur_clr(); //カーソル位置ノカーソルを消去 + if((select_Pal+16)>255){select_Pal=select_Pal+16-256;} + else{select_Pal=select_Pal+16;} + cur_disp(); //カーソル位置ニ、カーソルヲ表示 + make_paletwindow(); + } + else if(lt_key==PUSH_KEY){ + cur_clr(); //カーソル位置ノカーソルを消去 + if((select_Pal-1)<0){select_Pal=255;} + else{ select_Pal=select_Pal-1;} + cur_disp(); //カーソル位置ニ、カーソルヲ表示 + make_paletwindow(); + } + else if(rt_key==PUSH_KEY){ + cur_clr(); //カーソル位置ノカーソルを消去 + if((select_Pal+1)>255){select_Pal=0;} + else{ select_Pal=select_Pal+1;} + cur_disp(); //カーソル位置ニ、カーソルヲ表示 + make_paletwindow(); + } + else{} + + if(x_key==PUSH_KEY){ + if(palet[select_Pal].blue < 7)palet[select_Pal].blue++; + make_paletwindow(); + } + if(z_key==PUSH_KEY){ + if(palet[select_Pal].blue > 0)palet[select_Pal].blue--; + make_paletwindow(); + } + if(s_key==PUSH_KEY){ + if(palet[select_Pal].green < 7)palet[select_Pal].green++; + make_paletwindow(); + } + if(a_key==PUSH_KEY){ + if(palet[select_Pal].green > 0)palet[select_Pal].green--; + make_paletwindow(); + } + if(w_key==PUSH_KEY){ + if(palet[select_Pal].red < 7)palet[select_Pal].red++; + make_paletwindow(); + } + if(q_key==PUSH_KEY){ + if(palet[select_Pal].red > 0)palet[select_Pal].red--; + make_paletwindow(); + } + + //パレットのコピー、ペースト + if(c_key==PUSH_KEY){ + palet_copywok.red = palet[select_Pal].red; + palet_copywok.green = palet[select_Pal].green; + palet_copywok.blue = palet[select_Pal].blue; + make_paletwindow(); + + } + if(v_key==PUSH_KEY){ + palet[select_Pal].red = palet_copywok.red; + palet[select_Pal].green = palet_copywok.green; + palet[select_Pal].blue = palet_copywok.blue; + make_paletwindow(); + } + } + + elDraw::ShowFPS(); + _ShowMouse=TRUE; + + elDraw::Refresh(); + + if(exitflg!=0){ + elDraw::Exit(); + } +} + +//256個のパレット、下のゲージを描画。パレットはROMビューア画面にも反映 +void make_paletwindow() +{ + int lp; + //カーソル位置のパレットを画面に反映 + pal_1_disp(); + + //ビューアー画面にもパレットを反映 + pce_rom_Disp(); + + //一番下にゲージを描画 + for(lp=1;lp<8;lp++){ + if(lp<=(palet[select_Pal].red)){ + elDraw32::ColorFill( + GAGE_X+lp*16, GAGE_R_Y, + GAGE_X+lp*16+15, GAGE_R_Y+6, + RGB(255,0,0)); + } + else{ + elDraw32::ColorFill( + GAGE_X+lp*16, GAGE_R_Y, + GAGE_X+lp*16+15, GAGE_R_Y+6, + RGB(0,0,0)); + } + } + for(lp=1;lp<8;lp++){ + if(lp<=(palet[select_Pal].green)){ + elDraw32::ColorFill( + GAGE_X+lp*16, GAGE_G_Y, + GAGE_X+lp*16+15, GAGE_G_Y+6, + RGB(0,255,0)); + } + else{ + elDraw32::ColorFill( + GAGE_X+lp*16, GAGE_G_Y, + GAGE_X+lp*16+15, GAGE_G_Y+6, + RGB(0,0,0)); + } + } + for(lp=1;lp<8;lp++){ + if(lp<=(palet[select_Pal].blue)){ + elDraw32::ColorFill( + GAGE_X+lp*16, GAGE_B_Y, + GAGE_X+lp*16+15, GAGE_B_Y+6, + RGB(0,0,255)); + } + else{ + elDraw32::ColorFill( + GAGE_X+lp*16, GAGE_B_Y, + GAGE_X+lp*16+15, GAGE_B_Y+6, + RGB(0,0,0)); + } + } +} +/********************************************************************************/ +/* */ +/********************************************************************************/ + + +//バグ有り・・・アラインメント考慮せず。 +//アラインメントのためにbfSize以下すべてニバイトずれています。 +//この形式でデータを保存してはじめてわかりました。06年7月 +//biClrImporantは本当は4なのに2バイトになって正常動作しているのは +//ストラクチャの中身が全部ニバイトずれているからです。 +//ここはとりあえずこのままにします・・・ + +struct BMAPHEADER { + unsigned char bfType0; //1 データ形式(B) + unsigned char bfType1; //1 データ形式(M) + unsigned long bfSize; //4 ファイルサイズ + unsigned short bfReserved1; //2 予約 + unsigned short bfReserved2; //2 予約 + unsigned long bfOffBits; //4 ビットマップデータの開始オフセット + unsigned long biSize; //4 ヘッダーのサイズ(以下のデータ) + long biWidth; //4 水平ドット数 + long biHeight; //4 垂直ドット数 + unsigned short biPlanes; //2 プレーン数 + unsigned short biBitCount; //2 1ピクセル当たりのビット数(8) + unsigned long biCompression; //4 圧縮形式(0=無し) + unsigned long biSizeImage; //4 ビットマップデータサイズ + long biXPixPerMeter; //4 水平解像度 + long biYPixPerMeter; //4 垂直解像度 + unsigned long biClrUsed; //4 使用色数 +// unsigned long biClrImporant; //4 重要な色? +// unsigned short dmy; //2 ※仕様書にない空白の領域? + unsigned short biClrImporant; //2 重要な色? + unsigned char palet[256][4]; //1024 256色パレット +}; + +char buf[0x10000+100]; + +struct BMAPHEADER *bitmap_ptr; + +unsigned char val_henkan(unsigned char val){ + if(val <63) {return(0);} + else if(val <95) {return(1);} + else if(val <127){return(2);} + else if(val <159){return(3);} + else if(val <191){return(4);} + else if(val <223){return(5);} + else if(val <255){return(6);} + else {return(7);} //==255 +} +/////////////////////////////////////////////////////////////////// +// // +// ダイアログ関数 // +// // +/////////////////////////////////////////////////////////////////// +BOOL OpenDlg(char* lpstrFileTitle,char* lpstrFile) +{ + int i,j; + OPENFILENAME ofn; + char Filter[]=" すべてのファイル "; + + j=(int)strlen(Filter); + for (i=0;ipalet[lp][0]); //b + palet[lp].green = val_henkan( bitmap_ptr->palet[lp][1]); //g + palet[lp].red = val_henkan( bitmap_ptr->palet[lp][2]); //r + } + return(0); +} + +void bitmap_palet_Wright(){ + int lp; + FILE *fp; + + bitmap_ptr =(struct BMAPHEADER *)buf; + +//※適当に作成したファイルではエディタに読み込めませんでした。 +//起動時にsample.bmpを読み込み、読み込んだままの形式で保存します +// bitmap_ptr->bfType0 = 'B'; +// bitmap_ptr->bfType1 = 'M'; +// bitmap_ptr->bfSize =0x2000; //ファイルサイズ +// bitmap_ptr->bfReserved1 =0; //予約 +// bitmap_ptr->bfReserved2 =0; //予約 +// bitmap_ptr->bfOffBits =0x1000; //ビットマップデータの開始オフセット +// bitmap_ptr->biSize =40; //ヘッダーのサイズ(以下のデータ) +// bitmap_ptr->biWidth =100; //水平ドット数 +// bitmap_ptr->biHeight =100; //垂直ドット数 +// bitmap_ptr->biPlanes =1; //プレーン数 +// bitmap_ptr->biBitCount =8; //1ピクセル当たりのビット数(8) +// bitmap_ptr->biCompression=0; //圧縮形式(0=無し) +// bitmap_ptr->biSizeImage =0; //ビットマップデータサイズ +// bitmap_ptr->biXPixPerMeter=0; //水平解像度 +// bitmap_ptr->biYPixPerMeter=0; //垂直解像度 +// bitmap_ptr->biClrUsed =256; //使用色数 +// bitmap_ptr->biClrImporant=0; //重要な色? +//// bitmap_ptr->palet[256][4]=; //256色パレット + + //01234567を32倍して0,32,64, 96,128,160,192,224 + //0以外のとき、+31で 0,63,95,127,159,191,223,255 + for(lp=0;lp<256;lp++){ + bitmap_ptr->palet[lp][0]= palet[lp].blue<<5; //b + if(palet[lp].blue != 0)bitmap_ptr->palet[lp][0]+=31; + + bitmap_ptr->palet[lp][1]= palet[lp].green<<5; //g + if(palet[lp].green != 0)bitmap_ptr->palet[lp][1]+=31; + + bitmap_ptr->palet[lp][2]= palet[lp].red<<5; //r + if(palet[lp].red != 0)bitmap_ptr->palet[lp][2]+=31; + + bitmap_ptr->palet[lp][3]=0; //reserved; + } + if (( fp = fopen( FileName, "wb" )) == NULL ) + { + elDraw::Error("bmpwrite()","BMP file not write error"); + return; + } + fwrite(&buf[0], 1,filesize,fp); + fclose(fp); +} + +void text_disp() +{ + elFont::Begin(GOTHIC,14,0,FALSE,FALSE,FALSE); + elFont::Color(RGB(255,255,255),0,FALSE); + elFont::Draw( 200,Y_001,"PC Engine Viewer"); + + elFont::Draw( 400,Y_001, RomName ); //21/12/08 + + // elFont::Draw( 340,Y_002,"Z Key---RED +1LEVEL X Key---RED -1LEVEL"); + // elFont::Draw( 340,Y_003,"A Key---GREEN +1 S Key---GREEN -1"); + // elFont::Draw( 340,Y_004,"Q Key---BLUE +1 W Key---BLUE -1"); + //elFont::Draw( 340,Y_001,"CURSOL Key-----Move"); + //elFont::Draw( 340,Y_002,"C Key---Palet COPY V Key---PASTE"); + //elFont::Draw( 340,Y_003,"F1Key---Palet load "); + //elFont::Draw( 340,Y_004,"F5Key---Palet save "); + + //elFont::Draw( 340,200-10,"PCE Palet..."); + //elFont::Draw( 340,220,"Sprite = 16Palet. BG = 16Palet."); + //elFont::Draw( 340,240,"1Palet = 16Color."); + //elFont::Draw( 340,260,"1Color = R(3bit),G(3bit),B(3bit)."); + //elFont::Draw( 340,280,"3bit = 8Level ((min)0,1,2...6,7(max))"); + //elFont::Draw( 340,300,"(Sprite = 256Color. BG = 256Color.)"); + + elFont::Draw( GAGE_X-5,GAGE_R_Y-20," 1 2 3 4 5 6 7"); + elFont::Draw( GAGE_X-5,GAGE_R_Y-5,"R:"); + elFont::Draw( GAGE_X-5,GAGE_G_Y-5,"G:"); + elFont::Draw( GAGE_X-5,GAGE_B_Y-5,"B:"); + elFont::Before(); +} + +#include "viewer.cpp" +#include "bmpsave.cpp" +#include "mouse.cpp" diff --git a/PROJECT/inifile.cpp b/PROJECT/inifile.cpp new file mode 100644 index 0000000..d4777f9 --- /dev/null +++ b/PROJECT/inifile.cpp @@ -0,0 +1,127 @@ +/* +MFCは2000系でレジストリに書き込むので使用できません。 +API系関数はGetPrivateProfileIntなどです。 + +フルパスを作成するのが面倒ですが、動作確認しました。 +スペースがあるマイドキュメントでも動作します。 + +*/ + + +#include +#include + +/************************************************** + フルパスの作成 +**************************************************/ +char szPath[_MAX_PATH]; //¥mydocuments¥新しいフォルダ(7)¥test¥test.exe +char szDrive[_MAX_DRIVE]; //c: +char szDir[_MAX_DIR]; //¥mydocuments¥新しいフォルダ(7)¥test¥ +char szFileName[_MAX_FNAME]; //test +char szExt[_MAX_EXT]; //.exe +char szDrvPath[_MAX_PATH]; //c:¥mydocuments¥新しいフォルダ(7)¥test¥test.exe +char szOutput[_MAX_PATH * 5 + 1024];//(^^; + +void makefullpath() +{ + DWORD dwRet; + //実行中のプロセスのフルパス名を取得する + dwRet = GetModuleFileName(NULL, szPath, sizeof(szPath)); + if(dwRet == 0) { + //エラー処理など(省略) + } + //フルパス名を分割する + _splitpath(szPath, szDrive, szDir, szFileName, szExt); + + //出力文字列を作成 + //wsprintf(szOutput, + // "実行しているプログラムのフルパス名 %s\r\nドライブ %s\r\n" + // "ディレクトリ %s\r\nファイル名 %s\r\n拡張子 %s\n", + // szPath, + // szDrive, + // szDir, + // szFileName, + // szExt); + + //c:.....のメイク + sprintf(szDrvPath,"%s%s%s\0",szDrive,szDir,"test.ini"); +} + + +/************************************************** +// Iniファイルの情報を読み取る +// fileName Iniファイルの名前(フルパス) +// section セクション名 +// entry Entry名 +**************************************************/ +//bufは最大256文字分のバッファ +void ini_GetStr(char *section,char *koumoku, char *szAppName,char *buf) +{ + int i; + GetPrivateProfileString(section,koumoku, NULL, buf, 255, szAppName); +} + +/************************************************** +// Iniファイルの情報を読み取る +// fileName Iniファイルの名前(フルパス) +// section セクション名 +// entry Entry名 +**************************************************/ +int ini_GetInt(char *section,char *koumoku,char *szAppName) +{ + int i; + printf("path = %s\n",szAppName); + + return GetPrivateProfileInt(section,koumoku,-1, szAppName); +} + +/************************************************** +// Iniファイルへ情報保存 +**************************************************/ +void ini_SetInt(char *section,char *koumoku,char *szAppName,int val) +{ + //WritePrivateProfileSection(section,koumoku,szAppName); + char buf[256]; + sprintf( buf,"%d\0",val); + + WritePrivateProfileString( + section, // セクション名へのポインタ + koumoku, // キー名へのポインタ + buf, // 追加するべき値 + szAppName // .ini ファイルへのポインタ + ); +} +/************************************************** +// Iniファイルへ情報保存 +**************************************************/ +void ini_SetStr(char *section,char *koumoku,char *szAppName,char *str) +{ + //WritePrivateProfileSection(szAppName,"JOUHOU",szAppName); + WritePrivateProfileString( + section, // セクション名へのポインタ + koumoku, // キー名へのポインタ + str, // 追加するべき値 + szAppName // .ini ファイルへのポインタ + ); +} +/************************************************** +**************************************************/ +//extern int main() +//{ +// int val; +// char buf[256]; +// makefullpath(); +// +// ini_SetInt("JOUHOU", "SPEED",szDrvPath,5678910); +// ini_SetInt("MOJIRETU", "FILE",szDrvPath,"abcdefg.txt"); +// val = ini_GetInt("JOUHOU", "SPEED",szDrvPath); +// printf("int %d\n",val); +// +// ini_GetStr("MOJIRETU", "FILE",szDrvPath,buf); +// printf("str %s\n",buf); +// +// //メッセージボックスで出力 +// MessageBox(NULL, szOutput, "結果", MB_OK); +// +// return 0; +//} diff --git a/PROJECT/main.ico b/PROJECT/main.ico new file mode 100644 index 0000000..644b40b Binary files /dev/null and b/PROJECT/main.ico differ diff --git a/PROJECT/mouse.cpp b/PROJECT/mouse.cpp new file mode 100644 index 0000000..bdfb188 --- /dev/null +++ b/PROJECT/mouse.cpp @@ -0,0 +1,270 @@ +/********************************************************************************/ +/* */ +/********************************************************************************/ +#define BTN_MAX 31 + +struct botton_st { + int xx,yy; + int lenx,leny; + char *title; +} botton_Data[BTN_MAX]={ + //0 + {GAGE_X-70,GAGE_R_Y-4, 20,20, "←"}, //パレット赤 + {GAGE_X-35,GAGE_R_Y-4, 20,20, "→"}, //パレット赤 + {GAGE_X-70,GAGE_G_Y-4, 20,20, "←"}, //パレット緑 + {GAGE_X-35,GAGE_G_Y-4, 20,20, "→"}, //パレット緑 + {GAGE_X-70,GAGE_B_Y-4, 20,20, "←"}, //パレット青 + {GAGE_X-35,GAGE_B_Y-4, 20,20, "→"}, //パレット青 + + {PAL_R,PAL_D-85, 20,40, "↑"}, //パレットセレクト + {PAL_R,PAL_D-85+45, 20,40, "↓"}, //パレットセレクト + + {GAGE_X- 90,GAGE_B_Y+55, 60,20, " LOAD "}, //パレット読み込み + {GAGE_X- 20,GAGE_B_Y+55, 60,20, " SAVE "}, //パレット書き込み + {GAGE_X+180,GAGE_B_Y+55, 120,20, " ROM LOAD "}, //ROM + {GAGE_X+ 50,GAGE_B_Y+55, 60,20, " HELP "}, + + //10 + {ROMBTN_X ,ROMBTN_Y ,65,20, "↑-1h "}, + {ROMBTN_X ,ROMBTN_Y+24 ,65,20, "↓+1h "}, + {ROMBTN_X+75 ,ROMBTN_Y ,65,20, "↑-8h "}, + {ROMBTN_X+75 ,ROMBTN_Y+24 ,65,20, "↓+8h "}, + {ROMBTN_X+150,ROMBTN_Y ,65,20, "↑-20h "}, + {ROMBTN_X+150,ROMBTN_Y+24 ,65,20, "↓+20h "}, + {ROMBTN_X+225,ROMBTN_Y ,65,20, "↑-80h "}, + {ROMBTN_X+225,ROMBTN_Y+24 ,65,20, "↓+80h "}, + // + {ROMBTN_X ,ROMBTN_Y+60 ,65,20, "↑-200h "}, + {ROMBTN_X ,ROMBTN_Y+60+24 ,65,20, "↓+200h "}, + {ROMBTN_X+75 ,ROMBTN_Y+60 ,65,20, "↑-800h "}, + {ROMBTN_X+75 ,ROMBTN_Y+60+24 ,65,20, "↓+800h "}, + {ROMBTN_X+150,ROMBTN_Y+60 ,65,20, "↑-2000h"}, + {ROMBTN_X+150,ROMBTN_Y+60+24 ,65,20, "↓+2000h"}, + {ROMBTN_X+225,ROMBTN_Y+60 ,65,20, "↑-8000h"}, + {ROMBTN_X+225,ROMBTN_Y+60+24 ,65,20, "↓+8000h"}, + {PAL_L,PAL_U,PAL_R-PAL_L,PAL_D-PAL_U,""}, //palet + + {GAGE_X+330,GAGE_B_Y+55, 60,20, " SPR / BG "}, + {GAGE_X+410,GAGE_B_Y+55, 60,20, " BMP SAVE "} + }; + +void mouse_box_disp() +{ + int lp; + for(lp=0;lp15)viewer_Pal=0; + gamen_rewrite(); + + for(lp=0;lp<16;lp++){ + elDraw::ShowFormat( PAL_L-14,PAL_U+lp*16+4," "); + } + elDraw::ShowFormat( PAL_L-14,PAL_U+(viewer_Pal*16)+4,"→"); + elDraw::ShowFormat( PAL_R,PAL_D-85-14,"Pal=%-2d",viewer_Pal); +} + +void mouse_fnc() +{ + //マウスにより、ある領域のクリックで処理 + // elDraw::Line(MousePX-10,MousePY,MousePX+10,MousePY,RGB(255,255,255),1); + + int lp; + int xx1,yy1,xx2,yy2; + mouse_box_disp(); + //select_pal(0); + + //220505 なんですかこれは・・・20年間気付かなかった。こんなにたくさんループする必要ないです。コメントに。 + //項目分ループしてるから、描画を何度も繰り返すとき遅くなっていたのです。 + //・・・と思ったら、コメントに出来ないようです。動かなくなります。 + for(lp=0;lp= xx1) && (MousePX = yy1) && (MousePY 15)viewer_Pal=0; + //gamen_rewrite(); + return; //220505 確定したらループ継続せずrtnのこと + case 8: //" LOAD " //パレット読み込み + if(bitmap_palet_Read( NULL )== -1){return;} + gamen_rewrite(); + text_disp(); + return; //220505 確定したらループ継続せずrtnのこと + + case 9: //" SAVE " //パレット書き込み + bitmap_palet_Wright(); + gamen_rewrite(); + text_disp(); + return; //220505 確定したらループ継続せずrtnのこと + + case 10: //" ROM LOAD " //ROM + //pceロム読み込み + if(pce_Read()== -1){return;} + //全画面表示 + gamen_rewrite(); + text_disp(); + return; //220505 確定したらループ継続せずrtnのこと + + case 11: //" HELP " + if(help_flg==0){ + help_flg=1; + mode_help_disp(); + } + else{ + help_flg=0; + elDraw::Clear(); + //全画面表示 + gamen_rewrite(); + text_disp(); + } + return; //220505 確定したらループ継続せずrtnのこと + case 12: //"↑-1h " + pce_adr_updn(-0x01);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 13: //"↓+1h " + pce_adr_updn(0x01);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 14: //"↑-8h " + pce_adr_updn(-0x08);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 15: //"↓+8h " + pce_adr_updn(0x08);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 16: //"↑-20h " + pce_adr_updn(-0x20);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 17: //"↓+20h " + pce_adr_updn(0x20);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 18: //"↑-80h " + pce_adr_updn(-0x80);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 19: //"↓+80h " + pce_adr_updn(0x80);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 20: //"↑-200h " + pce_adr_updn(-0x200);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 21: //"↓+200h " + pce_adr_updn(0x200);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 22: //"↑-800h " + pce_adr_updn(-0x800);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 23: //"↓+800h " + pce_adr_updn(0x800);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 24: //"↑-2000h" + pce_adr_updn(-0x2000);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 25: //"↓+2000h" + pce_adr_updn(0x2000);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 26: //"↑-8000h" + pce_adr_updn(-0x8000);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 27: //"↓+8000h" + pce_adr_updn(0x8000);pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 28: + cur_clr(); //カーソル位置ノカーソルを消去 + select_Pal= (MousePX-xx1)/16+(MousePY-yy1)/16*16; + cur_disp(); //カーソル位置ニ、カーソルヲ表示 + return; //220505 確定したらループ継続せずrtnのこと + + case 29: + rom_Disp_Mode++; + if(rom_Disp_Mode>=2){ + rom_Disp_Mode=0;//0=Sprite 1=BG + } + pce_rom_Disp(); + return; //220505 確定したらループ継続せずrtnのこと + case 30: + void bmpsave(); + bmpsave(); + return; //220505 確定したらループ継続せずrtnのこと + default: + break; + } + if(palet[select_Pal].red<0) + palet[select_Pal].red=0; + if(palet[select_Pal].green<0) + palet[select_Pal].green=0; + if(palet[select_Pal].blue<0) + palet[select_Pal].blue=0; + if(palet[select_Pal].red>7) + palet[select_Pal].red=7; + if(palet[select_Pal].green>7) + palet[select_Pal].green=7; + if(palet[select_Pal].blue>7) + palet[select_Pal].blue=7; + + if( help_flg==0) + make_paletwindow(); + } + } + } +} diff --git a/PROJECT/resource.aps b/PROJECT/resource.aps new file mode 100644 index 0000000..0b479d8 Binary files /dev/null and b/PROJECT/resource.aps differ diff --git a/PROJECT/resource.h b/PROJECT/resource.h new file mode 100644 index 0000000..dd5458f --- /dev/null +++ b/PROJECT/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/PROJECT/resource.rc b/PROJECT/resource.rc new file mode 100644 index 0000000..6fc8d67 --- /dev/null +++ b/PROJECT/resource.rc @@ -0,0 +1,72 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Japanese resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN) +#ifdef _WIN32 +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT +#pragma code_page(932) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +MAIN ICON DISCARDABLE "main.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Japanese resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/PROJECT/resource.res b/PROJECT/resource.res new file mode 100644 index 0000000..9ee4c2c Binary files /dev/null and b/PROJECT/resource.res differ diff --git a/PROJECT/sub.cpp b/PROJECT/sub.cpp new file mode 100644 index 0000000..ba14538 --- /dev/null +++ b/PROJECT/sub.cpp @@ -0,0 +1,123 @@ + +//char textworkbuf[MAX_PATH]; +char textworkbuf[1024]; + +//************************************** +// 今の日付と時間の文字列を得る +//************************************** +char * GetStr_DayAndTime() +{ + time_t t = time(NULL); + struct tm *local = localtime(&t); + //char * const wdays[] = { "日", "月", "火", "水", "木", "金", "土" }; + char * const wdays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; + + sprintf(textworkbuf, ";[ %04d/%02d/%02d (%s)] %02d:%02d:%02d\n", + local->tm_year + 1900, + local->tm_mon + 1, + local->tm_mday, + wdays[local->tm_wday], + local->tm_hour, + local->tm_min, + local->tm_sec); + + return textworkbuf; +} + + +//************************************** +// EXEのあるパスを得る +//************************************** +char * GetInstallPath() +{ + + char Path[MAX_PATH+1]; + char drive[MAX_PATH+1],dir[MAX_PATH+1],fname[MAX_PATH+1],ext[MAX_PATH+1]; + + if(0 != GetModuleFileName( NULL, Path, MAX_PATH )) // 実行ファイルの完全パスを取得 + { + _splitpath(Path,drive,dir,fname,ext); //パス名を分解 + + //printf("完全パス : %s\n",Path); + //printf("ドライブ : %s\n",drive); + //printf("ディレクトリ パス : %s\n",dir); + //printf("ファイル名(拡張子なし) : %s\n",fname); + //printf("拡張子 : %s\n",ext); + + sprintf(textworkbuf, "%s%s",drive,dir ); + + return textworkbuf; + } + + return NULL; //エラー +} + + +//************************************** +//指定ファイル名をインストールディレクトリ(EXEのあるフォルダ)からのフルパスにします +// ロムを読み込むためにカレントディレクトリを移動した場合 +// EXEのあるフォルダにあるファイルを見失うため +//************************************** +char *GetFullPath_ThisFile( char *fname ) +{ + char Path[1024]; + char *dir; + + dir = GetInstallPath(); + + if( dir == NULL )return NULL; + + sprintf(Path, "%s%s",dir,fname ); + strcpy(textworkbuf,Path); + + return textworkbuf; +} + + + +//--------------------------------------------------------------- +// 四角を描画 +//--------------------------------------------------------------- +// あまりにも点描画が遅いため、あるていど早くする努力をしてみました。 +// 21/12/08 + +//void elDraw32_ColorFill(int X1,int Y1,int X2,int Y2,COLORREF Color) +void elDraw32_ColorFill(int X1,int Y1,int X2,int Y2, int rr,int gg, int bb ) +{ + static DDBLTFX ddbltfx; + static RECT rect; + + rect.left = X1; + rect.top = Y1; + rect.right = X2; + rect.bottom = Y2; + + ddbltfx.dwSize = sizeof(ddbltfx); + //ddbltfx.dwFillColor = GetRValue(Color)<Blt(&rect,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx); + DDBack->Blt(&rect,NULL,NULL,DDBLT_COLORFILL,&ddbltfx); +} + + + +//上の関数をマクロにしてみました + DDBLTFX cf_ddbltfx; + RECT cf_rect; + +#define ColFilMac(X1,Y1,X2,Y2,rr,gg,bb) \ + cf_rect.left = X1; \ + cf_rect.top = Y1; \ + cf_rect.right = X2; \ + cf_rect.bottom = Y2; \ + cf_ddbltfx.dwSize = sizeof(cf_ddbltfx); \ + cf_ddbltfx.dwFillColor = rr<Blt(&cf_rect,NULL,NULL,DDBLT_COLORFILL,&cf_ddbltfx); + diff --git a/PROJECT/viewer.cpp b/PROJECT/viewer.cpp new file mode 100644 index 0000000..378dfd7 --- /dev/null +++ b/PROJECT/viewer.cpp @@ -0,0 +1,419 @@ +//ROM読み込みエリア 最大のスト2に合わせ、4メガバイトまで +// 1024 x 1024 = 1048576(100000h) 1mega byte + +//#define ROMDT_ST2 0x100000*4 +//#define ROMDT_ST2 0x100000*16 //220420 cdromromも読みたいため16メガバイトに +#define ROMDT_ST2 0x100000*0x20 //220505 スーパー雷電 26MB サファイヤ17MB ダウンロード2(19MB) + // ウインズオブ 7.4MB サイキックストーム12MB ネクスザールスペシャル6.5MB + // スターパロジャー 4.2MB フォゴットン 9.1MB + // 大旋風とかは2-4MBです。 + + +unsigned char romdata[ROMDT_ST2]; +int rom_datacnt; + +//pceの画像はデータをワードアクセスのため +unsigned short *rom_ptr; +//──────────────────────────────── +//──────────────────────────────── +int romFileSize = 0; + + + +//──────────────────────────────── +//rom読み込み関数 +//──────────────────────────────── +//(21/12/08) .pceのときヘッダ200hを取る処理を追加。取らないときは.binのこと + +int pce_Read() +{ + int Rtype = 0; // 0=.pce 1=.bin + int i,lp; + FILE *fp; + char buf[_MAX_PATH]; + + for(lp=0;lp(ROMDT_ST2-0x2000)){ + rom_datacnt = ROMDT_ST2-0x2000; + } + rom_ptr =(unsigned short *)&romdata[rom_datacnt]; //ワードポインタ +}