diff --git a/GIAN07/ENDING.CPP b/GIAN07/ENDING.CPP index 92b4fbb3..45506f36 100644 --- a/GIAN07/ENDING.CPP +++ b/GIAN07/ENDING.CPP @@ -27,10 +27,10 @@ typedef struct tagEndingStTask{ DWORD fadein; // フェードイン時刻 DWORD fadeout; // フェードアウト時刻 - DWORD NumStf; // 全スタッフ数 DWORD StfID[10]; // スタッフID DWORD TitleID; // タイトル、すなわち役職ID + short NumStf; // 全スタッフ数 short alpha; // パレットの状態 int ox, oy; // 表示基準座標 @@ -52,9 +52,25 @@ EndingGrpInfo EGrpInfo; EndingStTask EStfTask; EndingText EText; -// フォント情報格納用ね // -ExtraFontInfo *pFontInfo[7]; -ExtraFontInfo *pMember[7]; +const PIXEL_LTRB StaffLabel[7] = { + { 0, 0, 160, 24 }, + { 0, 24, 104, 48 }, + { 0, 48, 160, 72 }, + { 0, 72, 232, 96 }, + { 0, 96, 168, 120 }, + { 0, 144, 104, 168 }, + { 0, (480 - 32), (9 * 32), 480 }, +}; + +const PIXEL_LTRB StaffMember[7] = { + { 0, 168, 72, 192 }, + { 96, 168, 168, 192 }, + { 192, 168, 264, 192 }, + { 288, 168, 360, 192 }, + { 0, 192, 144, 216 }, + { 168, 192, 320, 216 }, + { 0, 216, 336, 264 } +}; // フラッシュの状態 // DWORD FlashState = 0; @@ -68,8 +84,6 @@ void DrawStfInfo(); // スタッフの描画 void DrawFadeInfo(); // フェードIO情報の反映 -void EndingCleanup(); // おしまい処理 - void EndingSCLDecode(); // エンディング用 SCL のデコード @@ -87,20 +101,6 @@ bool EndingInit(void) { PALETTE pal; - PIXEL_LTRB src[7] = { - {0, 0,160, 24}, {0, 24,104, 48}, {0, 48,160, 72}, - {0,72,232, 96}, {0, 96,168,120}, {0,144,104,168}, - {0, 480-32, 9*32, 480}, - }; - - PIXEL_LTRB src2[7] = { - {0, 168, 72, 192}, {96, 168, 168, 192}, {192, 168, 264, 192}, {288, 168, 360, 192}, - {0, 192, 144, 216}, {168, 192, 320, 216}, - {0, 216, 336, 264} - }; - - int i; - GrpSetClip(0, 0, 640, 480); GrpCls(); GrpFlip(); @@ -128,42 +128,16 @@ bool EndingInit(void) EText.Rect = TextObj.Register({ 640, 131 }); EText.Rerender = true; - for(i=0; i<7; i++){ - pFontInfo[i] = CreateExtraFont(GrEndingCredits, &src[i]); - if(pFontInfo[i] == NULL) return FALSE; - } - - for(i=0; i<7; i++){ - pMember[i] = CreateExtraFont(GrEndingCredits, &src2[i]); - if(pMember[i] == NULL) return FALSE; - } - return TRUE; } -// おしまい処理 // -void EndingCleanup() -{ - int i; - - for(i=0; i<7; i++){ - DeleteExtraFont(pFontInfo[i]); - } - - for(i=0; i<7; i++){ - DeleteExtraFont(pMember[i]); - } -} - - // エンディング状態推移用プロシージャ // void EndingProc(void) {/* Key_Read(); if(Key_Data){ - EndingCleanup(); GameExit(); return; } @@ -274,16 +248,18 @@ void DrawGrpInfo() // スタッフの描画 // void DrawStfInfo() { - int i; - if(!EStfTask.bWantDisp) return; - DrawExtraFont(pFontInfo[EStfTask.TitleID], - EStfTask.ox, EStfTask.oy, 0);//255-EStfTask.alpha); + // [src] is copied! For now. + auto Blit = [](WINDOW_POINT dst, PIXEL_LTRB src) { + dst -= (src.Size() / 2); + GrpBlt(&src, dst.x, dst.y, GrEndingCredits); + }; - for(i=0; i -// ヒミツの関数 // -void __FillExpoint(EXPOINT *p, int x, int y, int w, int h); - // Glyph selection inside the 16×16 font // std::optional Glyph16x16(char c) { @@ -292,136 +287,3 @@ void DrawGrdFont(TEXTRENDER_RECT_ID rect_id, std::string_view str) } }); } - - -// フォント生成 // -ExtraFontInfo *CreateExtraFont(SURFACE_DDRAW& Surface, PIXEL_LTRB *pSrc) -{ - ExtraFontInfo *pInfo; - int MaxSize; - DWORD Width, Height; - void *Target; - - DDSURFACEDESC ddsd; - - // 俺様メモリの確保ぉ // - pInfo = (ExtraFontInfo *)LocalAlloc(LPTR, sizeof(ExtraFontInfo)); - if(pInfo == NULL) return NULL; - - // 幅と高さを代入しましょう // - pInfo->Width = Width = (pSrc->right) - (pSrc->left); - pInfo->Height = Height = (pSrc->bottom) - (pSrc->top); - - // 画像格納に必要なサイズを求める // - MaxSize = pInfo->Width * pInfo->Height * sizeof(EXPOINT); - - pInfo->Data = (EXPOINT *)LocalAlloc(LPTR, MaxSize); - if(pInfo->Data == NULL){ - LocalFree(pInfo); - return NULL; - } - - memset(&ddsd,0,sizeof(DDSURFACEDESC)); - ddsd.dwSize = sizeof(ddsd); - auto ddret = Surface.surf->Lock(nullptr, &ddsd, DDLOCK_WAIT, nullptr); - if(ddret != DD_OK){ - DeleteExtraFont(pInfo); - return NULL; - } - - pInfo->DataSize = 0; - - // 透過色をセットしましょう // - std::visit([&ddsd, &pInfo, &pSrc, &Width, &Height](auto pixel) { - auto* pPixel = reinterpret_cast(ddsd.lpSurface); - const auto TransID = pPixel[0]; - - for(decltype(Height) y = 0; y < Height; y++) { - for(decltype(Width) x = 0; x < Width; x++) { - const auto offset = ( - (x+pSrc->left) + ((y+pSrc->top) * ddsd.dwWidth) - ); - if(pPixel[offset] != TransID){ - pInfo->Data[pInfo->DataSize].c = pPixel[offset]; - __FillExpoint(&(pInfo->Data[pInfo->DataSize]), x, y, Width, Height); - pInfo->DataSize++; - } - } - } - }, DxObj.PixelFormat); - - Surface.surf->Unlock(nullptr); - - return pInfo; -} - - -void __FillExpoint(EXPOINT *p, int x, int y, int w, int h) -{ - x -= w / 2; - y -= h / 2; - - p->x = x; - p->y = y; - - p->d = atan8(x * 64, y * 64); - p->l = isqrt(x * x + y * y); -} - - -// フォント削除 // -void DeleteExtraFont(ExtraFontInfo *pFont) -{ - if(pFont == NULL) return; - - if(pFont->Data) LocalFree(pFont->Data); - - LocalFree(pFont); -} - - -// フォント描画 // -void DrawExtraFont(ExtraFontInfo *pFont, int ox, int oy, int t, int radius_max) -{ - DDSURFACEDESC ddsd; - - if(pFont == NULL) return; - - - memset(&ddsd,0,sizeof(DDSURFACEDESC)); - ddsd.dwSize = sizeof(ddsd); - const auto ddret = DxObj.Back->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); - if(ddret != DD_OK) return; - - std::visit([&pFont, &ox, &oy, &t, &radius_max, &ddsd](auto pixel) { - auto* pData = pFont->Data; - auto* pPixel = reinterpret_cast(ddsd.lpSurface); - - for(decltype(pFont->DataSize) i = 0; i < pFont->DataSize; i++, pData++){ - int x, y; - if(t){ - //d = pData->d + (pData->l * (sinl(t-64,128)+128)) / 64; - const auto d = pData->d + (sinl(t-64, 64)+64) * (pData->l) / 32; - auto l1 = (pData->l+60) * cosm(t) / 256 - 60; - auto l2 = (pData->l-10) * cosm(t) / 256 + 10; - - if(radius_max){ - l1 = min(radius_max, abs(l1)); - l2 = min(radius_max, abs(l2)); - } - - x = ox + cosl(d, l1); - y = oy + sinl(d, l2); - } - else{ - x = ox + pData->x; - y = oy + pData->y; - } - if(x < 0 || x > 639 || y < 0 || y > 399) continue; - - pPixel[x + (y * ddsd.dwWidth)] = pData->c; - } - }, DxObj.PixelFormat); - - DxObj.Back->Unlock(NULL); -} diff --git a/GIAN07/FONTUTY.H b/GIAN07/FONTUTY.H index c9dea8cc..dcc45319 100644 --- a/GIAN07/FONTUTY.H +++ b/GIAN07/FONTUTY.H @@ -22,23 +22,6 @@ -typedef struct tagEXPOINT { - int x, y; // 元座標(中心からの相対座標) - int l; // 極座標における長さ - BYTE d; // 極座標における角度 - - PIXELFORMAT::LARGEST c; // 色情報 -} EXPOINT; - -typedef struct tagExtraFontInfo { - int Width; // 元画像の幅 - int Height; // 元画像の高さ - - int DataSize; // 点の数 - - EXPOINT *Data; // データ格納先 -} ExtraFontInfo; - enum class GIAN_FONT_ID : uint8_t { SMALL = 0, // フォント(小さい文字用) NORMAL = 1, // フォント(通常の文字用) @@ -69,14 +52,5 @@ extern void GrpPutMidNum(int x, int y, int n); // MIDI 用フォントを描画 // グラデーション付きフォントを描画する void DrawGrdFont(TEXTRENDER_RECT_ID rect_id, std::string_view str); -ExtraFontInfo *CreateExtraFont(SURFACE_DDRAW& Surface, PIXEL_LTRB *pSrc); // フォント生成 -void DeleteExtraFont(ExtraFontInfo *pFont); // フォント削除 - -// Renders [pFont] to the back buffer at the given left/top position. Setting -// [t] renders the [t]th frame of a double-spiral moiré animation instead; in -// that case, [radius_max] can be used to restrict this animation to the given -// radius in the center of [pFont], which won't render any pixels outside. -void DrawExtraFont(ExtraFontInfo *pFont, int ox, int oy, int t = 0, int radius_max = 0); - #endif diff --git a/game/coords.cpp b/game/coords.cpp new file mode 100644 index 00000000..1c7cf9dd --- /dev/null +++ b/game/coords.cpp @@ -0,0 +1,12 @@ +/* + * Coordinate systems + * + */ + +#include "coords.h" + +PIXEL_POINT& operator -=(PIXEL_POINT& self, const PIXEL_SIZE& other) { + self.x -= other.w; + self.y -= other.h; + return self; +} diff --git a/game/coords.h b/game/coords.h index f6872617..1124939d 100644 --- a/game/coords.h +++ b/game/coords.h @@ -40,9 +40,15 @@ struct PIXEL_SIZE { return { (w - other.x), (h - other.y) }; } + PIXEL_SIZE operator /(int divisor) const { + return { (w / divisor), (h / divisor) }; + } + std::strong_ordering operator <=>(const PIXEL_SIZE& other) const = default; }; +PIXEL_POINT& operator -=(PIXEL_POINT& self, const PIXEL_SIZE& other); + // Left-top-width-height rectangle in unscaled pixel space. Relative to any // origin. struct PIXEL_LTWH { diff --git a/unused/ENDING.CPP b/unused/ENDING.CPP new file mode 100644 index 00000000..97fb2883 --- /dev/null +++ b/unused/ENDING.CPP @@ -0,0 +1,55 @@ +/* + * Usage code for the unused double-spiral moiré animation + * + */ + +#include "FONTUTY.H" + +// フォント情報格納用ね // +ExtraFontInfo *pFontInfo[7]; +ExtraFontInfo *pMember[7]; + +bool EndingInit(void) +{ + int i; + + for(i=0; i<7; i++){ + pFontInfo[i] = CreateExtraFont(GrEndingCredits, &src[i]); + if(pFontInfo[i] == NULL) return FALSE; + } + + for(i=0; i<7; i++){ + pMember[i] = CreateExtraFont(GrEndingCredits, &src2[i]); + if(pMember[i] == NULL) return FALSE; + } +} + +// スタッフの描画 // +void DrawStfInfo() +{ + int i; + + if(!EStfTask.bWantDisp) return; + + DrawExtraFont(pFontInfo[EStfTask.TitleID], + EStfTask.ox, EStfTask.oy, 0);//255-EStfTask.alpha); + + for(i=0; iWidth = Width = (pSrc->right) - (pSrc->left); + pInfo->Height = Height = (pSrc->bottom) - (pSrc->top); + + // 画像格納に必要なサイズを求める // + MaxSize = pInfo->Width * pInfo->Height * sizeof(EXPOINT); + + pInfo->Data = (EXPOINT *)LocalAlloc(LPTR, MaxSize); + if(pInfo->Data == NULL){ + LocalFree(pInfo); + return NULL; + } + + memset(&ddsd,0,sizeof(DDSURFACEDESC)); + ddsd.dwSize = sizeof(ddsd); + auto ddret = Surface.surf->Lock(nullptr, &ddsd, DDLOCK_WAIT, nullptr); + if(ddret != DD_OK){ + DeleteExtraFont(pInfo); + return NULL; + } + + pInfo->DataSize = 0; + + // 透過色をセットしましょう // + std::visit([&ddsd, &pInfo, &pSrc, &Width, &Height](auto pixel) { + auto* pPixel = reinterpret_cast(ddsd.lpSurface); + const auto TransID = pPixel[0]; + + for(decltype(Height) y = 0; y < Height; y++) { + for(decltype(Width) x = 0; x < Width; x++) { + const auto offset = ( + (x+pSrc->left) + ((y+pSrc->top) * ddsd.dwWidth) + ); + if(pPixel[offset] != TransID){ + pInfo->Data[pInfo->DataSize].c = pPixel[offset]; + __FillExpoint(&(pInfo->Data[pInfo->DataSize]), x, y, Width, Height); + pInfo->DataSize++; + } + } + } + }, DxObj.PixelFormat); + + Surface.surf->Unlock(nullptr); + + return pInfo; +} + + +void __FillExpoint(EXPOINT *p, int x, int y, int w, int h) +{ + x -= w / 2; + y -= h / 2; + + p->x = x; + p->y = y; + + p->d = atan8(x * 64, y * 64); + p->l = isqrt(x * x + y * y); +} + + +// フォント削除 // +void DeleteExtraFont(ExtraFontInfo *pFont) +{ + if(pFont == NULL) return; + + if(pFont->Data) LocalFree(pFont->Data); + + LocalFree(pFont); +} + + +// フォント描画 // +void DrawExtraFont(ExtraFontInfo *pFont, int ox, int oy, int t, int radius_max) +{ + DDSURFACEDESC ddsd; + + if(pFont == NULL) return; + + + memset(&ddsd,0,sizeof(DDSURFACEDESC)); + ddsd.dwSize = sizeof(ddsd); + const auto ddret = DxObj.Back->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); + if(ddret != DD_OK) return; + + std::visit([&pFont, &ox, &oy, &t, &radius_max, &ddsd](auto pixel) { + auto* pData = pFont->Data; + auto* pPixel = reinterpret_cast(ddsd.lpSurface); + + for(decltype(pFont->DataSize) i = 0; i < pFont->DataSize; i++, pData++){ + int x, y; + if(t){ + //d = pData->d + (pData->l * (sinl(t-64,128)+128)) / 64; + const auto d = pData->d + (sinl(t-64, 64)+64) * (pData->l) / 32; + auto l1 = (pData->l+60) * cosm(t) / 256 - 60; + auto l2 = (pData->l-10) * cosm(t) / 256 + 10; + + if(radius_max){ + l1 = min(radius_max, abs(l1)); + l2 = min(radius_max, abs(l2)); + } + + x = ox + cosl(d, l1); + y = oy + sinl(d, l2); + } + else{ + x = ox + pData->x; + y = oy + pData->y; + } + if(x < 0 || x > 639 || y < 0 || y > 399) continue; + + pPixel[x + (y * ddsd.dwWidth)] = pData->c; + } + }, DxObj.PixelFormat); + + DxObj.Back->Unlock(NULL); +} diff --git a/unused/FONTUTY.H b/unused/FONTUTY.H new file mode 100644 index 00000000..98b043a8 --- /dev/null +++ b/unused/FONTUTY.H @@ -0,0 +1,39 @@ +/* + * Unused double-spiral moiré animation + * + * This animation was intended to be used for the staff roll sprites, but was + * effectively commented out for the final release and replaced with regular + * sprite blitting. A recording of the originally intended effect can be + * found at + * + * https://rec98.nmlgc.net/blog/2022-12-31 + * + * Moved here because the effect directly writes pixels into the back buffer, + * and might therefore be hard to port to non-DirectDraw renderers. + */ + +typedef struct tagEXPOINT { + int x, y; // 元座標(中心からの相対座標) + int l; // 極座標における長さ + BYTE d; // 極座標における角度 + + PIXELFORMAT::LARGEST c; // 色情報 +} EXPOINT; + +typedef struct tagExtraFontInfo { + int Width; // 元画像の幅 + int Height; // 元画像の高さ + + int DataSize; // 点の数 + + EXPOINT *Data; // データ格納先 +} ExtraFontInfo; + +ExtraFontInfo *CreateExtraFont(SURFACE_DDRAW& Surface, PIXEL_LTRB *pSrc); // フォント生成 +void DeleteExtraFont(ExtraFontInfo *pFont); // フォント削除 + +// Renders [pFont] to the back buffer at the given left/top position. Setting +// [t] renders the [t]th frame of a double-spiral moiré animation instead; in +// that case, [radius_max] can be used to restrict this animation to the given +// radius in the center of [pFont], which won't render any pixels outside. +void DrawExtraFont(ExtraFontInfo *pFont, int ox, int oy, int t = 0, int radius_max = 0);