diff --git a/CMakeLists.txt b/CMakeLists.txt index 28c78534e..8e5dd9ea9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,6 +139,8 @@ set(Impacto_Src src/profile/games/darling/sysmesbox.cpp + src/profile/games/sghd/titlemenu.cpp + src/games/rne/tilebackground.cpp src/games/rne/datedisplay.cpp src/games/rne/systemmenu.cpp @@ -204,6 +206,8 @@ set(Impacto_Src src/games/darling/sysmesbox.cpp + src/games/sghd/titlemenu.cpp + src/hud/dialoguebox.cpp src/hud/datedisplay.cpp src/hud/saveicondisplay.cpp @@ -252,6 +256,7 @@ set(Impacto_Src src/ui/widgets/cclcc/sysmenubutton.cpp src/ui/widgets/cclcc/tipsentrybutton.cpp src/ui/widgets/cclcc/tipstabgroup.cpp + src/ui/widgets/sghd/titlebutton.cpp src/stbi_impl.c @@ -403,6 +408,8 @@ set(Impacto_Header src/profile/games/dash/titlemenu.h + src/profile/games/sghd/titlemenu.h + src/profile/games/chlcc/dialoguebox.h src/profile/games/chlcc/titlemenu.h src/profile/games/chlcc/savemenu.h @@ -459,6 +466,8 @@ set(Impacto_Header src/games/dash/titlemenu.h + src/games/sghd/titlemenu.h + src/games/chlcc/dialoguebox.h src/games/chlcc/titlemenu.h src/games/chlcc/savemenu.h @@ -555,6 +564,7 @@ set(Impacto_Header src/ui/widgets/rne/sysmenubutton.h src/ui/widgets/cc/titlebutton.h src/ui/widgets/cclcc/titlebutton.h + src/ui/widgets/sghd/titlebutton.h src/renderer/3d/camera.h src/renderer/3d/model.h diff --git a/profiles/sghd/charset.lua b/profiles/sghd/charset.lua new file mode 100644 index 000000000..8600fed08 --- /dev/null +++ b/profiles/sghd/charset.lua @@ -0,0 +1,45 @@ +-- WARNING, 0-INDEXED ARRAYS AHEAD + +root.Charset = { + Flags = {} +}; + +for i = 0, (64 * 37) - 1 do root.Charset.Flags[i] = 0; end + +local spaces = {[0]=0, 63}; +for i = 0, #spaces do + root.Charset.Flags[spaces[i]] = root.Charset.Flags[spaces[i]] | CharacterTypeFlags.Space; +end + +-- 、 。 . , ? ! 〜 ” ー ) 〕 ] } 〉 》 」 』 】☆ ★ ♪ 々 ぁ ぃ ぅ ぇ +-- ぉ っ ゃ ゅ ょ ァ ィ ゥ ェ ォ ッ ャ ュ ョ – +local wordEndingPuncts = { + [0]=0x00BE, 0x00BF, 0x00C1, + 0x00C0, 0x00C4, 0x00C5, + 0x00E4, 0x00CB, 0x00E5, + 0x00CD, 0x00CF, 0x00D1, + 0x00D3, 0x00D5, 0x00D7, + 0x00D9, 0x00DB, 0x00DD, + 0x01A5, 0x01A6, 0x00E6, + 0x0187, 0x00E8, 0x00E9, + 0x00EA, 0x00EB, 0x00EC, + 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F2, 0x00F3, + 0x00F4, 0x00F5, 0x00F6, + 0x00F7, 0x00F8, 0x00F9, + 0x00FA, 0x0113 +}; +for i = 0, #wordEndingPuncts do + root.Charset.Flags[wordEndingPuncts[i]] = root.Charset.Flags[wordEndingPuncts[i]] | CharacterTypeFlags.WordEndingPunct; +end + +-- space(63) space(0) “ ( 〔 [ { 〈 《 「 +local wordStartingPuncts = { + [0]=63, 0, 0x00CA, + 0x00CC, 0x00CE, 0x00D0, + 0x00D2, 0x00D4, 0x00D6, + 0x00D8, 0x00DA, 0x00DC +}; +for i = 0, #wordStartingPuncts do + root.Charset.Flags[wordStartingPuncts[i]] = root.Charset.Flags[wordStartingPuncts[i]] | CharacterTypeFlags.WordStartingPunct; +end diff --git a/profiles/sghd/config.lua b/profiles/sghd/config.lua new file mode 100644 index 000000000..2ee34ab77 --- /dev/null +++ b/profiles/sghd/config.lua @@ -0,0 +1,5 @@ +root.Language = "English"; +root.ResolutionWidth = 1920; +root.ResolutionHeight = 1080; +root.Fullscreen = false; +root.Subtitles = "off"; diff --git a/profiles/sghd/dialogue.lua b/profiles/sghd/dialogue.lua new file mode 100644 index 000000000..4a96fbf4c --- /dev/null +++ b/profiles/sghd/dialogue.lua @@ -0,0 +1,79 @@ +root.Sprites["ADVBox"] = { + Sheet = "Data01", + Bounds = { X = 767, Y = 806, Width = 1280, Height = 216 }, +}; + +root.Sprites["DialogueWaitIcon"] = { + Sheet = "Data01", + Bounds = { X = 1, Y = 97, Width = 32, Height = 32 } +}; + +-- NOTE: Values taken from sgps3 +-- TODO: Check and fix +root.Dialogue = { + REVBounds = { X = 0, Y = 0, Width = 960, Height = 400 }, + REVNameFontSize = 24, + REVNameColor = 24, + REVNameOffset = 34, + NVLBounds = { X = 125, Y = 85, Width = 1024, Height = 400 }, + ADVBounds = { X = 161, Y = 525, Width = 960, Height = 180 }, + ADVBoxSprite = "ADVBox", + ADVBoxPos = { X = 0, Y = 504 }, + FadeOutDuration = 0.33, + FadeInDuration = 0.33, + DialogueBoxCurrentType = DialogueBoxType.Plain, + NVLBoxMaxOpacity = 0.55, + ADVNameAlignment = TextAlignment.Left, + ADVNameFontSize = 22, + ADVNamePos = { X = 600, Y = 672 }, + WaitIconCurrentType = WaitIconType.Rotate, + WaitIconSprite = "DialogueWaitIcon", + WaitIconOffset = { X = 4, Y = 4 }, + WaitIconAnimationDuration = 3.2, + DialogueFont = "Default", + DefaultFontSize = 32, + RubyFontSize = 14, + RubyYOffset = -18, + ColorTable = { + {0xFFFFFF, 0x000000}, {0x5080FF, 0x000000}, + {0xFF7080, 0x000000}, {0xFFA0F8, 0x000000}, + {0x46FF80, 0x000000}, {0x90FFFF, 0x000000}, + {0xFFFF70, 0x000000}, {0x80FFC0, 0x000000}, + {0xFFB080, 0x000000}, {0xB080FF, 0x000000}, + {0x000000, 0x808080}, {0x000000, 0x5080FF}, + {0x000000, 0xFF7080}, {0x000000, 0xFFA0F8}, + {0x000000, 0x268840}, {0x000000, 0x409999}, + {0x000000, 0x888830}, {0x000000, 0x80FFC0}, + {0x000000, 0xFFB080}, {0x000000, 0xB080FF}, + {0xD0D0D0, 0x000000}, {0xD0D0FF, 0x000000}, + {0xFFD0D0, 0x000000}, {0xFFD0FF, 0x000000}, + {0xD0FFD0, 0x000000}, {0xD0FFFF, 0x000000}, + {0xFFFFD0, 0x000000}, {0xE8FFD0, 0x000000}, + {0xFFE8D0, 0x000000}, {0xD0E8FF, 0x000000}, + {0xFFFFFF, 0x808080}, {0xFFFFFF, 0x5080FF}, + {0xFFFFFF, 0xFF7080}, {0xFFFFFF, 0xFFA0F8}, + {0xFFFFFF, 0x46FF80}, {0xFFFFFF, 0x90FFFF}, + {0xFFFFFF, 0xFFFF70}, {0xFFFFFF, 0x80FFC0}, + {0xFFFFFF, 0xFFB080}, {0xFFFFFF, 0xB080FF}, + {0xFFEEEE, 0x000000}, {0xFFCCCC, 0x000000}, + {0xFFAAAA, 0x000000}, {0xFF9999, 0x000000}, + {0xFF8888, 0x000000}, {0xFFFF00, 0x000000}, + {0xFEF000, 0x000000}, {0xFF7777, 0x000000}, + {0xFF6666, 0x000000}, {0xFF5555, 0x000000}, + {0xFF4444, 0x000000}, {0xFF3333, 0x000000}, + {0xFF2222, 0x000000}, {0xFF0000, 0x000000}, + {0xDD0000, 0x000000}, {0xBB0000, 0x000000}, + {0xB00000, 0x000000}, {0xAA0000, 0x000000}, + {0x950000, 0x000000}, {0x808080, 0x000000}, + {0xAAAAAA, 0x000000}, {0xAAC1C9, 0x000000}, + {0x000000, 0x000000}, {0x000000, 0x000000}, + {0x000000, 0x000000}, {0x000000, 0x000000}, + {0x000000, 0x000000}, {0xF80B0B, 0x000000}, + {0xF8910B, 0x000000}, {0x33F12A, 0x000000} + }, + MaxPageSize = 2000, + PageCount = 3, + ColorTagIsUint8 = true +}; + +include('sghd/nametag.lua'); diff --git a/profiles/sghd/font.lua b/profiles/sghd/font.lua new file mode 100644 index 000000000..8164ebb43 --- /dev/null +++ b/profiles/sghd/font.lua @@ -0,0 +1,56 @@ +-- WARNING, 0-INDEXED ARRAYS AHEAD + +root.Fonts = { + ["Default"] = { + Type = FontType.Basic, + Sheet = "Font", + Columns = 64, + Rows = 14, + Widths = {}, + DesignColWidth = 32, + LineSpacing = 22, + } +}; + +local westernWidths = { + [0]=0x20, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x0C, 0x11, 0x11, 0x0F, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x13, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x14, 0x10, 0x14, 0x14, + 0x15, 0x14, 0x14, 0x14, 0x14, 0x14, 0x1A, 0x15, 0x17, 0x18, 0x15, 0x14, + 0x19, 0x17, 0x0B, 0x14, 0x17, 0x15, 0x1E, 0x18, 0x1A, 0x16, 0x1B, 0x15, + 0x14, 0x16, 0x17, 0x1A, 0x1F, 0x19, 0x1A, 0x14, 0x13, 0x14, 0x13, 0x15, + 0x13, 0x11, 0x14, 0x14, 0x0A, 0x0C, 0x14, 0x0A, 0x1E, 0x14, 0x15, 0x14, + 0x15, 0x0E, 0x12, 0x10, 0x14, 0x15, 0x1F, 0x15, 0x15, 0x11, 0x11, 0x11, + 0x09, 0x09, 0x0A, 0x0A, 0x12, 0x0A, 0x0A, 0x09, 0x07, 0x07, 0x0E, 0x0E, + 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0B, 0x0B, 0x0E, 0x0D, 0x11, 0x10, + 0x0C, 0x0E, 0x0C, 0x0E, 0x0A, 0x0C, 0x18, 0x17, 0x0A, 0x0A, 0x0E, 0x1E, + 0x1C, 0x1C, 0x16, 0x1E, 0x19, 0x18, 0x14, 0x18, 0x1B, 0x1B, 0x1C, 0x1A, + 0x18, 0x1B, 0x1A, 0x16, 0x18, 0x1C, 0x1C, 0x19, 0x1B, 0x1C, 0x16, 0x18, + 0x19, 0x1A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +}; + +for i = 0, (64 * 14) - 1 do + if i <= #westernWidths then + root.Fonts["Default"].Widths[i] = westernWidths[i]; + else + root.Fonts["Default"].Widths[i] = root.Fonts["Default"].DesignColWidth; + end +end \ No newline at end of file diff --git a/profiles/sghd/game.lua b/profiles/sghd/game.lua new file mode 100644 index 000000000..ed1df214c --- /dev/null +++ b/profiles/sghd/game.lua @@ -0,0 +1,51 @@ +root.ActiveRenderer = RendererType.OpenGL; + +root.LayerCount = 100; +root.GameFeatures = GameFeature.Sc3VirtualMachine | GameFeature.Renderer2D | GameFeature.Input | GameFeature.Audio | +GameFeature.Video | GameFeature.DebugMenu; +-- NOTE: 1080p messes up rendering of "loading system data..." message, +-- but is probably correct because otherwise logo slideshow has wrong size. +-- Probably a scaling factor somewhere needs to be adjusted for the message. +root.DesignWidth = 1920; +root.DesignHeight = 1080; + +root.WindowName = "STEINS;GATE"; + +root.CharaIsMvl = false; +root.LayFileBigEndian = true; +root.LayFileTexXMultiplier = 2048; +root.LayFileTexYMultiplier = 1024; +root.UseScreenCapEffects = false; + +root.Vm = { + StartScript = 2, -- _STARTUP_WIN.SCX + StartScriptBuffer = 0, + GameInstructionSet = InstructionSet.SGHD, + UseReturnIds = true, + ScrWorkChaStructSize = 40, + ScrWorkBgStructSize = 40 +}; + +include('common/scriptinput.lua'); +include('common/scriptvars.lua'); +include('sghd/config.lua'); +include('sghd/scriptvars.lua'); +include('sghd/savedata.lua'); +include('sghd/tipssystem.lua'); +include('sghd/vfs.lua'); +include('sghd/sprites.lua'); +include('common/animation.lua'); +include('sghd/charset.lua'); +include('sghd/font.lua'); +include('sghd/dialogue.lua'); +include('sghd/nametag.lua'); +include('sghd/hud/saveicon.lua'); +include('sghd/hud/loadingdisplay.lua'); +include('sghd/hud/datedisplay.lua'); +include('sghd/hud/titlemenu.lua'); +include('sghd/hud/systemmenu.lua'); +include('sghd/hud/backlogmenu.lua'); +include('sghd/hud/sysmesboxdisplay.lua'); +include('sghd/hud/selectiondisplay.lua'); +include('sghd/hud/tipsmenu.lua'); +include('sghd/hud/tipsnotification.lua'); diff --git a/profiles/sghd/hud/datedisplay.lua b/profiles/sghd/hud/datedisplay.lua new file mode 100644 index 000000000..540b1fbd5 --- /dev/null +++ b/profiles/sghd/hud/datedisplay.lua @@ -0,0 +1,180 @@ +-- TODO: Copied from SGPS3 - check and fix + +local sheet = "Data01"; +local name = "Date"; + +local yearNumFirstX = 1525; +local yearNumFirstY = 63; +local yearNumWidth = 25; +local yearNum1Width = 8; +local yearNumHeight = 20; + +local numFirstX = 1524; +local numFirstY = 33; +local numWidth = 40; +local num1Width = 12; +local numHeight = 28; + +local weekFirstX = 1785; +local weekFirstY = 63; +local weekSecondX = 1525; +local weekSecondY = 85; +local weekWidth = 73; +local weekFriWidth = 56; +local weekHeight = 20; + +root.DateDisplay = { + Type = DateDisplayType.RNE, + YearNumSprites = {}, + MonthNumSprites = {}, + DayNumSprites = {}, + WeekSprites = {}, + BackgroundStartPos = { X = 1088, Y = 73 }, + BackgroundEndPos = { X = 1088 - 256, Y = 73 }, + DateStartX = 1167, + YearWeekY = 60, + MonthDayY = 52, + Spacing = 1, + FadeInDuration = 0.5, + FadeOutDuration = 0.5 +}; + +for i = 0, 9 do + local yearW; + if i == 1 then + yearW = yearNum1Width; + else + yearW = yearNumWidth; + end + + root.Sprites[name .. "YearNum" .. i] = { + Sheet = sheet, + Bounds = { + X = yearNumFirstX, + Y = yearNumFirstY, + Width = yearW, + Height = yearNumHeight + } + }; + root.DateDisplay.YearNumSprites[#root.DateDisplay.YearNumSprites + 1] = name .. "YearNum" .. i; + + local numW + if i == 1 then + numW = num1Width; + else + numW = numWidth; + end + + root.Sprites[name .. "Num" .. i] = { + Sheet = sheet, + Bounds = { + X = numFirstX, + Y = numFirstY, + Width = numW, + Height = numHeight + } + }; + root.DateDisplay.MonthNumSprites[#root.DateDisplay.MonthNumSprites + 1] = name .. "Num" .. i; + root.DateDisplay.DayNumSprites[#root.DateDisplay.DayNumSprites + 1] = name .. "Num" .. i; + + if i == 1 then + yearNumFirstX = yearNumFirstX + yearNum1Width; + numFirstX = numFirstX + num1Width; + else + yearNumFirstX = yearNumFirstX + yearNumWidth; + numFirstX = numFirstX + numWidth; + end +end + +for i = 0, 6 do + if i > 1 then + local weekW; + if i == 5 then + weekW = weekFriWidth; + else + weekW = weekWidth; + end + + root.Sprites[name .. "Week" .. i] = { + Sheet = sheet, + Bounds = { + X = weekSecondX, + Y = weekSecondY, + Width = weekW, + Height = weekHeight + } + }; + if i == 5 then + weekSecondX = weekSecondX + weekFriWidth; + else + weekSecondX = weekSecondX + weekWidth; + end + else + root.Sprites[name .. "Week" .. i] = { + Sheet = sheet, + Bounds = { + X = weekFirstX, + Y = weekFirstY, + Width = weekWidth, + Height = weekHeight + } + }; + weekFirstX = weekFirstX + weekWidth; + end + root.DateDisplay.WeekSprites[#root.DateDisplay.WeekSprites + 1] = name .. "Week" .. i; +end + +root.Sprites[name .. "MonthDaySeparator"] = { + Sheet = sheet, + Bounds = { + X = 1897, + Y = 33, + Width = 10, + Height = 28 + } +}; +root.DateDisplay.MDSeparatorSprite = name .. "MonthDaySeparator"; + +root.Sprites[name .. "DayYearSeparator"] = { + Sheet = sheet, + Bounds = { + X = 1758, + Y = 63, + Width = 8, + Height = 20 + } +}; +root.DateDisplay.DYSeparatorSprite = name .. "DayYearSeparator"; + +root.Sprites[name .. "OpenBracket"] = { + Sheet = sheet, + Bounds = { + X = 1766, + Y = 63, + Width = 8, + Height = 20 + } +}; +root.DateDisplay.OpenBracketSprite = name .. "OpenBracket"; + +root.Sprites[name .. "CloseBracket"] = { + Sheet = sheet, + Bounds = { + X = 1776, + Y = 63, + Width = 8, + Height = 20 + } +}; +root.DateDisplay.CloseBracketSprite = name .. "CloseBracket"; + +root.Sprites[name .. "Background"] = { + Sheet = sheet, + Bounds = { + X = 1525, + Y = 1, + Width = 450, + Height = 28 + } +}; +root.DateDisplay.BackgroundSprite = name .. "Background"; diff --git a/profiles/sghd/hud/loadingdisplay.lua b/profiles/sghd/hud/loadingdisplay.lua new file mode 100644 index 000000000..f324e3990 --- /dev/null +++ b/profiles/sghd/hud/loadingdisplay.lua @@ -0,0 +1,78 @@ +root.LoadingDisplay = { + ResourceLoadBgAnim = "ResourceLoadingBg", + SaveLoadBgAnim = "SaveLoadingBg", + LoadingIconAnim = "LoadingDisc", + LoadingTextAnim = "LoadingText", + ResourceBgPos = { X = 1074, Y = 611 }, + SaveBgPos = { X = 1019, Y = 598 }, + IconPos = { X = 986, Y = 608 }, + TextPos = { X = 1025, Y = 628 }, + FadeInDuration = 0.66, + FadeOutDuration = 0.33 +}; + +MakeAnimation({ + Name = "ResourceLoadingBg", + Sheet = "Data01", + FirstFrameX = 555, + FirstFrameY = 544, + FrameWidth = 206, + ColWidth = 206, + FrameHeight = 58, + RowHeight = 60, + Frames = 8, + Duration = 0.8, + Rows = 8, + Columns = 1, + PrimaryDirection = AnimationDirections.Down +}); + +MakeAnimation({ + Name = "SaveLoadingBg", + Sheet = "Data01", + FirstFrameX = 388, + FirstFrameY = 0, + FrameWidth = 277, + ColWidth = 279, + FrameHeight = 81, + RowHeight = 83, + Frames = 4, + Duration = 0.8, + Rows = 2, + Columns = 2, + PrimaryDirection = AnimationDirections.Down, + SecondaryDirection = AnimationDirections.Right +}); + +MakeAnimation({ + Name = "LoadingDisc", + Sheet = "Data01", + FirstFrameX = 172, + FirstFrameY = 1, + FrameWidth = 60, + ColWidth = 62, + FrameHeight = 60, + RowHeight = 62, + Frames = 3, + Duration = 0.8, + Rows = 1, + Columns = 3, + PrimaryDirection = AnimationDirections.Right +}); +root.Animations["LoadingDisc"].Frames[#root.Animations["LoadingDisc"].Frames + 1] = "LoadingDisc1"; + +MakeAnimation({ + Name = "LoadingText", + Sheet = "Data01", + FirstFrameX = 173, + FirstFrameY = 91, + FrameWidth = 214, + ColWidth = 214, + FrameHeight = 21, + RowHeight = 23, + Frames = 5, + Duration = 0.8, + Rows = 5, + Columns = 1, + PrimaryDirection = AnimationDirections.Down +}); diff --git a/profiles/sghd/hud/saveicon.lua b/profiles/sghd/hud/saveicon.lua new file mode 100644 index 000000000..67c2ad27c --- /dev/null +++ b/profiles/sghd/hud/saveicon.lua @@ -0,0 +1,32 @@ +-- TODO: Copied from SGPS3 - check and fix + +root.SaveIcon = { + ForegroundAnimation = "SaveIcon", + DefaultPosition = { X = 1153, Y = 23 }, + BackgroundSprite = "SaveIconBg", + BackgroundOffset = { X = -7, Y = -4 }, + BackgroundMaxAlpha = 0.5, + FadeInDuration = 0.5, + FadeOutDuration = 0.25 +}; + +MakeAnimation({ + Name = "SaveIcon", + Sheet = "Data01", + FirstFrameX = 1977, + FirstFrameY = 1, + FrameWidth = 70, + ColWidth = 70, + FrameHeight = 70, + RowHeight = 72, + Frames = 8, + Duration = 0.4, + Rows = 8, + Columns = 1, + PrimaryDirection = AnimationDirections.Down +}); + +root.Sprites["SaveIconBg"] = { + Sheet = "Data01", + Bounds = { X = 1439, Y = 1, Width = 84, Height = 84 } +}; diff --git a/profiles/sghd/hud/selectiondisplay.lua b/profiles/sghd/hud/selectiondisplay.lua new file mode 100644 index 000000000..9e1a7e428 --- /dev/null +++ b/profiles/sghd/hud/selectiondisplay.lua @@ -0,0 +1,77 @@ +-- TODO: Copied from SGPS3 - check and fix + +root.SelectionDisplay = { + DrawType = DrawComponentType.Text, + SelectionBackgroundSprite = "SelectionBackground", + PlainSelectionFrameTopLeftSprite = "PlainSelectionFrameTopLeft", + PlainSelectionFrameTopSideSprite = "PlainSelectionFrameTopSide", + PlainSelectionFrameTopRightSprite = "PlainSelectionFrameTopRight", + PlainSelectionFrameLeftSideSprite = "PlainSelectionFrameLeftSide", + PlainSelectionFrameBottomLeftSprite = "PlainSelectionFrameBottomLeft", + PlainSelectionFrameRightSideSprite = "PlainSelectionFrameRightSide", + PlainSelectionFrameBottomRightSprite = "PlainSelectionFrameBottomRight", + PlainSelectionFrameBottomSideSprite = "PlainSelectionFrameBottomSide", + PlainSelectionFrameMiddleSprite = "PlainSelectionFrameMiddle", + SelectionHighlightSprite = "SelectionHighlight", + SelectionMaxCount = 5, + SelectionBackgroundX = 228, + SelectionBackgroundY = {277, 277, 196, 129, 95}, + SelectionYSpacing = 81, + PlainSelectionYSpacing = 10, + FadeAnimationDurationInOut = 0.2 +}; + +root.Sprites["SelectionBackground"] = { + Sheet = "Data01", + Bounds = { X = 1, Y = 535, Width = 829, Height = 69 } +}; + +root.Sprites["PlainSelectionFrameTopLeft"] = { + Sheet = "Data01", + Bounds = { X = 0, Y = 0, Width = 16, Height = 16 } +}; + +root.Sprites["PlainSelectionFrameTopSide"] = { + Sheet = "Data01", + Bounds = { X = 16, Y = 0, Width = 16, Height = 16 } +}; + +root.Sprites["PlainSelectionFrameTopRight"] = { + Sheet = "Data01", + Bounds = { X = 32, Y = 0, Width = 16, Height = 16 } +}; + +root.Sprites["PlainSelectionFrameLeftSide"] = { + Sheet = "Data01", + Bounds = { X = 0, Y = 16, Width = 16, Height = 16 } +}; + +root.Sprites["PlainSelectionFrameBottomLeft"] = { + Sheet = "Data01", + Bounds = { X = 0, Y = 32, Width = 16, Height = 16 } +}; + +root.Sprites["PlainSelectionFrameRightSide"] = { + Sheet = "Data01", + Bounds = { X = 32, Y = 16, Width = 16, Height = 16 } +}; + +root.Sprites["PlainSelectionFrameBottomRight"] = { + Sheet = "Data01", + Bounds = { X = 32, Y = 32, Width = 16, Height = 16 } +}; + +root.Sprites["PlainSelectionFrameBottomSide"] = { + Sheet = "Data01", + Bounds = { X = 16, Y = 32, Width = 16, Height = 16 } +}; + +root.Sprites["PlainSelectionFrameMiddle"] = { + Sheet = "Data01", + Bounds = { X = 16, Y = 16, Width = 16, Height = 16 } +}; + +root.Sprites["SelectionHighlight"] = { + Sheet = "Data01", + Bounds = { X = 65, Y = 33, Width = 94, Height = 30 } +}; diff --git a/profiles/sghd/hud/sysmesboxdisplay.lua b/profiles/sghd/hud/sysmesboxdisplay.lua new file mode 100644 index 000000000..cfc58aba2 --- /dev/null +++ b/profiles/sghd/hud/sysmesboxdisplay.lua @@ -0,0 +1,85 @@ +-- TODO: Copied from SGPS3 - check and fix + +local sheet = "Data01"; +local name = "SysMesBox"; + +root.SysMesBoxDisplay = { + Type = SysMesBoxType.CHLCC, + DrawType = DrawComponentType.SystemMessage, + BoxX = 602, + BoxY = 224, + TextFontSize = 32, + TextMiddleY = 236, + TextX = 640, + TextLineHeight = 34, + TextMarginY = 14, + ChoicePadding = 40, + ChoiceY = 365, + ChoiceXBase = 680, + MinMaxMesWidth = 294, + MinHighlightWidth = 48, + HighlightBaseWidth = 144, + HighlightYOffset = 0, + HighlightXOffset = 0, + HighlightXBase = 658, + HighlightXStep = 132, + HighlightRightPartSpriteWidth = 24, + AnimationSpeed = 55, + FadeInDuration = 0.33, + FadeOutDuration = 0.25 +}; + +root.Sprites[name .. "Box"] = { + Sheet = sheet, + Bounds = { + X = 767, + Y = 637, + Width = 1280, + Height = 172 + } +}; +root.SysMesBoxDisplay.Box = name .. "Box"; + +root.Sprites[name .. "BoxDecoration"] = { + Sheet = sheet, + Bounds = { + X = 1383, + Y = 117, + Width = 592, + Height = 8 + } +}; +root.SysMesBoxDisplay.BoxDecoration = name .. "BoxDecoration"; + +root.Sprites[name .. "SelectionLeftPart"] = { + Sheet = sheet, + Bounds = { + X = 502, + Y = 51, + Width = 144, + Height = 38 + } +}; +root.SysMesBoxDisplay.SelectionLeftPart = name .. "SelectionLeftPart"; + +root.Sprites[name .. "SelectionRightPart"] = { + Sheet = sheet, + Bounds = { + X = 634, + Y = 51, + Width = 24, + Height = 38 + } +}; +root.SysMesBoxDisplay.SelectionRightPart = name .. "SelectionRightPart"; + +root.Sprites[name .. "SelectionMiddlePart"] = { + Sheet = sheet, + Bounds = { + X = 515, + Y = 51, + Width = 132, + Height = 38 + } +}; +root.SysMesBoxDisplay.SelectionMiddlePart = name .. "SelectionMiddlePart"; diff --git a/profiles/sghd/hud/tipsnotification.lua b/profiles/sghd/hud/tipsnotification.lua new file mode 100644 index 000000000..4d80584c8 --- /dev/null +++ b/profiles/sghd/hud/tipsnotification.lua @@ -0,0 +1,3 @@ +root.TipsNotification = { + Type = TipsNotificationType.None, +}; diff --git a/profiles/sghd/hud/titlemenu.lua b/profiles/sghd/hud/titlemenu.lua new file mode 100644 index 000000000..1e909a27a --- /dev/null +++ b/profiles/sghd/hud/titlemenu.lua @@ -0,0 +1,320 @@ +root.TitleMenu = { + Type = TitleMenuType.SGHD, + DrawType = DrawComponentType.SystemMenu, + PressToStartX = 72, + PressToStartY = 595, + PressToStartAnimDurationIn = 0.5, + PressToStartAnimDurationOut = 0.5, + PressToStartSprite = "TitleMenuPressToStart", + IntroBackgroundSprite = "TitleMenuIntroBackground", + BackgroundSprite = "TitleMenuBackground", + ExclMarkLogoSprite = "ExclMarkLogo", + ExclMarkLogoX = 614, + ExclMarkLogoY = 316, + CopyrightTextSprite = "CopyrightText", + CopyrightTextX = 72, + CopyrightTextY = 675, + SpinningCircleSprite = "SpinningCircle", + SpinningCircleX = 610.5, + SpinningCircleY = -285.5, + SpinningCircleAnimationDuration = 15, + ItemHighlightSprite = "TitleMenuItemHighlight", + ItemHighlightOffsetX = 73, + ItemHighlightOffsetY = 7, + ItemPadding = 40, + ItemYBase = 69, + ItemFadeInDuration = 0.3, + ItemFadeOutDuration = 0.6, + SecondaryItemFadeInDuration = 0.2, + SecondaryItemFadeOutDuration = 0.2, + PrimaryFadeInDuration = 0.3, + PrimaryFadeOutDuration = 0.3, + SecondaryFadeInDuration = 0.512, + SecondaryFadeOutDuration = 0.512, + ItemHyperUpLine = "TitleMenuItemHyperUpLine", + ItemSuperUpLine = "TitleMenuItemSuperUpLine", + ItemUpLine = "TitleMenuItemUpLine", + ItemStraightLine = "TitleMenuItemStraightLine", + ItemDownLine = "TitleMenuItemDownLine", + ItemSuperDownLine = "TitleMenuItemSuperDownLine", + ItemLoadQuickSprite = "TitleMenuItemLoadQuick", + SecondaryItemX = 320, + ItemLoadY = 109, + ItemLoadQuickY = 83, + ItemLoadSprite = "TitleMenuItemLoad", + ItemLoadQuickHighlightedSprite = "TitleMenuItemLoadQuickHighlighted", + ItemLoadHighlightedSprite = "TitleMenuItemLoadHighlighted", + SecondaryItemHighlightSprite = "TitleMenuSecondaryItemHighlight", + ItemClearListY = 71, + ItemCGLibraryY = 97, + ItemSoundLibraryY = 123, + ItemMovieLibraryY = 149, + ItemTipsY = 175, + ItemTrophyY = 201, + ItemConfigY = 163, + ItemSystemSaveY = 189, + SecondaryItemHighlightX = 286, + SecondaryMenuPaddingY = 26, + SecondaryMenuLoadOffsetY = 76, + SecondaryMenuLineX = 241, + SecondaryMenuLoadLineY = 93, + SecondaryMenuLoadQuickLineY = 119, + SecondaryMenuExtraClearY = 81, + SecondaryMenuExtraCGY = 107, + SecondaryMenuExtraSoundY = 133, + SecondaryMenuExtraMovieY = 159, + SecondaryMenuExtraTipsY = 159, + SecondaryMenuExtraTrophyY = 159, + SecondaryMenuSystemConfigY = 173, + SecondaryMenuSystemSaveY = 199, + MenuEntriesNum = 14, + MenuEntriesSprites = {}, + MenuEntriesHighlightedSprites = {}, + LineNum = 6, + LineEntriesSprites = {} +}; + +for i = 0, 3 do + root.Sprites["TitleMenuEntry" .. i] = { + Sheet = "Title", + Bounds = { + X = 1151, + Y = 101 + i * 25, + Width = 188, + Height = 23 + } + }; + root.TitleMenu.MenuEntriesSprites[#root.TitleMenu.MenuEntriesSprites + 1] = "TitleMenuEntry" .. i; +end + +for i = 0, 9 do + root.Sprites["TitleMenuEntry" .. (i + 4)] = { + Sheet = "Title", + Bounds = { + X = 1369, + Y = 684 + i * 22, + Width = 216, + Height = 20 + } + }; + root.TitleMenu.MenuEntriesSprites[#root.TitleMenu.MenuEntriesSprites + 1] = "TitleMenuEntry" .. (i + 4); +end + +for i = 0, 3 do + root.Sprites["TitleMenuEntryHighlighted" .. i] = { + Sheet = "Title", + Bounds = { + X = 1151, + Y = 1 + i * 25, + Width = 188, + Height = 23 + } + }; + root.TitleMenu.MenuEntriesHighlightedSprites[#root.TitleMenu.MenuEntriesHighlightedSprites + 1] = "TitleMenuEntryHighlighted" .. i; +end + +for i = 0, 9 do + root.Sprites["TitleMenuEntryHighlighted" .. (i + 4)] = { + Sheet = "Title", + Bounds = { + X = 1151, + Y = 684 + i * 22, + Width = 216, + Height = 20 + } + }; + root.TitleMenu.MenuEntriesHighlightedSprites[#root.TitleMenu.MenuEntriesHighlightedSprites + 1] = "TitleMenuEntryHighlighted" .. (i + 4); +end + +root.Sprites["TitleMenuPressToStart"] = { + Sheet = "Title", + Bounds = { X = 1, Y = 921, Width = 313, Height = 28 }, +}; + +root.Sprites["ExclMarkLogo"] = { + Sheet = "Title", + Bounds = { X = 831, Y = 895, Width = 82, Height = 128 }, +}; + +root.Sprites["CopyrightText"] = { + Sheet = "Title", + Bounds = { X = 193, Y = 891, Width = 380, Height = 24 }, +}; + +root.Sprites["SpinningCircle"] = { + Sheet = "Title", + Bounds = { X = 1366, Y = 1, Width = 681, Height = 681 }, +}; + +root.Sprites["TitleMenuIntroBackground"] = { + Sheet = "Title", + Bounds = { X = 0, Y = 0, Width = 1280, Height = 720 }, +}; + +root.Sprites["TitleMenuBackground"] = { + Sheet = "Title", + Bounds = { X = 0, Y = 0, Width = 1920, Height = 1080 }, +}; + +root.Sprites["TitleMenuItemHighlight"] = { + Sheet = "Title", + Bounds = { X = 915, Y = 951, Width = 244, Height = 36 }, +}; + +root.Sprites["TitleMenuItemHyperUpLine"] = { + Sheet = "Title", + Bounds = { X = 1805, Y = 686, Width = 51, Height = 80 }, +}; + +root.Sprites["TitleMenuItemSuperUpLine"] = { + Sheet = "Title", + Bounds = { X = 1805, Y = 776, Width = 51, Height = 54 }, +}; + +root.Sprites["TitleMenuItemUpLine"] = { + Sheet = "Title", + Bounds = { X = 1805, Y = 845, Width = 51, Height = 28 }, +}; + +root.Sprites["TitleMenuItemStraightLine"] = { + Sheet = "Title", + Bounds = { X = 1805, Y = 888, Width = 51, Height = 2 }, +}; + +root.Sprites["TitleMenuItemDownLine"] = { + Sheet = "Title", + Bounds = { X = 1805, Y = 910, Width = 51, Height = 28 }, +}; + +root.Sprites["TitleMenuItemSuperDownLine"] = { + Sheet = "Title", + Bounds = { X = 1805, Y = 959, Width = 51, Height = 54 }, +}; + +root.TitleMenu.LineEntriesSprites[#root.TitleMenu.LineEntriesSprites + 1] = "TitleMenuItemHyperUpLine"; +root.TitleMenu.LineEntriesSprites[#root.TitleMenu.LineEntriesSprites + 1] = "TitleMenuItemSuperUpLine"; +root.TitleMenu.LineEntriesSprites[#root.TitleMenu.LineEntriesSprites + 1] = "TitleMenuItemUpLine"; +root.TitleMenu.LineEntriesSprites[#root.TitleMenu.LineEntriesSprites + 1] = "TitleMenuItemStraightLine"; +root.TitleMenu.LineEntriesSprites[#root.TitleMenu.LineEntriesSprites + 1] = "TitleMenuItemDownLine"; +root.TitleMenu.LineEntriesSprites[#root.TitleMenu.LineEntriesSprites + 1] = "TitleMenuItemSuperDownLine"; + +root.Sprites["TitleMenuItemLoadQuick"] = { + Sheet = "Title", + Bounds = { X = 1369, Y = 684, Width = 216, Height = 20 }, +}; + +root.Sprites["TitleMenuItemLoad"] = { + Sheet = "Title", + Bounds = { X = 1369, Y = 706, Width = 216, Height = 20 }, +}; + +root.Sprites["TitleMenuItemLoadQuickHighlighted"] = { + Sheet = "Title", + Bounds = { X = 1151, Y = 684, Width = 216, Height = 20 }, +}; + +root.Sprites["TitleMenuItemLoadHighlighted"] = { + Sheet = "Title", + Bounds = { X = 1151, Y = 706, Width = 216, Height = 20 }, +}; + +root.Sprites["TitleMenuSecondaryItemHighlight"] = { + Sheet = "Title", + Bounds = { X = 915, Y = 989, Width = 285, Height = 34 }, +}; + +root.TitleMenu = { + Type = TitleMenuType.SGHD, + DrawType = DrawComponentType.SystemMenu, + BackgroundSprite = "TitleMenuBackground", + BackgroundX = 0.0, + BackgroundY = 0.0, + + PressToStartX = 830, + PressToStartY = 620, + PressToStartAnimDurationIn = 0.7, + PressToStartAnimDurationOut = 0.7, + PressToStartAnimFastDurationIn = 0.1, + PressToStartAnimFastDurationOut = 0.1, + PressToStartSprite = "TitleMenuPressToStart", + + MenuX = 1555, + MenuY = 110, + MenuEntriesNum = 5, + MenuEntriesSprites = { "TitleMenuEntryStart", "TitleMenuEntryLoad", "TitleMenuEntryExtra", "TitleMenuEntryConfig", "TitleMenuEntryHelp" }, + MenuEntriesHighlightedSprites = { "TitleMenuEntryStartHighlighted", "TitleMenuEntryLoadHighlighted", "TitleMenuEntryExtraHighlighted", "TitleMenuEntryConfigHighlighted", "TitleMenuEntryHelpHighlighted" }, + MenuEntriesSpacingY = 75, + MenuStartId = 0, + MenuLoadId = 1, + MenuExtraId = 2, + MenuConfigId = 3, + MenuHelpId = 4, +}; + +root.Sprites["TitleMenuBackground"] = { + Sheet = "Title", + Bounds = { X = 0, Y = 0, Width = 1920, Height = 1080 }, +}; + +root.Sprites["TitleMenuPressToStart"] = { + Sheet = "Title", + Bounds = { X = 140, Y = 1080, Width = 360, Height = 50 }, +}; + +MenuEntryWidth = 200; +MenuEntryHeight = 50; +MenuEntrySheet = "Title"; +MenuEntryFirstRowX = 1920; +MenuEntrySecondRowX = 1920 + MenuEntryWidth; +MenuEntryThirdRowX = 1920 + MenuEntryWidth * 2; +MenuEntryFourthRowX = 1920 + MenuEntryWidth * 3; + +root.Sprites["TitleMenuEntryStartHighlighted"] = { + Sheet = MenuEntrySheet, + Bounds = { X = MenuEntryFirstRowX, Y = 0, Width = MenuEntryWidth, Height = MenuEntryHeight }, +}; + +root.Sprites["TitleMenuEntryLoadHighlighted"] = { + Sheet = MenuEntrySheet, + Bounds = { X = MenuEntryFirstRowX, Y = MenuEntryHeight * 1, Width = MenuEntryWidth, Height = MenuEntryHeight }, +}; + +root.Sprites["TitleMenuEntryExtraHighlighted"] = { + Sheet = MenuEntrySheet, + Bounds = { X = MenuEntryFirstRowX, Y = MenuEntryHeight * 2, Width = MenuEntryWidth, Height = MenuEntryHeight }, +}; + +root.Sprites["TitleMenuEntryConfigHighlighted"] = { + Sheet = MenuEntrySheet, + Bounds = { X = MenuEntryFirstRowX, Y = MenuEntryHeight * 3, Width = MenuEntryWidth, Height = MenuEntryHeight }, +}; + +root.Sprites["TitleMenuEntryHelpHighlighted"] = { + Sheet = MenuEntrySheet, + Bounds = { X = MenuEntryThirdRowX, Y = 0, Width = MenuEntryWidth, Height = MenuEntryHeight }, +}; + +root.Sprites["TitleMenuEntryStart"] = { + Sheet = MenuEntrySheet, + Bounds = { X = MenuEntrySecondRowX, Y = 0, Width = MenuEntryWidth, Height = MenuEntryHeight }, +}; + +root.Sprites["TitleMenuEntryLoad"] = { + Sheet = MenuEntrySheet, + Bounds = { X = MenuEntrySecondRowX, Y = MenuEntryHeight * 1, Width = MenuEntryWidth, Height = MenuEntryHeight }, +}; + +root.Sprites["TitleMenuEntryExtra"] = { + Sheet = MenuEntrySheet, + Bounds = { X = MenuEntrySecondRowX, Y = MenuEntryHeight * 2, Width = MenuEntryWidth, Height = MenuEntryHeight }, +}; + +root.Sprites["TitleMenuEntryConfig"] = { + Sheet = MenuEntrySheet, + Bounds = { X = MenuEntrySecondRowX, Y = MenuEntryHeight * 3, Width = MenuEntryWidth, Height = MenuEntryHeight }, +}; + +root.Sprites["TitleMenuEntryHelp"] = { + Sheet = MenuEntrySheet, + Bounds = { X = MenuEntryFourthRowX, Y = 0, Width = MenuEntryWidth, Height = MenuEntryHeight }, +}; diff --git a/profiles/sghd/nametag.lua b/profiles/sghd/nametag.lua new file mode 100644 index 000000000..332157a43 --- /dev/null +++ b/profiles/sghd/nametag.lua @@ -0,0 +1,16 @@ +-- TODO: Copied from SGPS3 and CHLCC - check and fix + +include('common/nametag.lua'); + +MakeNameTag({ + Sheet = "Data01", + X = 0, + Y = 0, + LeftWidth = 195, + LineWidth = 1, + RightWidth = 200, + Height = 11, + ScreenX = 400, + ScreenY = 680, + BaseLineWidth = 0 +}); diff --git a/profiles/sghd/savedata.lua b/profiles/sghd/savedata.lua new file mode 100644 index 000000000..a2288452f --- /dev/null +++ b/profiles/sghd/savedata.lua @@ -0,0 +1,4 @@ +root.SaveData = { + Type = SaveDataType.None, + SaveFilePath = "games/sghd/savedata/SYSTEM.DAT", +}; diff --git a/profiles/sghd/scriptvars.lua b/profiles/sghd/scriptvars.lua new file mode 100644 index 000000000..7593c2f39 --- /dev/null +++ b/profiles/sghd/scriptvars.lua @@ -0,0 +1,97 @@ +-- TODO: Copied from SGPS3 - check and fix + +local sv = root.ScriptVars; + +sv.SW_TITLEDISPCT = 1014; +sv.SW_TITLEMASKALPHA = 1033; +sv.SW_TITLEMASKCOLOR = 1034; +sv.SW_SYSSEL = 1028; +sv.SW_SYSTEMMENUCHG = 1040; +sv.SW_SYSTEMMENUALPHA = 1041; +sv.SW_SYSMENUCT = 1042; +sv.SW_MASK1ALPHA_OFS = 1586; +sv.SW_MASK2ALPHA_OFS = 1587; +sv.SW_MASK3ALPHA_OFS = 1588; +sv.SW_MAINTHDP = 1704; +sv.SW_SAVEERRORCODE = 1733; +sv.SW_TITLECUR1 = 1740; +sv.SW_TITLECUR2 = 1741; +sv.SW_SVSENO = 2001; +sv.SW_SVBGMNO = 2005; +sv.SW_SVSCRNO1 = 2006; +sv.SW_SVSCRNO2 = 2007; +sv.SW_SVSCRNO3 = 2008; +sv.SW_SVSCRNO4 = 2009; +sv.SW_SVBGNO1 = 2010; +sv.SW_SVCHANO1 = 2018; +sv.SW_TITLE = 2300; +sv.SW_PLAYTIME = 2304; +sv.SW_MESWINDOW_COLOR = 7777; +sv.SW_BGMREQNO = 2310; +sv.SW_SEREQNO = 2311; +sv.SW_BGMVOL = 2314; +sv.SW_SEVOL = 2315; +sv.SW_SCRIPTNO0 = 2320; +sv.SW_SCRIPTNO1 = 2321; +sv.SW_SCRIPTNO2 = 2322; +sv.SW_SCRIPTNO3 = 2323; +sv.SW_SCRIPTNO4 = 2324; +sv.SW_SCRIPTNO5 = 2325; +sv.SW_SCRIPTNO6 = 2326; +sv.SW_SCRIPTNO7 = 2327; +sv.SW_MASK1COLOR = 2329; +sv.SW_MASK1ALPHA = 2330; +sv.SW_MASK1PRI = 2331; +sv.SW_MASK1POSX = 2332; +sv.SW_MASK1POSY = 2333; +sv.SW_MASK1SIZEX = 2334; +sv.SW_MASK1SIZEY = 2335; +sv.SW_MESMODE0 = 3173; +sv.SW_CHA1POSX = 2600; +sv.SW_CHA1POSY = 2601; +sv.SW_CHA1ROTX = 2602; +sv.SW_CHA1ROTY = 2603; +sv.SW_CHA1ROTZ = 2604; +sv.SW_CHA1ALPHA = 2607; +sv.SW_CHA1NO = 2609; +sv.SW_CHA1PRI = 2610; +sv.SW_CHA1POSE = 2611; +sv.SW_CHA1FACE = 2612; +sv.SW_CHA1EX = 2613; +sv.SW_CHA1FADECT = 2614; +sv.SW_CHA1FADETYPE = 2615; +sv.SW_CHA1SURF = 1850; +sv.SW_BG1POSX = 2400; +sv.SW_BG1POSY = 2401; +sv.SW_BG1SX = 2402; +sv.SW_BG1SY = 2403; +sv.SW_BG1SIZE = 2404; +sv.SW_BG1LX = 2405; +sv.SW_BG1LY = 2406; +sv.SW_BG1NO = 2407; +sv.SW_BG1PRI = 2408; +sv.SW_BG1DISPMODE = 2409; +sv.SW_BG1FADECT = 2410; +sv.SW_BG1FADETYPE = 2411; +sv.SW_BG1ALPHA = 2413; +sv.SW_BG1MASKNO = 2414; +sv.SW_BG1MASKFADERANGE = 2415; +sv.SW_BG1POSX_OFS = 1200; +sv.SW_BG1POSY_OFS = 1201; +sv.SW_BG1SX_OFS = 1202; +sv.SW_BG1SY_OFS = 1203; +sv.SW_BG1SIZE_OFS = 1204; +sv.SW_BG1LX_OFS = 1205; +sv.SW_BG1LY_OFS = 1206; +sv.SW_BG1ALPHA_OFS = 1208; +sv.SW_CHA1POSY_OFS = 1301; +sv.SW_CHA1ALPHA_OFS = 1307; +sv.SW_BG1SURF = 1800; +sv.SW_SAVEFILESTATUS = 2122; +sv.SW_SAVEFILENO = 2123; +sv.SW_BGLINK = 2580; +sv.SW_BGLINK2 = 2581; +sv.SW_EFF_CAP_PRI = 3268; +sv.SW_EFF_CAP_BUF = 3269; +sv.SW_EFF_CAP_PRI2 = 3270; +sv.SW_EFF_CAP_BUF2 = 3271; diff --git a/profiles/sghd/sprites.lua b/profiles/sghd/sprites.lua new file mode 100644 index 000000000..847cf0f34 --- /dev/null +++ b/profiles/sghd/sprites.lua @@ -0,0 +1,19 @@ +root.SpriteSheets = { + ["Data01"] = { + Path = { Mount = "system", Id = 6 }, + DesignWidth = 3072, + DesignHeight = 1788 + }, + ["Title"] = { + Path = { Mount = "system", Id = 30 }, + DesignWidth = 3072, + DesignHeight = 1536 + }, + ["Font"] = { + Path = { Mount = "system", Id = 9 }, + DesignWidth = 3072, + DesignHeight = 2208 + }, +}; + +root.Sprites = {}; diff --git a/profiles/sghd/tipssystem.lua b/profiles/sghd/tipssystem.lua new file mode 100644 index 000000000..787fff547 --- /dev/null +++ b/profiles/sghd/tipssystem.lua @@ -0,0 +1,3 @@ +root.TipsSystem = { + Type = TipsSystemType.None, +}; \ No newline at end of file diff --git a/profiles/sghd/vfs.lua b/profiles/sghd/vfs.lua new file mode 100644 index 000000000..f6d3d33cc --- /dev/null +++ b/profiles/sghd/vfs.lua @@ -0,0 +1,15 @@ +root.Vfs = { + Mounts = { + ["script"] = {"games/sghd/gamedata/script.mpk"}, + ["system"] = {"games/sghd/gamedata/system.mpk"}, + ["bgm"] = {"games/sghd/gamedata/bgm.mpk"}, + ["se"] = {"games/sghd/gamedata/se.mpk"}, + ["voice"] = {"games/sghd/gamedata/voice.mpk"}, + ["bg"] = {"games/sghd/gamedata/bg.mpk"}, + ["chara"] = {"games/sghd/gamedata/chara.mpk"}, + ["mask"] = {"games/sghd/gamedata/mask.mpk"}, + ["manual"] = {"games/sghd/gamedata/manual.mpk"}, + ["mgsshader"] = {"games/sghd/gamedata/mgsshader.mpk"}, + ["shader"] = {"games/sghd/gamedata/shader.mpk"} + } +}; diff --git a/src/games/sghd/dialoguebox.cpp b/src/games/sghd/dialoguebox.cpp new file mode 100644 index 000000000..7b681a606 --- /dev/null +++ b/src/games/sghd/dialoguebox.cpp @@ -0,0 +1,48 @@ +#include "dialoguebox.h" + +#include "../../renderer2d.h" +#include "../../profile/dialogue.h" +#include "../../profile/game.h" +#include "../../profile/games/sg/dialoguebox.h" +#include "../../mem.h" +#include "../../profile/scriptvars.h" + +namespace Impacto { +namespace SGHD { + +using namespace Impacto::Profile::ScriptVars; +using namespace Impacto::Profile::Dialogue; +using namespace Impacto::Profile::SGHD::DialogueBox; + +void DialogueBox::Update(float dt) { + if (TextBoxEffect.State != AS_Playing) { + TextBoxEffect.DurationIn = ADVBoxEffectDuration; + TextBoxEffect.LoopMode = ALM_Loop; + TextBoxEffect.StartIn(); + } + + TextBoxEffect.Update(dt); +} + +void DialogueBox::Render(DialoguePageMode mode, bool hasName, float nameWidth, + uint32_t nameId, float opacity) { + glm::vec4 col = ScrWorkGetColor(SW_MESWINDOW_COLOR); + col.a = 1.0f; + if (mode == DPM_ADV) { + Renderer2D::DrawCCMessageBox(ADVBoxSprite, ADVBoxMask, ADVBoxPos, col, + opacity * 272, 16, TextBoxEffect.Progress); + if (hasName) { + Renderer2D::DrawSprite(NamePlateMainSprites[nameId], + ADVBoxNamePlateMainPos); + Renderer2D::DrawSprite(NamePlateLabelSprites[nameId], + ADVBoxNamePlateLabelPos); + } + } else { + glm::vec4 nvlBoxTint(0.0f, 0.0f, 0.0f, opacity * NVLBoxMaxOpacity); + Renderer2D::DrawRect( + RectF(0, 0, Profile::DesignWidth, Profile::DesignHeight), nvlBoxTint); + } +} + +} // namespace SGHD +} // namespace Impacto diff --git a/src/games/sghd/dialoguebox.h b/src/games/sghd/dialoguebox.h new file mode 100644 index 000000000..04eacec22 --- /dev/null +++ b/src/games/sghd/dialoguebox.h @@ -0,0 +1,20 @@ +#pragma once + +#include "../../hud/dialoguebox.h" +#include "../../animation.h" + +namespace Impacto { +namespace SGHD { + +class DialogueBox : public Impacto::DialogueBox { + public: + void Update(float dt) override; + void Render(DialoguePageMode mode, bool hasName, float nameWidth, + uint32_t nameId, float opacity) override; + + private: + Animation TextBoxEffect; +}; + +} // namespace SGHD +} // namespace Impacto diff --git a/src/games/sghd/sysmesbox.cpp b/src/games/sghd/sysmesbox.cpp new file mode 100644 index 000000000..7d8f464a0 --- /dev/null +++ b/src/games/sghd/sysmesbox.cpp @@ -0,0 +1,207 @@ +#include "sysmesbox.h" + +#include "../../profile/ui/sysmesbox.h" +#include "../../profile/games/sghd/sysmesbox.h" +#include "../../profile/dialogue.h" +#include "../../profile/game.h" +#include "../../profile/scriptvars.h" +#include "../../mem.h" +#include "../../renderer2d.h" + +namespace Impacto { +namespace UI { +namespace SGHD { + +using namespace Impacto::UI::Widgets; +using namespace Impacto::Profile::ScriptVars; +using namespace Impacto::Profile::SysMesBox; +using namespace Impacto::Profile::SGHD::SysMesBox; + +void SysMesBox::ChoiceItemOnClick(Button* target) { + ScrWork[SW_SYSSEL] = target->Id; + ChoiceMade = true; +} + +void SysMesBox::Show() { + MessageItems = new Widgets::Group(this); + ChoiceItems = new Widgets::Group(this); + + Sprite nullSprite = Sprite(); + nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); + + auto onClick = + std::bind(&SysMesBox::ChoiceItemOnClick, this, std::placeholders::_1); + + float diff = 0.0f; + float maxWidth = FLT_MIN; + for (int i = 0; i < MessageCount; i++) { + if (maxWidth < MessageWidths[i]) maxWidth = MessageWidths[i]; + } + if (maxWidth < BoxMinimumWidth) maxWidth = BoxMinimumWidth; + + for (int i = 0; i < MessageCount; i++) { + diff = Messages[i][0].DestRect.X - (TextX - (maxWidth / 2.0f)); + for (int j = 0; j < MessageLengths[i]; j++) { + Messages[i][j].Colors = Profile::Dialogue::ColorTable[0]; + Messages[i][j].DestRect.X -= diff; + Messages[i][j].DestRect.Y = TextMiddleY + (i * TextLineHeight); + } + + Label* message = new Label(Messages[i], MessageLengths[i], MessageWidths[i], + TextFontSize, true); + + MessageItems->Add(message, FDIR_DOWN); + } + + float totalChoiceWidth = 0.0f; + for (int i = 0; i < ChoiceCount; i++) { + totalChoiceWidth += ChoiceWidths[i] + ChoicePadding; + } + if (maxWidth < totalChoiceWidth) maxWidth = totalChoiceWidth; + if (maxWidth < MinMaxMesWidth) maxWidth = MinMaxMesWidth; + + ChoiceX = (maxWidth / 2.0f) - totalChoiceWidth + ChoiceXBase; + + float tempChoiceX = ChoiceX; + + for (int i = 0; i < ChoiceCount; i++) { + diff = Choices[i][0].DestRect.X - tempChoiceX; + for (int j = 0; j < ChoiceLengths[i]; j++) { + Choices[i][j].Colors = Profile::Dialogue::ColorTable[0]; + Choices[i][j].DestRect.X -= diff; + Choices[i][j].DestRect.Y = ChoiceY; + } + + Button* choice = new Button( + i, nullSprite, nullSprite, SelectionHighlight, + glm::vec2(Choices[i][0].DestRect.X, Choices[i][0].DestRect.Y)); + + choice->SetText(Choices[i], ChoiceLengths[i], ChoiceWidths[i], + Profile::Dialogue::DefaultFontSize, true); + choice->OnClickHandler = onClick; + + ChoiceItems->Add(choice, FDIR_LEFT); + + tempChoiceX += ChoiceWidths[i] + ChoicePadding; + } + + FadeAnimation.StartIn(); + MessageItems->Show(); + MessageItems->HasFocus = false; + if (ChoiceCount != 0) ChoiceItems->Show(); + State = Showing; + + if (UI::FocusedMenu != 0) { + LastFocusedMenu = UI::FocusedMenu; + LastFocusedMenu->IsFocused = false; + } + IsFocused = true; + UI::FocusedMenu = this; +} + +void SysMesBox::Hide() { + FadeAnimation.StartOut(); + State = Hiding; + if (LastFocusedMenu != 0) { + UI::FocusedMenu = LastFocusedMenu; + LastFocusedMenu->IsFocused = true; + } else { + UI::FocusedMenu = 0; + } + IsFocused = false; +} + +void SysMesBox::Update(float dt) { + UpdateInput(); + + FadeAnimation.Update(dt); + if (State != Hidden) { + if (FadeAnimation.IsIn()) State = Shown; + if (FadeAnimation.IsOut()) State = Hidden; + + if (IsFocused) { + MessageItems->Update(dt); + ChoiceItems->Update(dt); + } + } +} + +void SysMesBox::Render() { + if (State != Hidden) { + glm::vec4 col(1.0f, 1.0f, 1.0f, FadeAnimation.Progress); + + float diff = 0.0f; + float maxWidth = FLT_MIN; + for (int i = 0; i < MessageCount; i++) { + if (maxWidth < MessageWidths[i]) maxWidth = MessageWidths[i]; + } + if (maxWidth < BoxMinimumWidth) maxWidth = BoxMinimumWidth; + + float leftStartX = BoxMiddleBaseX - (maxWidth / 2.0f); + Renderer2D::DrawSprite(BoxPartLeft, glm::vec2(leftStartX, BoxY), col); + + BoxPartMiddle.BaseScale = + glm::vec2((maxWidth - BoxRightBaseWidth) / BoxMiddleBaseWidth, 1.0f); + Renderer2D::DrawSprite( + BoxPartMiddle, glm::vec2(leftStartX + BoxRightRemainPad, BoxY), col); + + Renderer2D::DrawSprite( + BoxPartRight, + glm::vec2(leftStartX + maxWidth + BoxRightBaseWidth, BoxY), col); + + MessageItems->Tint.a = FadeAnimation.Progress; + MessageItems->Render(); + ChoiceItems->Tint.a = FadeAnimation.Progress; + ChoiceItems->Render(); + } +} + +void SysMesBox::Init() { + ChoiceMade = false; + MessageCount = 0; + ChoiceCount = 0; + + FadeAnimation.DurationIn = FadeInDuration; + FadeAnimation.DurationOut = FadeOutDuration; + FadeAnimation.Direction = 1; + FadeAnimation.LoopMode = ALM_Stop; + + memset(Messages, 0, (8 * 255) * sizeof(ProcessedTextGlyph)); + memset(Choices, 0, (8 * 255) * sizeof(ProcessedTextGlyph)); +} + +void SysMesBox::AddMessage(uint8_t* str) { + Impacto::Vm::Sc3VmThread dummy; + dummy.Ip = str; + int len = TextLayoutPlainLine(&dummy, 255, Messages[MessageCount], + Profile::Dialogue::DialogueFont, TextFontSize, + Profile::Dialogue::ColorTable[10], 1.0f, + glm::vec2(TextX, 0.0f), TextAlignment::Left); + float mesLen = 0.0f; + for (int i = 0; i < len; i++) { + mesLen += Messages[MessageCount][i].DestRect.Width; + } + MessageWidths[MessageCount] = mesLen; + MessageLengths[MessageCount] = len; + MessageCount++; +} + +void SysMesBox::AddChoice(uint8_t* str) { + Impacto::Vm::Sc3VmThread dummy; + dummy.Ip = str; + int len = TextLayoutPlainLine(&dummy, 255, Choices[ChoiceCount], + Profile::Dialogue::DialogueFont, TextFontSize, + Profile::Dialogue::ColorTable[10], 1.0f, + glm::vec2(TextX, 0.0f), TextAlignment::Left); + float mesLen = 0.0f; + for (int i = 0; i < len; i++) { + mesLen += Choices[ChoiceCount][i].DestRect.Width; + } + ChoiceWidths[ChoiceCount] = mesLen; + ChoiceLengths[ChoiceCount] = len; + ChoiceCount++; +} + +} // namespace SGHD +} // namespace UI +} // namespace Impacto diff --git a/src/games/sghd/sysmesbox.h b/src/games/sghd/sysmesbox.h new file mode 100644 index 000000000..0739516b6 --- /dev/null +++ b/src/games/sghd/sysmesbox.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../../ui/sysmesbox.h" +#include "../../ui/widgets/button.h" +#include "../../ui/widgets/label.h" +#include "../../text.h" + +namespace Impacto { +namespace UI { +namespace SGHD { + +class SysMesBox : public UI::SysMesBox { + public: + virtual void Show() override; + virtual void Hide() override; + virtual void Update(float dt) override; + virtual void Render() override; + + virtual void Init(); + virtual void AddMessage(uint8_t* str) override; + virtual void AddChoice(uint8_t* str) override; + + private: + void ChoiceItemOnClick(UI::Widgets::Button* target); +}; + +} // namespace SGHD +} // namespace UI +} // namespace Impacto diff --git a/src/games/sghd/titlemenu.cpp b/src/games/sghd/titlemenu.cpp new file mode 100644 index 000000000..2fc6d7622 --- /dev/null +++ b/src/games/sghd/titlemenu.cpp @@ -0,0 +1,253 @@ +#include "titlemenu.h" + +#include + +#include "../../spritesheet.h" + +#include "../../profile/ui/titlemenu.h" +#include "../../profile/games/sghd/titlemenu.h" +#include "../../spritesheet.h" +#include "../../renderer/renderer.h" +#include "../../mem.h" +#include "../../profile/scriptvars.h" +#include "../../vm/interface/input.h" + +namespace Impacto { +namespace UI { +namespace SGHD { + +using namespace Impacto::Profile::TitleMenu; +using namespace Impacto::Profile::SGHD::TitleMenu; +using namespace Impacto::Profile::ScriptVars; + +using namespace Impacto::Vm::Interface; + +static glm::vec2 MainMenuButtonPos(int id) { + // Buttons are arranged top-to-bottom in one column + // All buttons are the same size + const RectF bounds = MenuEntriesSprites[0].Bounds; + const float offsetY = (bounds.Height + MenuEntriesSpacingY) * id; + return glm::vec2(MenuX, MenuY + offsetY); +} + +void TitleMenu::MenuButtonOnClick(Widgets::Button* target) { + ScrWork[SW_TITLECUR1] = target->Id; + SetFlag(SF_TITLEEND, 1); + AllowsScriptInput = true; +} + +TitleMenu::TitleMenu() { + MainItems = new Widgets::Group(this, glm::vec2(MenuX, MenuY)); + MainItems->Hide(); + + auto onClick = + std::bind(&TitleMenu::MenuButtonOnClick, this, std::placeholders::_1); + + // Main menu buttons + + // Steins;Gate main menu buttons don't distinguish between "highlighted" and + // "focused". Therefore, both are passed as the same. + + // Start new game button + int id = MenuStartId; + Start = new TitleButton(id, MenuEntriesSprites[id], MenuEntriesHSprites[id], + MenuEntriesHSprites[id], MainMenuButtonPos(id)); + Start->OnClickHandler = onClick; + MainItems->Add(Start, FDIR_DOWN); + + // Load menu button + id = MenuLoadId; + Load = new TitleButton(id, MenuEntriesSprites[id], MenuEntriesHSprites[id], + MenuEntriesHSprites[id], MainMenuButtonPos(id)); + // TODO: Replace w/ proper handler + Load->OnClickHandler = onClick; + MainItems->Add(Load, FDIR_DOWN); + + // Extras menu button + id = MenuExtraId; + Extra = new TitleButton(id, MenuEntriesSprites[id], MenuEntriesHSprites[id], + MenuEntriesHSprites[id], MainMenuButtonPos(id)); + // TODO: Replace w/ proper handler + Extra->OnClickHandler = onClick; + MainItems->Add(Extra, FDIR_DOWN); + + // Config menu button + id = MenuConfigId; + Config = new TitleButton(id, MenuEntriesSprites[id], MenuEntriesHSprites[id], + MenuEntriesHSprites[id], MainMenuButtonPos(id)); + // TODO: Replace w/ proper handler + Config->OnClickHandler = onClick; + MainItems->Add(Config, FDIR_DOWN); + + // Help menu button + id = MenuHelpId; + Help = new TitleButton(id, MenuEntriesSprites[id], MenuEntriesHSprites[id], + MenuEntriesHSprites[id], MainMenuButtonPos(id)); + // TODO: Replace w/ proper handler + Help->OnClickHandler = onClick; + MainItems->Add(Help, FDIR_DOWN); + + Sprite nullSprite = Sprite(); + nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); + PressToStartAnimation = Animation(); + PressToStartAnimation.DurationIn = + Profile::TitleMenu::PressToStartAnimDurationIn; + PressToStartAnimation.DurationOut = + Profile::TitleMenu::PressToStartAnimDurationOut; + PressToStartAnimation.LoopMode = ALM_ReverseDirection; + PressToStartAnimation.StartIn(); + PressToStartAnimation = Animation(); + PressToStartAnimation.DurationIn = + Profile::TitleMenu::PressToStartAnimDurationIn; + PressToStartAnimation.DurationOut = + Profile::TitleMenu::PressToStartAnimDurationOut; + PressToStartAnimation.LoopMode = ALM_ReverseDirection; + // TODO: Remove + PressToStartAnimation.StartIn(); +} + +void TitleMenu::Show() { + if (State != Shown) { + State = Shown; + MainItems->Show(); + if (UI::FocusedMenu != 0) { + LastFocusedMenu = UI::FocusedMenu; + LastFocusedMenu->IsFocused = false; + } + IsFocused = true; + UI::FocusedMenu = this; + AllowsScriptInput = true; + // The "Press ENTER" animation only plays before menu is shown + if (PressToStartAnimation.State == AS_Playing) { + PressToStartAnimation.LoopMode = ALM_Stop; + } + } +} + +void TitleMenu::Hide() { + if (State != Hidden) { + State = Hidden; + MainItems->Hide(); + if (LastFocusedMenu != nullptr) { + UI::FocusedMenu = LastFocusedMenu; + LastFocusedMenu->IsFocused = true; + } else { + UI::FocusedMenu = 0; + } + IsFocused = false; + AllowsScriptInput = true; + if (PressToStartAnimation.State == AS_Stopped) { + PressToStartAnimation.StartIn(); + } + } +} + +void TitleMenu::UpdateInput() { + Menu::UpdateInput(); + switch (State) { + case Hidden: { + // Any input should fade in the main title menu buttons + // TODO: ESC (and maybe (B)) should display quit game sysmesbox instead + if (PADinputMouseWentDown || PADinputButtonWentDown) { + TitleMenu::Show(); + } + } break; + case Shown: { + // Return to the "Press ENTER" screen + if (PADinputButtonWentDown & PAD1B) { + TitleMenu::Hide(); + return; + } + } + default: { + // TODO: During transitionary states, we should probably not accept any + // input (or cancel the transition, but that'd be more complicated) + } break; + } +} + +void TitleMenu::Update(float dt) { + UpdateInput(); + + PressToStartAnimation.Update(dt); + MainItems->Update(dt); + + /* + if (GetFlag(SF_TITLEMODE)) { + Show(); + } else { + Hide(); + } + + + // These are copied from C;C, unsure if correct + if (State != Hidden && GetFlag(SF_TITLEMODE)) { + switch (ScrWork[SW_TITLEMODE]) { + case 1: { // Press to start + PressToStartAnimation.DurationIn = PressToStartAnimDurationIn; + PressToStartAnimation.DurationOut = PressToStartAnimDurationOut; + } break; + case 2: { // Transition between Press to start and menus + PressToStartAnimation.DurationIn = PressToStartAnimFastDurationIn; + PressToStartAnimation.DurationOut = PressToStartAnimFastDurationOut; + } break; + default: { + ImpLog(LL_Warning, LC_Render, "Unknown SW_TITLEMODE %i", + SW_TITLEMODE); } break; + } + } + */ + if (GetFlag(SF_TITLEMODE)) { + Show(); + } else { + Hide(); + } + PressToStartAnimation.Update(dt); + + if (GetFlag(SF_TITLEMODE)) { + Show(); + } else { + Hide(); + } + + // These are copied from C;C, unsure if correct + if (State != Hidden && GetFlag(SF_TITLEMODE)) { + switch (ScrWork[SW_TITLEMODE]) { + case 1: { // Press to start + PressToStartAnimation.DurationIn = PressToStartAnimDurationIn; + PressToStartAnimation.DurationOut = PressToStartAnimDurationOut; + } break; + case 2: { // Transition between Press to start and menus + PressToStartAnimation.DurationIn = PressToStartAnimFastDurationIn; + PressToStartAnimation.DurationOut = PressToStartAnimFastDurationOut; + } break; + default: { + ImpLog(LL_Warning, LC_Render, "Unknown SW_TITLEMODE %i", SW_TITLEMODE); + } break; + } + } +} + +void TitleMenu::Render() { + DrawMainBackground(1.0f); + DrawStartButton(); + MainItems->Render(); +} + +inline void TitleMenu::DrawMainBackground(float opacity) { + glm::vec4 col = glm::vec4(1.0f); + col.a = 1.0f; + Renderer->DrawSprite(BackgroundSprite, glm::vec2(BackgroundX, BackgroundY), + col); +} + +inline void TitleMenu::DrawStartButton() { + glm::vec4 col = glm::vec4(1.0f); + col.a = glm::smoothstep(0.0f, 1.0f, PressToStartAnimation.Progress); + Renderer->DrawSprite(PressToStartSprite, + glm::vec2(PressToStartX, PressToStartY), col); +} + +} // namespace SGHD +} // namespace UI +} // namespace Impacto diff --git a/src/games/sghd/titlemenu.h b/src/games/sghd/titlemenu.h new file mode 100644 index 000000000..4c6ac85ce --- /dev/null +++ b/src/games/sghd/titlemenu.h @@ -0,0 +1,44 @@ +#pragma once + +#include "../../animation.h" +#include "../../ui/menu.h" +#include "../../ui/widgets/group.h" +#include "../../ui/widgets/button.h" +#include "../../ui/widgets/sghd/titlebutton.h" + +using Impacto::UI::Widgets::SGHD::TitleButton; + +namespace Impacto { +namespace UI { +namespace SGHD { + +class TitleMenu : public Menu { + public: + TitleMenu(); + + void Show(); + void Hide(); + void UpdateInput(); + void Update(float dt); + void Render(); + + private: + Animation PressToStartAnimation; + + Widgets::Group* MainItems; + TitleButton* Start; + TitleButton* Load; + TitleButton* Extra; + TitleButton* Config; + TitleButton* Help; + + void DrawMainBackground(); + void DrawStartButton(); + + void MenuButtonOnClick(Widgets::Button* target); + void DrawMainBackground(float opacity = 1.0f); +}; + +} // namespace SGHD +} // namespace UI +} // namespace Impacto diff --git a/src/profile/games/sghd/titlemenu.cpp b/src/profile/games/sghd/titlemenu.cpp new file mode 100644 index 000000000..42a0d955a --- /dev/null +++ b/src/profile/games/sghd/titlemenu.cpp @@ -0,0 +1,73 @@ +#include "titlemenu.h" +#include "../../profile_internal.h" + +#include "../../../game.h" +#include "../../../ui/ui.h" +#include "../../../games/sghd/titlemenu.h" + +namespace Impacto { +namespace Profile { +namespace SGHD { +namespace TitleMenu { + +// Background itself +Sprite BackgroundSprite; +float BackgroundX; +float BackgroundY; + +// "Press Enter" blinking prompt +float PressToStartX; +float PressToStartY; +float PressToStartAnimDurationIn; +float PressToStartAnimDurationOut; +float PressToStartAnimFastDurationIn; +float PressToStartAnimFastDurationOut; + +// Main menu +float MenuX; +float MenuY; +float MenuEntriesSpacingY; +int MenuStartId; +int MenuLoadId; +int MenuExtraId; +int MenuConfigId; +int MenuHelpId; + +void Configure() { + BackgroundSprite = EnsureGetMemberSprite("BackgroundSprite"); + BackgroundX = EnsureGetMemberFloat("BackgroundX"); + BackgroundY = EnsureGetMemberFloat("BackgroundY"); + + PressToStartX = EnsureGetMemberFloat("PressToStartX"); + PressToStartY = EnsureGetMemberFloat("PressToStartY"); + PressToStartAnimDurationIn = + EnsureGetMemberFloat("PressToStartAnimDurationIn"); + PressToStartAnimDurationOut = + EnsureGetMemberFloat("PressToStartAnimDurationOut"); + PressToStartAnimFastDurationIn = + EnsureGetMemberFloat("PressToStartAnimFastDurationIn"); + PressToStartAnimFastDurationOut = + EnsureGetMemberFloat("PressToStartAnimFastDurationOut"); + + MenuX = EnsureGetMemberFloat("MenuX"); + MenuY = EnsureGetMemberFloat("MenuY"); + MenuEntriesSpacingY = EnsureGetMemberFloat("MenuEntriesSpacingY"); + MenuStartId = EnsureGetMemberInt("MenuStartId"); + MenuLoadId = EnsureGetMemberInt("MenuLoadId"); + MenuExtraId = EnsureGetMemberInt("MenuExtraId"); + MenuConfigId = EnsureGetMemberInt("MenuConfigId"); + MenuHelpId = EnsureGetMemberInt("MenuHelpId"); + + UI::SGHD::TitleMenu* menu = new UI::SGHD::TitleMenu(); + UI::TitleMenuPtr = menu; + + auto drawType = Game::DrawComponentType::_from_integral_unchecked( + EnsureGetMemberInt("DrawType")); + + UI::Menus[drawType].push_back(UI::TitleMenuPtr); +} + +} // namespace TitleMenu +} // namespace SGHD +} // namespace Profile +} // namespace Impacto diff --git a/src/profile/games/sghd/titlemenu.h b/src/profile/games/sghd/titlemenu.h new file mode 100644 index 000000000..9a022d070 --- /dev/null +++ b/src/profile/games/sghd/titlemenu.h @@ -0,0 +1,35 @@ +#pragma once + +#include "../../../spritesheet.h" +#include "../../../games/sghd/titlemenu.h" + +namespace Impacto { +namespace Profile { +namespace SGHD { +namespace TitleMenu { + +void Configure(); + +extern Sprite BackgroundSprite; +extern float BackgroundX; +extern float BackgroundY; + +extern float PressToStartAnimFastDurationIn; +extern float PressToStartAnimFastDurationOut; + +extern float MenuX; +extern float MenuY; +extern float MenuEntriesSpacingY; + +extern int MenuStartId; +extern int MenuLoadId; +extern int MenuExtraId; +extern int MenuConfigId; +extern int MenuHelpId; + +// TODO: All the other sprites + +} // namespace TitleMenu +} // namespace SGHD +} // namespace Profile +} // namespace Impacto diff --git a/src/profile/profile_internal.cpp b/src/profile/profile_internal.cpp index 096fa372a..f58ccbefb 100644 --- a/src/profile/profile_internal.cpp +++ b/src/profile/profile_internal.cpp @@ -75,7 +75,7 @@ int PushNextTableElement() { return lua_next(LuaState, -2); } nativeType result; \ bool success = TryGet##typeName(result); \ if (!success) { \ - ImpLog(LL_Fatal, LC_Profile, "Expected %s to be " typeDesc "\n"); \ + ImpLog(LL_Fatal, LC_Profile, "Expected item to be " typeDesc "\n"); \ Window->Shutdown(); \ } \ return result; \ diff --git a/src/profile/sprites.cpp b/src/profile/sprites.cpp index dc7935d4a..62353d0d3 100644 --- a/src/profile/sprites.cpp +++ b/src/profile/sprites.cpp @@ -50,6 +50,8 @@ void LoadSpritesheets() { std::string name(EnsureGetKeyString()); Sprite& sprite = Sprites[name]; + + ImpLog(LL_Debug, LC_Profile, "Loading spritesheet %s\n", name.c_str()); sprite.Sheet = EnsureGetMemberSpriteSheet("Sheet"); sprite.Bounds = EnsureGetMemberRectF("Bounds"); if (!TryGetMemberVec2("BaseScale", sprite.BaseScale)) diff --git a/src/profile/ui/titlemenu.cpp b/src/profile/ui/titlemenu.cpp index a65d74b3e..dead4a24b 100644 --- a/src/profile/ui/titlemenu.cpp +++ b/src/profile/ui/titlemenu.cpp @@ -8,6 +8,7 @@ #include "../games/mo8/titlemenu.h" #include "../games/cc/titlemenu.h" #include "../games/cclcc/titlemenu.h" +#include "../games/sghd/titlemenu.h" #include "../../log.h" namespace Impacto { @@ -54,6 +55,10 @@ void Configure() { CC::TitleMenu::Configure(); } else if (Type == +TitleMenuType::CCLCC) { CCLCC::TitleMenu::Configure(); + } else if (Type == +TitleMenuType::SGHD) { + SGHD::TitleMenu::Configure(); + } else { + ImpLog(LL_Warning, LC_Profile, "Unknown title menu type in profile!\n"); } // if (Implementation != 0) { diff --git a/src/ui/ui.h b/src/ui/ui.h index e16e3f20d..3d974b21a 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -15,7 +15,8 @@ namespace UI { BETTER_ENUM(SystemMenuType, int, None, RNE, MO6TW, CHLCC, MO8, CCLCC) BETTER_ENUM(SaveMenuType, int, None, MO6TW, MO8, CHLCC, CCLCC) BETTER_ENUM(SysMesBoxType, int, None, RNE, Dash, CHLCC, MO6TW, Darling, CC) -BETTER_ENUM(TitleMenuType, int, None, RNE, Dash, CHLCC, MO6TW, MO8, CC, CCLCC) +BETTER_ENUM(TitleMenuType, int, None, RNE, Dash, CHLCC, MO6TW, MO8, CC, CCLCC, + SGHD) BETTER_ENUM(OptionsMenuType, int, None, MO6TW, MO8, CHLCC, CCLCC) BETTER_ENUM(TipsMenuType, int, None, MO6TW, CHLCC, CCLCC) BETTER_ENUM(ClearListMenuType, int, None, MO6TW, CHLCC, CCLCC) diff --git a/src/ui/widgets/sghd/titlebutton.cpp b/src/ui/widgets/sghd/titlebutton.cpp new file mode 100644 index 000000000..353549be2 --- /dev/null +++ b/src/ui/widgets/sghd/titlebutton.cpp @@ -0,0 +1,43 @@ +#include "titlebutton.h" + +#include "../../../renderer/renderer.h" +#include "../../../profile/games/sghd/titlemenu.h" + +namespace Impacto { +namespace UI { +namespace Widgets { +namespace SGHD { + +using namespace Impacto::Profile::SGHD::TitleMenu; + +void TitleButton::Render() { + /* + if (HasFocus) { + if (!IsSubButton) { // Main buttons + Renderer->DrawSprite(HighlightSprite, + glm::vec2(Bounds.X - ItemHighlightOffsetX, + Bounds.Y - ItemHighlightOffsetY), + Tint); + Renderer->DrawSprite( + ItemHighlightPointerSprite, + glm::vec2(Bounds.X - ItemHighlightPointerY, Bounds.Y), Tint); + Renderer->DrawSprite(FocusedSprite, glm::vec2(Bounds.X, Bounds.Y), Tint); + } else { // Sub buttons + Renderer->DrawSprite(HighlightSprite, glm::vec2(Bounds.X, Bounds.Y), + Tint); + Renderer->DrawSprite(FocusedSprite, glm::vec2(Bounds.X, Bounds.Y), Tint); + } + } else { + if (Enabled) { + Renderer->DrawSprite(NormalSprite, glm::vec2(Bounds.X, Bounds.Y), Tint); + } else { + Renderer->DrawSprite(DisabledSprite, glm::vec2(Bounds.X, Bounds.Y), Tint); + } + } + */ +} + +} // namespace SGHD +} // namespace Widgets +} // namespace UI +} // namespace Impacto diff --git a/src/ui/widgets/sghd/titlebutton.h b/src/ui/widgets/sghd/titlebutton.h new file mode 100644 index 000000000..85c2105d7 --- /dev/null +++ b/src/ui/widgets/sghd/titlebutton.h @@ -0,0 +1,22 @@ +#pragma once + +#include "../button.h" + +namespace Impacto { +namespace UI { +namespace Widgets { +namespace SGHD { + +class TitleButton : public Widgets::Button { + public: + TitleButton(int id, Sprite const& norm, Sprite const& focused, + Sprite const& highlight, glm::vec2 pos) + : Widgets::Button(id, norm, focused, highlight, pos) {} + void Render() override; + bool IsSubButton = false; +}; + +} // namespace SGHD +} // namespace Widgets +} // namespace UI +} // namespace Impacto diff --git a/src/vm/expression.cpp b/src/vm/expression.cpp index d2c535d71..143fddbc2 100644 --- a/src/vm/expression.cpp +++ b/src/vm/expression.cpp @@ -323,7 +323,11 @@ ExpressionParser::ExpressionParser(Sc3VmThread* thd) { ExpressionNode* ExpressionParser::ParseSubExpression(int minPrecidence) { ExpressionNode* leftExpr = ParseTerm(); - if (leftExpr == nullptr) return leftExpr; + if (leftExpr == nullptr) { + ImpLog(LL_Warning, LC_Expr, + "Failed to parse left expression, returning early!\n"); + return leftExpr; + } if (static_cast(CurrentToken) < Tokens.size()) { ExprToken peek = Tokens[CurrentToken]; @@ -430,6 +434,9 @@ ExpressionNode* ExpressionParser::ParseTerm() { term->Value = tok.Value; break; default: + ImpLog(LL_Warning, LC_Expr, + "Unknown expression token type %d, returning nullptr!\n", + tok.Type); return nullptr; } diff --git a/src/vm/inst_dialogue.cpp b/src/vm/inst_dialogue.cpp index 8aa14f908..caa93273d 100644 --- a/src/vm/inst_dialogue.cpp +++ b/src/vm/inst_dialogue.cpp @@ -508,6 +508,7 @@ VmInstruction(InstTips) { uint8_t* tipsDataAdr = ScriptGetLabelAddress( ScriptBuffers[thread->ScriptBufferId], labelNum); if (Profile::Vm::GameInstructionSet == +InstructionSet::MO8 || + Profile::Vm::GameInstructionSet == +InstructionSet::SGHD || Profile::Vm::GameInstructionSet == +InstructionSet::CHN) { PopLocalLabel(tipsDataAdr1); (void)tipsDataAdr1; diff --git a/src/vm/inst_gamespecific.cpp b/src/vm/inst_gamespecific.cpp index 3cf259706..fc6e291e1 100644 --- a/src/vm/inst_gamespecific.cpp +++ b/src/vm/inst_gamespecific.cpp @@ -35,6 +35,19 @@ VmInstruction(InstUnk0053) { ImpLogSlow(LL_Warning, LC_VMStub, "STUB instruction Unk0053(arg1: %i, arg2: %i)\n", arg1, arg2); } +VmInstruction(InstUnk0053SGHD) { + StartInstruction; + PopUint8(type); + // FIXME: Could be that we should only pop one if type != 2 and != 3 + PopUint16(arg1); + PopUint16(arg2); + PopUint16(arg3); + PopUint16(arg4); + ImpLogSlow(LL_Warning, LC_VMStub, + "STUB instruction Unk0053SG(type: %i, arg1: %i, arg2: %i, arg3: " + "%i, arg4: %i)\n", + type, arg1, arg2, arg3, arg4); +} VmInstruction(InstUnk0054) { StartInstruction; PopExpression(arg1); @@ -1066,6 +1079,18 @@ VmInstruction(InstUnk103A) { } break; } } +VmInstruction(InstUnk103FSGHD) { + StartInstruction; + PopUint8(type); + switch (type) { + // TODO: Cases 0x00 to 0x1A + default: { + ImpLogSlow(LL_Warning, LC_VMStub, + "STUB instruction Unk103FSteinsGate(type: %i)\n", type); + break; + } + } +} VmInstruction(InstUnk1037Noah) { StartInstruction; PopUint8(type); diff --git a/src/vm/inst_gamespecific.h b/src/vm/inst_gamespecific.h index e6d24f543..e0c63f8c8 100644 --- a/src/vm/inst_gamespecific.h +++ b/src/vm/inst_gamespecific.h @@ -9,6 +9,7 @@ namespace Vm { VmInstruction(InstUnk0041); VmInstruction(InstUnk0052); VmInstruction(InstUnk0053); +VmInstruction(InstUnk0053SGHD); VmInstruction(InstUnk0054); VmInstruction(InstAddContents); VmInstruction(InstUnk011F); @@ -35,6 +36,7 @@ VmInstruction(InstTwipo_Dash); VmInstruction(InstDelusionTriggerCHLCC); VmInstruction(InstYesNoTriggerCCLCC); VmInstruction(InstUnk103A); +VmInstruction(InstUnk103FSGHD); } // namespace Vm diff --git a/src/vm/inst_macros.inc b/src/vm/inst_macros.inc index 9259a2a91..b9ebab7c1 100644 --- a/src/vm/inst_macros.inc +++ b/src/vm/inst_macros.inc @@ -4,6 +4,8 @@ /* Sometimes needed by subsequent code, silence warning */ \ (void)noExpressions; \ (void)_oldIp; \ + ImpLogSlow(LL_Trace, LC_VM, "Instruction name: %s\n", \ + __func__); \ thread->Ip += 2 #define ResetInstruction thread->Ip = _oldIp diff --git a/src/vm/inst_system.cpp b/src/vm/inst_system.cpp index a2875e1b4..24b3116bf 100644 --- a/src/vm/inst_system.cpp +++ b/src/vm/inst_system.cpp @@ -34,7 +34,10 @@ using namespace Impacto::SaveSystem; using namespace Impacto::TipsSystem; using namespace Impacto::Profile::ScriptVars; -VmInstruction(InstDummy) {} +VmInstruction(InstDummy) { + ImpLog(LL_Warning, LC_VM, + "Dummy instruction called! Possibly actually used by the game?\n"); +} VmInstruction(InstEnd) { StartInstruction; diff --git a/src/vm/opcodetables_sghd.h b/src/vm/opcodetables_sghd.h new file mode 100644 index 000000000..b0b52d107 --- /dev/null +++ b/src/vm/opcodetables_sghd.h @@ -0,0 +1,797 @@ +#include "inst_system.h" +#include "inst_controlflow.h" +#include "inst_graphics2d.h" +#include "inst_dialogue.h" +#include "inst_sound.h" +#include "inst_movie.h" +#include "inst_gamespecific.h" +#include "inst_misc.h" + +// clang-format off + +namespace Impacto { + +namespace Vm { + +InstructionProc static OpcodeTableSystem_SGHD[256] = { + InstEnd, // 00 00 + InstCreateThread, // 00 01 + InstKillThread, // 00 02 + InstReset, // 00 03 + InstScriptLoad, // 00 04 + InstWait, // 00 05 + InstHalt, // 00 06 + InstJump, // 00 07 + InstJumpTable, // 00 08 + InstGetLabelAdr, // 00 09 + InstIf, // 00 0A + InstCall, // 00 0B + InstJumpFar, // 00 0C + InstCallFar, // 00 0D + InstReturn, // 00 0E + InstLoop, // 00 0F + InstFlagOnJump, // 00 10 + InstFlagOnWait, // 00 11 + InstSetFlag, // 00 12 + InstResetFlag, // 00 13 + InstCopyFlag, // 00 14 + InstKeyOnJump, // 00 15 + InstKeyWait, // 00 16 + InstKeyWaitTimer, // 00 17 + InstMemberWrite, // 00 18 + InstThreadControl, // 00 19 + InstGetSelfPointer, // 00 1A + InstLoadJump, // 00 1B + InstVsync, // 00 1C + InstTest, // 00 1D + InstThreadControlStore, // 00 1E + InstSwitch, // 00 1F + InstCase, // 00 20 + InstBGMplay, // 00 21 + InstBGMstop, // 00 22 + InstSEplay, // 00 23 + InstSEstop, // 00 24 + InstPadAct, // 00 25 + InstSSEplay, // 00 26 + InstSSEstop, // 00 27 + InstCopyThreadWork, // 00 28 + InstUPLmenuUI, // 00 29 + InstSave, // 00 2A + InstSaveIconLoad, // 00 2B + InstBGMflag, // 00 2C + InstUPLxTitle, // 00 2D + InstPresence, // 00 2E + InstSetAchievement, // 00 2F + InstSetPlayer, // 00 30 + InstVoiceTableLoadMaybe, // 00 31 + InstSetPadCustom, // 00 32 + InstMwait, // 00 33 + InstTerminate, // 00 34 + InstSignIn, // 00 35 + InstAchievementIcon, // 00 36 + InstVoicePlayOld, // 00 37 + InstVoiceStop, // 00 38 + InstVoicePlayWait, // 00 39 + InstBGMduelPlay, // 00 3A + InstSNDpause, // 00 3B + InstSEplayWait, // 00 3C + InstDebugPrint, // 00 3D + InstResetSoundAll, // 00 3E + InstSNDloadStop, // 00 3F + InstBGMstopWait, // 00 40 + InstUnk0041, // 00 41 + InstSetX360SysMesPos, // 00 42 + InstSystemMes, // 00 43 + InstSystemMenu, // 00 44 + InstGetNowTime, // 00 45 + InstGetSystemStatus, // 00 46 + InstReboot, // 00 47 + InstReloadScript, // 00 48 + InstReloadScriptMenu, // 00 49 + InstDebugEditer, // 00 4A + InstDummy, // 00 4B + InstDummy, // 00 4C + InstSysVoicePlay, // 00 4D + InstPadActEx, // 00 4E + InstDebugSetup, // 00 4F + InstPressStart, // 00 50 + InstGlobalSystemMessage, // 00 51 + InstUnk0052, // 00 52 + InstUnk0053SGHD, // 00 53 + InstUnk0054, // 00 54 + InstReturnIfFlag, // 00 55 + InstDummy, // 00 56 + InstDummy, // 00 57 + InstDummy, // 00 58 + InstDummy, // 00 59 + InstDummy, // 00 5A + InstDummy, // 00 5B + InstDummy, // 00 5C + InstDummy, // 00 5D + InstDummy, // 00 5E + InstDummy, // 00 5F + InstDummy, // 00 60 + InstDummy, // 00 61 + InstDummy, // 00 62 + InstDummy, // 00 63 + InstDummy, // 00 64 + InstDummy, // 00 65 + InstDummy, // 00 66 + InstDummy, // 00 67 + InstDummy, // 00 68 + InstDummy, // 00 69 + InstDummy, // 00 6A + InstDummy, // 00 6B + InstDummy, // 00 6C + InstDummy, // 00 6D + InstDummy, // 00 6E + InstDummy, // 00 6F + InstDummy, // 00 70 + InstDummy, // 00 71 + InstDummy, // 00 72 + InstDummy, // 00 73 + InstDummy, // 00 74 + InstDummy, // 00 75 + InstDummy, // 00 76 + InstDummy, // 00 77 + InstDummy, // 00 78 + InstDummy, // 00 79 + InstDummy, // 00 7A + InstDummy, // 00 7B + InstDummy, // 00 7C + InstDummy, // 00 7D + InstDummy, // 00 7E + InstDummy, // 00 7F + InstDummy, // 00 80 + InstDummy, // 00 81 + InstDummy, // 00 82 + InstDummy, // 00 83 + InstDummy, // 00 84 + InstDummy, // 00 85 + InstDummy, // 00 86 + InstDummy, // 00 87 + InstDummy, // 00 88 + InstDummy, // 00 89 + InstDummy, // 00 8A + InstDummy, // 00 8B + InstDummy, // 00 8C + InstDummy, // 00 8D + InstDummy, // 00 8E + InstDummy, // 00 8F + InstDummy, // 00 90 + InstDummy, // 00 91 + InstDummy, // 00 92 + InstDummy, // 00 93 + InstDummy, // 00 94 + InstDummy, // 00 95 + InstDummy, // 00 96 + InstDummy, // 00 97 + InstDummy, // 00 98 + InstDummy, // 00 99 + InstDummy, // 00 9A + InstDummy, // 00 9B + InstDummy, // 00 9C + InstDummy, // 00 9D + InstDummy, // 00 9E + InstDummy, // 00 9F + InstDummy, // 00 A0 + InstDummy, // 00 A1 + InstDummy, // 00 A2 + InstDummy, // 00 A3 + InstDummy, // 00 A4 + InstDummy, // 00 A5 + InstDummy, // 00 A6 + InstDummy, // 00 A7 + InstDummy, // 00 A8 + InstDummy, // 00 A9 + InstDummy, // 00 AA + InstDummy, // 00 AB + InstDummy, // 00 AC + InstDummy, // 00 AD + InstDummy, // 00 AE + InstDummy, // 00 AF + InstDummy, // 00 B0 + InstDummy, // 00 B1 + InstDummy, // 00 B2 + InstDummy, // 00 B3 + InstDummy, // 00 B4 + InstDummy, // 00 B5 + InstDummy, // 00 B6 + InstDummy, // 00 B7 + InstDummy, // 00 B8 + InstDummy, // 00 B9 + InstDummy, // 00 BA + InstDummy, // 00 BB + InstDummy, // 00 BC + InstDummy, // 00 BD + InstDummy, // 00 BE + InstDummy, // 00 BF + InstDummy, // 00 C0 + InstDummy, // 00 C1 + InstDummy, // 00 C2 + InstDummy, // 00 C3 + InstDummy, // 00 C4 + InstDummy, // 00 C5 + InstDummy, // 00 C6 + InstDummy, // 00 C7 + InstDummy, // 00 C8 + InstDummy, // 00 C9 + InstDummy, // 00 CA + InstDummy, // 00 CB + InstDummy, // 00 CC + InstDummy, // 00 CD + InstDummy, // 00 CE + InstDummy, // 00 CF + InstDummy, // 00 D0 + InstDummy, // 00 D1 + InstDummy, // 00 D2 + InstDummy, // 00 D3 + InstDummy, // 00 D4 + InstDummy, // 00 D5 + InstDummy, // 00 D6 + InstDummy, // 00 D7 + InstDummy, // 00 D8 + InstDummy, // 00 D9 + InstDummy, // 00 DA + InstDummy, // 00 DB + InstDummy, // 00 DC + InstDummy, // 00 DD + InstDummy, // 00 DE + InstDummy, // 00 DF + InstDummy, // 00 E0 + InstDummy, // 00 E1 + InstDummy, // 00 E2 + InstDummy, // 00 E3 + InstDummy, // 00 E4 + InstDummy, // 00 E5 + InstDummy, // 00 E6 + InstDummy, // 00 E7 + InstDummy, // 00 E8 + InstDummy, // 00 E9 + InstDummy, // 00 EA + InstDummy, // 00 EB + InstDummy, // 00 EC + InstDummy, // 00 ED + InstDummy, // 00 EE + InstDummy, // 00 EF + InstDummy, // 00 F0 + InstDummy, // 00 F1 + InstDummy, // 00 F2 + InstDummy, // 00 F3 + InstDummy, // 00 F4 + InstDummy, // 00 F5 + InstDummy, // 00 F6 + InstDummy, // 00 F7 + InstDummy, // 00 F8 + InstDummy, // 00 F9 + InstDummy, // 00 FA + InstDummy, // 00 FB + InstDummy, // 00 FC + InstDummy, // 00 FD + InstDummy, // 00 FE + InstDummy // 00 FF +}; + +InstructionProc static OpcodeTableGraph_SGHD[256] = { + InstCreateSurf, // 01 00 + InstReleaseSurf, // 01 01 + InstLoadPic, // 01 02 + InstReleaseSurf, // 01 03 + InstSurfFill, // 01 04 + InstCalc, // 01 05 + InstMesViewFlag, // 01 06 + InstSetMesWinPri, // 01 07 + InstMesSync, // 01 08 + InstMesSetID, // 01 09 + InstMesCls, // 01 0A + InstMesVoiceWait, // 01 0B + InstMes, // 01 0C + InstMesMain, // 01 0D + InstSetMesModeFormat, // 01 0E + InstSetNGmoji, // 01 0F + InstMesRev, // 01 10 + InstMessWindow, // 01 11 + InstSel, // 01 12 + InstSelect, // 01 13 + InstSysSel, // 01 14 + InstSysSelect, // 01 15 + InstDummy, // 01 16 + InstDummy, // 01 17 + InstDummy, // 01 18 + InstDummy, // 01 19 + InstDummy, // 01 1A + InstDummy, // 01 1B + InstDummy, // 01 1C + InstDummy, // 01 1D + InstDummy, // 01 1E + InstUnk011F, // 01 1F + InstSCcapture, // 01 20 + InstSetTextTable, // 01 21 + InstPlayMovie, // 01 22 + InstMovieMain, // 01 23 + InstLoadMovie, // 01 24 + InstSetRevMes, // 01 25 + InstPlayMovieMemory, // 01 26 + InstPlayMovie, // 01 27 + InstMovieMain, // 01 28 + InstLoadMovie, // 01 29 + InstPlayMovieMemory, // 01 2A + InstSFDpause, // 01 2B + InstPlayMovie, // 01 2C + InstUnk012D, // 01 2D + InstDummy, // 01 2E + InstDummy, // 01 2F + InstDummy, // 01 30 + InstDummy, // 01 31 + InstDummy, // 01 32 + InstDummy, // 01 33 + InstDummy, // 01 34 + InstDummy, // 01 35 + InstDummy, // 01 36 + InstDummy, // 01 37 + InstDummy, // 01 38 + InstDummy, // 01 39 + InstDummy, // 01 3A + InstDummy, // 01 3B + InstDummy, // 01 3C + InstDummy, // 01 3D + InstDummy, // 01 3E + InstDummy, // 01 3F + InstDummy, // 01 40 + InstDummy, // 01 41 + InstDummy, // 01 42 + InstDummy, // 01 43 + InstDummy, // 01 44 + InstDummy, // 01 45 + InstDummy, // 01 46 + InstDummy, // 01 47 + InstDummy, // 01 48 + InstDummy, // 01 49 + InstDummy, // 01 4A + InstDummy, // 01 4B + InstDummy, // 01 4C + InstDummy, // 01 4D + InstDummy, // 01 4E + InstDummy, // 01 4F + InstDummy, // 01 50 + InstDummy, // 01 51 + InstDummy, // 01 52 + InstDummy, // 01 53 + InstDummy, // 01 54 + InstDummy, // 01 55 + InstDummy, // 01 56 + InstDummy, // 01 57 + InstDummy, // 01 58 + InstDummy, // 01 59 + InstDummy, // 01 5A + InstDummy, // 01 5B + InstDummy, // 01 5C + InstDummy, // 01 5D + InstDummy, // 01 5E + InstDummy, // 01 5F + InstDummy, // 01 60 + InstDummy, // 01 61 + InstDummy, // 01 62 + InstDummy, // 01 63 + InstDummy, // 01 64 + InstDummy, // 01 65 + InstDummy, // 01 66 + InstDummy, // 01 67 + InstDummy, // 01 68 + InstDummy, // 01 69 + InstDummy, // 01 6A + InstDummy, // 01 6B + InstDummy, // 01 6C + InstDummy, // 01 6D + InstDummy, // 01 6E + InstDummy, // 01 6F + InstDummy, // 01 70 + InstDummy, // 01 71 + InstDummy, // 01 72 + InstDummy, // 01 73 + InstDummy, // 01 74 + InstDummy, // 01 75 + InstDummy, // 01 76 + InstDummy, // 01 77 + InstDummy, // 01 78 + InstDummy, // 01 79 + InstDummy, // 01 7A + InstDummy, // 01 7B + InstDummy, // 01 7C + InstDummy, // 01 7D + InstDummy, // 01 7E + InstDummy, // 01 7F + InstDummy, // 01 80 + InstDummy, // 01 81 + InstDummy, // 01 82 + InstDummy, // 01 83 + InstDummy, // 01 84 + InstDummy, // 01 85 + InstDummy, // 01 86 + InstDummy, // 01 87 + InstDummy, // 01 88 + InstDummy, // 01 89 + InstDummy, // 01 8A + InstDummy, // 01 8B + InstDummy, // 01 8C + InstDummy, // 01 8D + InstDummy, // 01 8E + InstDummy, // 01 8F + InstDummy, // 01 90 + InstDummy, // 01 91 + InstDummy, // 01 92 + InstDummy, // 01 93 + InstDummy, // 01 94 + InstDummy, // 01 95 + InstDummy, // 01 96 + InstDummy, // 01 97 + InstDummy, // 01 98 + InstDummy, // 01 99 + InstDummy, // 01 9A + InstDummy, // 01 9B + InstDummy, // 01 9C + InstDummy, // 01 9D + InstDummy, // 01 9E + InstDummy, // 01 9F + InstDummy, // 01 A0 + InstDummy, // 01 A1 + InstDummy, // 01 A2 + InstDummy, // 01 A3 + InstDummy, // 01 A4 + InstDummy, // 01 A5 + InstDummy, // 01 A6 + InstDummy, // 01 A7 + InstDummy, // 01 A8 + InstDummy, // 01 A9 + InstDummy, // 01 AA + InstDummy, // 01 AB + InstDummy, // 01 AC + InstDummy, // 01 AD + InstDummy, // 01 AE + InstDummy, // 01 AF + InstDummy, // 01 B0 + InstDummy, // 01 B1 + InstDummy, // 01 B2 + InstDummy, // 01 B3 + InstDummy, // 01 B4 + InstDummy, // 01 B5 + InstDummy, // 01 B6 + InstDummy, // 01 B7 + InstDummy, // 01 B8 + InstDummy, // 01 B9 + InstDummy, // 01 BA + InstDummy, // 01 BB + InstDummy, // 01 BC + InstDummy, // 01 BD + InstDummy, // 01 BE + InstDummy, // 01 BF + InstDummy, // 01 C0 + InstDummy, // 01 C1 + InstDummy, // 01 C2 + InstDummy, // 01 C3 + InstDummy, // 01 C4 + InstDummy, // 01 C5 + InstDummy, // 01 C6 + InstDummy, // 01 C7 + InstDummy, // 01 C8 + InstDummy, // 01 C9 + InstDummy, // 01 CA + InstDummy, // 01 CB + InstDummy, // 01 CC + InstDummy, // 01 CD + InstDummy, // 01 CE + InstDummy, // 01 CF + InstDummy, // 01 D0 + InstDummy, // 01 D1 + InstDummy, // 01 D2 + InstDummy, // 01 D3 + InstDummy, // 01 D4 + InstDummy, // 01 D5 + InstDummy, // 01 D6 + InstDummy, // 01 D7 + InstDummy, // 01 D8 + InstDummy, // 01 D9 + InstDummy, // 01 DA + InstDummy, // 01 DB + InstDummy, // 01 DC + InstDummy, // 01 DD + InstDummy, // 01 DE + InstDummy, // 01 DF + InstDummy, // 01 E0 + InstDummy, // 01 E1 + InstDummy, // 01 E2 + InstDummy, // 01 E3 + InstDummy, // 01 E4 + InstDummy, // 01 E5 + InstDummy, // 01 E6 + InstDummy, // 01 E7 + InstDummy, // 01 E8 + InstDummy, // 01 E9 + InstDummy, // 01 EA + InstDummy, // 01 EB + InstDummy, // 01 EC + InstDummy, // 01 ED + InstDummy, // 01 EE + InstDummy, // 01 EF + InstDummy, // 01 F0 + InstDummy, // 01 F1 + InstDummy, // 01 F2 + InstDummy, // 01 F3 + InstDummy, // 01 F4 + InstDummy, // 01 F5 + InstDummy, // 01 F6 + InstDummy, // 01 F7 + InstDummy, // 01 F8 + InstDummy, // 01 F9 + InstDummy, // 01 FA + InstDummy, // 01 FB + InstDummy, // 01 FC + InstDummy, // 01 FD + InstDummy, // 01 FE + InstDummy // 01 FF +}; + +InstructionProc static OpcodeTableUser1_SGHD[256] = { + InstMSinit, // 10 00 + InstBGload, // 10 01 + InstBGswap, // 10 02 + InstBGsetColor, // 10 03 + InstBGsetLink, // 10 04 + InstCHAload, // 10 05 + InstCHAswap, // 10 06 + InstBGcopy, // 10 07 + InstCHAcopy, // 10 08 + InstSaveSlot, // 10 09 + InstSystemMain, // 10 0A + InstCharaLayerLoad, // 10 0B + InstGameInfoInit, // 10 0C + InstCHAmove, // 10 0D + InstBGloadEx, // 10 0E + InstDummy, // 10 0F + InstBGrelease, // 10 10 + InstCHArelease, // 10 11 + InstClearFlagChk, // 10 12 + InstOption, // 10 13 + InstSystemDataReset, // 10 14 + InstDebugData, // 10 15 + InstGetCharaPause, // 10 16 + InstBGfadeExpInit, // 10 17 + InstDummy, // 10 18 + InstDummy, // 10 19 + InstDummy, // 10 1A + InstHelp, // 10 1B + InstAchievementMenu, // 10 1C + InstSoundMenu, // 10 1D + InstAllClear, // 10 1E + InstAlbum, // 10 1F + InstMovieMode, // 10 20 + InstClistInit, // 10 21 + InstAutoSave, // 10 22 + InstSaveMenu, // 10 23 + InstLoadData, // 10 24 + InstDummy, // 10 25 + InstDummy, // 10 26 + InstSetDic, // 10 27 + InstSetPlayMode, // 10 28 + InstSetEVflag, // 10 29 + InstSetCutin, // 10 2A + InstDummy, // 10 2B + InstDummy, // 10 2C + InstAchChkTitle, // 10 2D + InstSetSceneViewFlag, // 10 2E + InstChkClearFlag, // 10 2F + InstBGeffectWave, // 10 30 + InstGeotag, // 10 31 + InstNameID, // 10 32 + InstTips, // 10 33 + InstTitleMenu, // 10 34 + InstDummy, // 10 35 + InstBGeffect, // 10 36 + InstPhoneSG, // 10 37 + InstUnk1038Darling, // 10 38 + InstTwipo, // 10 39 + InstUnk103A, // 10 3A + InstDummy, // 10 3B + InstDummy, // 10 3C + InstDummy, // 10 3D + InstDummy, // 10 3E + InstUnk103FSGHD, // 10 3F + InstDummy, // 10 40 + InstDummy, // 10 41 + InstDummy, // 10 42 + InstDummy, // 10 43 + InstDummy, // 10 44 + InstDummy, // 10 45 + InstDummy, // 10 46 + InstDummy, // 10 47 + InstDummy, // 10 48 + InstDummy, // 10 49 + InstDummy, // 10 4A + InstDummy, // 10 4B + InstDummy, // 10 4C + InstDummy, // 10 4D + InstDummy, // 10 4E + InstDummy, // 10 4F + InstDummy, // 10 50 + InstDummy, // 10 51 + InstDummy, // 10 52 + InstDummy, // 10 53 + InstDummy, // 10 54 + InstDummy, // 10 55 + InstDummy, // 10 56 + InstDummy, // 10 57 + InstDummy, // 10 58 + InstDummy, // 10 59 + InstDummy, // 10 5A + InstDummy, // 10 5B + InstDummy, // 10 5C + InstDummy, // 10 5D + InstDummy, // 10 5E + InstDummy, // 10 5F + InstDummy, // 10 60 + InstDummy, // 10 61 + InstDummy, // 10 62 + InstDummy, // 10 63 + InstDummy, // 10 64 + InstDummy, // 10 65 + InstDummy, // 10 66 + InstDummy, // 10 67 + InstDummy, // 10 68 + InstDummy, // 10 69 + InstDummy, // 10 6A + InstDummy, // 10 6B + InstDummy, // 10 6C + InstDummy, // 10 6D + InstDummy, // 10 6E + InstDummy, // 10 6F + InstDummy, // 10 70 + InstDummy, // 10 71 + InstDummy, // 10 72 + InstDummy, // 10 73 + InstDummy, // 10 74 + InstDummy, // 10 75 + InstDummy, // 10 76 + InstDummy, // 10 77 + InstDummy, // 10 78 + InstDummy, // 10 79 + InstDummy, // 10 7A + InstDummy, // 10 7B + InstDummy, // 10 7C + InstDummy, // 10 7D + InstDummy, // 10 7E + InstDummy, // 10 7F + InstDummy, // 10 80 + InstDummy, // 10 81 + InstDummy, // 10 82 + InstDummy, // 10 83 + InstDummy, // 10 84 + InstDummy, // 10 85 + InstDummy, // 10 86 + InstDummy, // 10 87 + InstDummy, // 10 88 + InstDummy, // 10 89 + InstDummy, // 10 8A + InstDummy, // 10 8B + InstDummy, // 10 8C + InstDummy, // 10 8D + InstDummy, // 10 8E + InstDummy, // 10 8F + InstDummy, // 10 90 + InstDummy, // 10 91 + InstDummy, // 10 92 + InstDummy, // 10 93 + InstDummy, // 10 94 + InstDummy, // 10 95 + InstDummy, // 10 96 + InstDummy, // 10 97 + InstDummy, // 10 98 + InstDummy, // 10 99 + InstDummy, // 10 9A + InstDummy, // 10 9B + InstDummy, // 10 9C + InstDummy, // 10 9D + InstDummy, // 10 9E + InstDummy, // 10 9F + InstDummy, // 10 A0 + InstDummy, // 10 A1 + InstDummy, // 10 A2 + InstDummy, // 10 A3 + InstDummy, // 10 A4 + InstDummy, // 10 A5 + InstDummy, // 10 A6 + InstDummy, // 10 A7 + InstDummy, // 10 A8 + InstDummy, // 10 A9 + InstDummy, // 10 AA + InstDummy, // 10 AB + InstDummy, // 10 AC + InstDummy, // 10 AD + InstDummy, // 10 AE + InstDummy, // 10 AF + InstDummy, // 10 B0 + InstDummy, // 10 B1 + InstDummy, // 10 B2 + InstDummy, // 10 B3 + InstDummy, // 10 B4 + InstDummy, // 10 B5 + InstDummy, // 10 B6 + InstDummy, // 10 B7 + InstDummy, // 10 B8 + InstDummy, // 10 B9 + InstDummy, // 10 BA + InstDummy, // 10 BB + InstDummy, // 10 BC + InstDummy, // 10 BD + InstDummy, // 10 BE + InstDummy, // 10 BF + InstDummy, // 10 C0 + InstDummy, // 10 C1 + InstDummy, // 10 C2 + InstDummy, // 10 C3 + InstDummy, // 10 C4 + InstDummy, // 10 C5 + InstDummy, // 10 C6 + InstDummy, // 10 C7 + InstDummy, // 10 C8 + InstDummy, // 10 C9 + InstDummy, // 10 CA + InstDummy, // 10 CB + InstDummy, // 10 CC + InstDummy, // 10 CD + InstDummy, // 10 CE + InstDummy, // 10 CF + InstDummy, // 10 D0 + InstDummy, // 10 D1 + InstDummy, // 10 D2 + InstDummy, // 10 D3 + InstDummy, // 10 D4 + InstDummy, // 10 D5 + InstDummy, // 10 D6 + InstDummy, // 10 D7 + InstDummy, // 10 D8 + InstDummy, // 10 D9 + InstDummy, // 10 DA + InstDummy, // 10 DB + InstDummy, // 10 DC + InstDummy, // 10 DD + InstDummy, // 10 DE + InstDummy, // 10 DF + InstDummy, // 10 E0 + InstDummy, // 10 E1 + InstDummy, // 10 E2 + InstDummy, // 10 E3 + InstDummy, // 10 E4 + InstDummy, // 10 E5 + InstDummy, // 10 E6 + InstDummy, // 10 E7 + InstDummy, // 10 E8 + InstDummy, // 10 E9 + InstDummy, // 10 EA + InstDummy, // 10 EB + InstDummy, // 10 EC + InstDummy, // 10 ED + InstDummy, // 10 EE + InstDummy, // 10 EF + InstDummy, // 10 F0 + InstDummy, // 10 F1 + InstDummy, // 10 F2 + InstDummy, // 10 F3 + InstDummy, // 10 F4 + InstDummy, // 10 F5 + InstDummy, // 10 F6 + InstDummy, // 10 F7 + InstDummy, // 10 F8 + InstDummy, // 10 F9 + InstDummy, // 10 FA + InstDummy, // 10 FB + InstDummy, // 10 FC + InstDummy, // 10 FD + InstDummy, // 10 FE + InstDummy // 10 FF +}; + +} + +} + +// clang-format on diff --git a/src/vm/vm.cpp b/src/vm/vm.cpp index a9cc812ec..7b375e290 100644 --- a/src/vm/vm.cpp +++ b/src/vm/vm.cpp @@ -16,6 +16,7 @@ #include "opcodetables_mo8.h" #include "opcodetables_dash.h" #include "opcodetables_cc.h" +#include "opcodetables_sghd.h" #include "opcodetables_sgps3.h" #include "opcodetables_chn.h" #include "../profile/game.h" @@ -46,10 +47,10 @@ static Sc3VmThread* static Sc3VmThread* NextFreeThreadCtx; // Next free thread context in the // thread pool -static InstructionProc* OpcodeTableSystem; -static InstructionProc* OpcodeTableUser1; -static InstructionProc* OpcodeTableGraph; -static InstructionProc* OpcodeTableGraph3D; +static InstructionProc* OpcodeTableSystem = nullptr; +static InstructionProc* OpcodeTableUser1 = nullptr; +static InstructionProc* OpcodeTableGraph = nullptr; +static InstructionProc* OpcodeTableGraph3D = nullptr; static void CreateThreadExecTable(); static void SortThreadExecTable(); @@ -118,6 +119,12 @@ void Init() { OpcodeTableUser1 = OpcodeTableUser1_SGPS3; break; } + case InstructionSet::SGHD: { + OpcodeTableSystem = OpcodeTableSystem_SGHD; + OpcodeTableGraph = OpcodeTableGraph_SGHD; + OpcodeTableUser1 = OpcodeTableUser1_SGHD; + break; + } case InstructionSet::MO8: { OpcodeTableSystem = OpcodeTableSystem_MO8; OpcodeTableGraph = OpcodeTableGraph_MO8; @@ -179,7 +186,8 @@ void Init() { bool LoadScript(uint32_t bufferId, uint32_t scriptId) { Io::FileMeta meta; Io::VfsGetMeta("script", scriptId, &meta); - ImpLogSlow(LL_Debug, LC_VM, "Loading script \"%s\"\n", meta.FileName.c_str()); + ImpLogSlow(LL_Debug, LC_VM, "Loading script \"%s\" into buffer %u\n", + meta.FileName.c_str(), bufferId); void* file; int64_t fileSize; @@ -488,12 +496,19 @@ void RunThread(Sc3VmThread* thread) { if (opcodeGrp1 == 0x10) { OpcodeTableUser1[opcode](thread); } else if (opcodeGrp1 == 0x02) { + if (OpcodeTableGraph3D == nullptr) { + ImpLog( + LL_Error, LC_VM, + "Encountered Graph3D opcode in game which shouldn't have any!\n"); + goto badOpcode; + } OpcodeTableGraph3D[opcode](thread); } else if (opcodeGrp1 == 0x01) { OpcodeTableGraph[opcode](thread); } else if (!opcodeGrp1) { OpcodeTableSystem[opcode](thread); } else { + badOpcode: ImpLog(LL_Error, LC_VM, "Thread CRASH! Unknown opcode. Attempting recovery. Address: " "%016X Opcode: %02X:%02X ScriptBuffer: %i\n", diff --git a/src/vm/vm.h b/src/vm/vm.h index d48fbd20b..caba5aa59 100644 --- a/src/vm/vm.h +++ b/src/vm/vm.h @@ -10,7 +10,7 @@ namespace Impacto { namespace Vm { BETTER_ENUM(InstructionSet, int, RNE, Darling, CHLCC, MO6TW, MO7, Dash, CC, - SGPS3, MO8, CHN) + SGHD, SGPS3, MO8, CHN) typedef void (*InstructionProc)(Sc3VmThread* thread);