diff --git a/POWERHD.SHP b/POWERHD.SHP new file mode 100644 index 0000000..83427e5 Binary files /dev/null and b/POWERHD.SHP differ diff --git a/SIDEFILLER.SHP b/SIDEFILLER.SHP new file mode 100644 index 0000000..c1f1b90 Binary files /dev/null and b/SIDEFILLER.SHP differ diff --git a/SIDEHD.SHP b/SIDEHD.SHP new file mode 100644 index 0000000..00e628d Binary files /dev/null and b/SIDEHD.SHP differ diff --git a/code/redalert/lcw.h b/code/redalert/lcw.h index f8b97a4..959377c 100644 --- a/code/redalert/lcw.h +++ b/code/redalert/lcw.h @@ -40,7 +40,8 @@ int LCW_Uncomp(void const * source, void * dest, unsigned long length=0); extern "C" { -int __cdecl LCW_Comp(void const * source, void * dest, int length); + int __cdecl LCW_Comp(void const * source, void * dest, int length); + int __cdecl LCW_Uncomp_CS(const void* src, void* dst, unsigned int bytes); } #endif diff --git a/code/redalert/lzw.cpp b/code/redalert/lzw.cpp index 13f910e..353394e 100644 --- a/code/redalert/lzw.cpp +++ b/code/redalert/lzw.cpp @@ -706,4 +706,237 @@ extern "C" int LCW_Comp(const void* src, void* dst, unsigned int bytes) *putp++ = 0x80; return putp - putstart; } -// jmarshall end \ No newline at end of file +// jmarshall end + +extern "C" int LCW_Uncomp_CS(const void* src, void* dst, unsigned int bytes) +{ + //captainslog_assert(src != nullptr); + //captainslog_assert(dst != nullptr); + + uint8_t* putstart = static_cast(dst); + uint8_t* putend = putstart + bytes; + uint8_t* putp = putstart; + const uint8_t* getp = static_cast(src); + // const uint8_t *getstart = getp; + + // If first byte is 0, the all offsets are relative to current position. Otherwise some are absolute to the start of the + // buffer, meaning only ~64KB can be compressed effectively. Compressor implemented in this file uses size to determine + // compression scheme used. + if (*getp == 0) { + // captainslog_debug("LCW Relative Decompression... "); + getp++; + + while (putp < putend) { + uint8_t flag; + uint16_t cpysize; + uint16_t offset; + + flag = *getp++; + + if (flag & 0x80) { + if (flag & 0x40) { + cpysize = (flag & 0x3F) + 3; + // long set 0b11111110 + if (flag == 0xFE) { + cpysize = *getp++; + cpysize += (*getp++) << 8; + + if (cpysize > putend - putp) { + cpysize = putend - putp; + } + + // captainslog_debug("0b11111110 Source Pos %ld, Dest Pos %ld, Count %d", source - sstart - 3, dest - + // start, cpysize); + memset(putp, (*getp++), cpysize); + putp += cpysize; + } + else { + uint8_t* s; + // long move, abs 0b11111111 + if (flag == 0xFF) { + cpysize = *getp++; + cpysize += (*getp++) << 8; + + if (cpysize > putend - putp) { + cpysize = putend - putp; + } + + offset = *getp++; + offset += (*getp++) << 8; + + // extended format for VQA32 and large WSA files. + s = putp - offset; + + // captainslog_debug("0b11111111 Source Pos %ld, Dest Pos %ld, Count %d, Offset %d", source - sstart - + // 5, dest - start, cpysize, offset); + for (; cpysize > 0; --cpysize) { + *putp++ = *s++; + } + // short move abs 0b11?????? + } + else { + if (cpysize > putend - putp) { + cpysize = putend - putp; + } + + offset = *getp++; + offset += (*getp++) << 8; + + // extended format for VQA32 and large WSA files. + s = putp - offset; + + // captainslog_debug("0b11?????? Source Pos %ld, Dest Pos %ld, Count %d, Offset %d", source - sstart - + // 3, dest - start, cpysize, offset); + for (; cpysize > 0; --cpysize) { + *putp++ = *s++; + } + } + } + // short copy 0b10?????? + } + else { + if (flag == 0x80) { + // captainslog_debug("0b10?????? Source Pos %ld, Dest Pos %ld, Count %d", source - sstart - 1, dest - + // start, 0); + return putp - putstart; + } + + cpysize = flag & 0x3F; + + if (cpysize > putend - putp) { + cpysize = putend - putp; + } + + // captainslog_debug("0b10?????? Source Pos %ld, Dest Pos %ld, Count %d", source - sstart - 1, dest - start, + // cpysize); + for (; cpysize > 0; --cpysize) { + *putp++ = *getp++; + } + } + // short move rel 0b0??????? + } + else { + cpysize = (flag >> 4) + 3; + + if (cpysize > putend - putp) { + cpysize = putend - putp; + } + + offset = ((flag & 0xF) << 8) + (*getp++); + // captainslog_debug("0b0??????? Source Pos %ld, Dest Pos %ld, Count %d, Offset %d", source - sstart - 2, dest - + // start, cpysize, offset); + for (; cpysize > 0; --cpysize) { + *putp = *(putp - offset); + putp++; + } + } + } + } + else { + // captainslog_debug("LCW Decompression... "); + + while (putp < putend) { + uint8_t flag; + uint16_t cpysize; + uint16_t offset; + + flag = *getp++; + + if (flag & 0x80) { + if (flag & 0x40) { + cpysize = (flag & 0x3F) + 3; + // long set 0b11111110 + if (flag == 0xFE) { + cpysize = *getp++; + cpysize += (*getp++) << 8; + + if (cpysize > putend - putp) { + cpysize = putend - putp; + } + + // captainslog_debug("0b11111110 Source Pos %ld, Dest Pos %ld, Count %d", source - sstart - 3, dest - + // start, cpysize); + memset(putp, (*getp++), cpysize); + putp += cpysize; + } + else { + uint8_t* s; + // long move, abs 0b11111111 + if (flag == 0xFF) { + cpysize = *getp++; + cpysize += (*getp++) << 8; + + if (cpysize > putend - putp) { + cpysize = putend - putp; + } + + offset = *getp++; + offset += (*getp++) << 8; + s = putstart + offset; + + // captainslog_debug("0b11111111 Source Pos %ld, Dest Pos %ld, Count %d, Offset %d", source - sstart - + // 5, dest - start, cpysize, offset); + for (; cpysize > 0; --cpysize) { + *putp++ = *s++; + } + // short move abs 0b11?????? + } + else { + if (cpysize > putend - putp) { + cpysize = putend - putp; + } + + offset = *getp++; + offset += (*getp++) << 8; + s = putstart + offset; + + // captainslog_debug("0b11?????? Source Pos %ld, Dest Pos %ld, Count %d, Offset %d", source - sstart - + // 3, dest - start, cpysize, offset); + for (; cpysize > 0; --cpysize) { + *putp++ = *s++; + } + } + } + // short copy 0b10?????? + } + else { + if (flag == 0x80) { + // captainslog_debug("0b10?????? Source Pos %ld, Dest Pos %ld, Count %d", source - sstart - 1, dest - + // start, 0); + return putp - putstart; + } + + cpysize = flag & 0x3F; + + if (cpysize > putend - putp) { + cpysize = putend - putp; + } + + // captainslog_debug("0b10?????? Source Pos %ld, Dest Pos %ld, Count %d", source - sstart - 1, dest - start, + // cpysize); + for (; cpysize > 0; --cpysize) { + *putp++ = *getp++; + } + } + // short move rel 0b0??????? + } + else { + cpysize = (flag >> 4) + 3; + + if (cpysize > putend - putp) { + cpysize = putend - putp; + } + + offset = ((flag & 0xF) << 8) + (*getp++); + // captainslog_debug("0b0??????? Source Pos %ld, Dest Pos %ld, Count %d, Offset %d", source - sstart - 2, dest - + // start, cpysize, offset); + for (; cpysize > 0; --cpysize) { + *putp = *(putp - offset); + putp++; + } + } + } + } + + return putp - putstart; +} \ No newline at end of file diff --git a/code/redalert/power.cpp b/code/redalert/power.cpp index 8c4edea..c9b6a67 100644 --- a/code/redalert/power.cpp +++ b/code/redalert/power.cpp @@ -50,6 +50,8 @@ void const* PowerClass::PowerShape; void const* PowerClass::PowerBarShape; +void const* PowerClass::PowerBarShapeHD; + PowerClass::PowerButtonClass PowerClass::PowerButton; @@ -139,8 +141,12 @@ void PowerClass::One_Time(void) PowerButton.Y = POWER_Y * RESFACTOR; PowerButton.Width = (POWER_WIDTH * RESFACTOR) - 1; PowerButton.Height = ScreenHeight - (POWER_Y * RESFACTOR);// POWER_HEIGHT* RESFACTOR; + PowerShape = MFCD::Retrieve("POWER.SHP"); PowerBarShape = MFCD::Retrieve("POWERBAR.SHP"); + + RawFileClass powerShapeFile("POWERHD.SHP"); + if (powerShapeFile.Is_Available()) PowerBarShapeHD = Load_Alloc_Data(powerShapeFile); } @@ -187,17 +193,21 @@ void PowerClass::Draw_It(bool complete) /* ** Hires power strip is too big to fit into a shape so it is in two parts */ - CC_Draw_Shape(PowerBarShape, 0, ScreenWidth - (640 - (240 * RESFACTOR)), (88 * RESFACTOR), WINDOW_MAIN, flags | SHAPE_NORMAL | SHAPE_WIN_REL, remap); + CC_Draw_Shape(PowerBarShapeHD, 0, ScreenWidth - (640 - (240 * RESFACTOR)), (88 * RESFACTOR), WINDOW_MAIN, flags | SHAPE_NORMAL | SHAPE_WIN_REL, remap); - int bottomOfBar = (88 * RESFACTOR) + 56; + + int bottomOfBar = (88 + 56) * RESFACTOR; - while (bottomOfBar < PowerButton.Height + 42) + while ( bottomOfBar < ( PowerButton.Height - 56 ) ) { - CC_Draw_Shape(PowerBarShape, 1, ScreenWidth - (640 - (240 * RESFACTOR)), bottomOfBar, WINDOW_MAIN, flags | SHAPE_NORMAL | SHAPE_WIN_REL, remap); - bottomOfBar += 8 * RESFACTOR; + CC_Draw_Shape(PowerBarShapeHD, 1, ScreenWidth - (640 - (240 * RESFACTOR)), bottomOfBar, WINDOW_MAIN, flags | SHAPE_NORMAL | SHAPE_WIN_REL, remap); + bottomOfBar += 56 * RESFACTOR; } - int bottom = bottomOfBar + (28 * RESFACTOR); + // bottom + CC_Draw_Shape(PowerBarShapeHD, 2, ScreenWidth - (640 - (240 * RESFACTOR)), bottomOfBar, WINDOW_MAIN, flags | SHAPE_NORMAL | SHAPE_WIN_REL, remap); + + int bottom = bottomOfBar + (36 * RESFACTOR); /* ** Determine how much the power production exceeds or falls short diff --git a/code/redalert/power.h b/code/redalert/power.h index d030986..1ec9aaa 100644 --- a/code/redalert/power.h +++ b/code/redalert/power.h @@ -113,6 +113,7 @@ class PowerClass : public RadarClass */ static void const * PowerShape; static void const * PowerBarShape; + static void const * PowerBarShapeHD; }; #endif diff --git a/code/redalert/shape.cpp b/code/redalert/shape.cpp index 14dbc28..4a1b343 100644 --- a/code/redalert/shape.cpp +++ b/code/redalert/shape.cpp @@ -1138,7 +1138,7 @@ void* Build_Frame2(void* shape, uint16_t frame, void* buffer) frame_data = &shape_data[(le32toh(offset_buff[0]) & 0xFFFFFF) + 768]; } - frame_size = LCW_Uncomp(frame_data, buffer, frame_size); + frame_size = LCW_Uncomp_CS(frame_data, buffer, frame_size); } else { // captainslog_debug("Decoding XOR frame."); diff --git a/code/redalert/sidebar.cpp b/code/redalert/sidebar.cpp index d73928f..e32f644 100644 --- a/code/redalert/sidebar.cpp +++ b/code/redalert/sidebar.cpp @@ -83,6 +83,9 @@ void* SidebarClass::SidebarShape = NULL; void* SidebarClass::SidebarMiddleShape = NULL; void* SidebarClass::SidebarBottomShape = NULL; +void* SidebarClass::SidebarShapeHD = NULL; +void* SidebarClass::SidebarFillerHD = NULL; + /*************************************************************************** ** This holds the translucent table for use with the construction clock @@ -122,6 +125,8 @@ SidebarClass::StripClass::SelectButton[COLUMNS][MAX_VISIBLE]; ** Shape data pointers */ void* SidebarClass::StripClass::LogoShapes = NULL; +void* SidebarClass::StripClass::LogoShapesHD = NULL; + void const* SidebarClass::StripClass::ClockShapes; void const* SidebarClass::StripClass::SpecialShapes[SPC_COUNT]; @@ -252,6 +257,16 @@ void SidebarClass::One_Time(void) if (SidebarShape == NULL) { SidebarShape = (void*)MFCD::Retrieve("SIDEBAR.SHP"); } + + if (SidebarShapeHD == NULL) { + RawFileClass sideBarFile("SIDEHD.SHP"); + if (sideBarFile.Is_Available() ) SidebarShapeHD = Load_Alloc_Data(sideBarFile); + } + + if (SidebarFillerHD == NULL) { + RawFileClass sideBarFillerFile("SIDEFILLER.SHP"); + if (sideBarFillerFile.Is_Available()) SidebarFillerHD = Load_Alloc_Data(sideBarFillerFile); + } } @@ -763,6 +778,7 @@ void SidebarClass::Draw_It(bool complete) // hack: black background for the sidebar GL_FillRect(TBLACK, SIDE_X * RESFACTOR, 8 * RESFACTOR, SIDE_WIDTH * RESFACTOR, ScreenHeight); + // Draw power on top PowerClass::Draw_It(complete); BStart(BENCH_SIDEBAR); @@ -774,17 +790,27 @@ void SidebarClass::Draw_It(bool complete) /* ** Draw the outline box around the sidebar buttons. */ - int shape = complete ? 0 : 1; - CC_Draw_Shape(SidebarShape, 0, SIDE_X * RESFACTOR, 8 * RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL); - CC_Draw_Shape(SidebarMiddleShape, shape, SIDE_X * RESFACTOR, (8 + 80) * RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL); + int topY = 90 * RESFACTOR; + int frameNr = 0; - CC_Draw_Shape(SidebarBottomShape, shape, SIDE_X * RESFACTOR, ScreenHeight - (80 * RESFACTOR) + 3, WINDOW_MAIN, SHAPE_WIN_REL); + for (int i = 0; i < Column[0].MaxButtonsVisible; i++) + { + CC_Draw_Shape(SidebarShapeHD, frameNr, SIDE_X * RESFACTOR, topY, WINDOW_MAIN, SHAPE_WIN_REL, 0); + topY += 24 * RESFACTOR; + + if (topY > ScreenHeight) break; + if (frameNr < 6) frameNr++; + } + + topY += 11 * RESFACTOR; + CC_Draw_Shape(SidebarFillerHD, 0, SIDE_X * RESFACTOR, topY, WINDOW_MAIN, SHAPE_WIN_REL, 0); Repair.Draw_Me(true); Upgrade.Draw_Me(true); Zoom.Draw_Me(true); + LogicPage->Unlock(); } } @@ -1312,6 +1338,7 @@ void SidebarClass::StripClass::Reload_LogoShapes(void) "stripna.shp", //HOUSE_GOOD "stripus.shp", //HOUSE_BAD }; + int houseloaded = 0; /* @@ -1697,9 +1724,6 @@ void SidebarClass::StripClass::Draw_It(bool complete) /* ** New sidebar needs to be drawn not filled */ - if (BuildableCount < MaxButtonsVisible) { - CC_Draw_Shape(LogoShapes, ID, X + (2 * RESFACTOR), Y, WINDOW_MAIN, SHAPE_WIN_REL | SHAPE_NORMAL, 0); - } /* ** Redraw the scroll buttons. @@ -2511,4 +2535,4 @@ void SidebarClass::Zoom_Mode_Control(void) } } #endif -} \ No newline at end of file +} diff --git a/code/redalert/sidebar.h b/code/redalert/sidebar.h index ce75364..3993e67 100644 --- a/code/redalert/sidebar.h +++ b/code/redalert/sidebar.h @@ -108,6 +108,8 @@ class SidebarClass: public PowerClass }; static void * SidebarShape; + static void * SidebarShapeHD; + static void * SidebarFillerHD; static void * SidebarMiddleShape; //Only used in Win95 version static void * SidebarBottomShape; //Only used in Win95 version @@ -319,6 +321,7 @@ class SidebarClass: public PowerClass ** placeholder pieces on the side bar. */ static void * LogoShapes; + static void * LogoShapesHD; /* ** This points to the animation sequence of frames used to mark the passage of time