From 3cf407eb0b345c0e7e770da8d7e05f2b89ca6e07 Mon Sep 17 00:00:00 2001 From: Giuliano Belinassi Date: Wed, 22 May 2024 16:29:17 -0300 Subject: [PATCH] Adding Dual screen support for DS port Signed-off-by: Giuliano Belinassi --- CMakeLists.txt | 2 +- common/video.h | 7 +- common/video_nds.cpp | 146 ++++++++++++++++++++++++++++----------- tiberiandawn/conquer.cpp | 5 ++ tiberiandawn/credits.cpp | 12 +++- tiberiandawn/externs.h | 9 +++ tiberiandawn/globals.cpp | 7 ++ tiberiandawn/gscreen.cpp | 3 + tiberiandawn/init.cpp | 11 +++ tiberiandawn/menus.cpp | 63 +++++++++++++++++ tiberiandawn/power.cpp | 10 ++- tiberiandawn/radar.cpp | 110 ++++++++++++++++++++++++----- tiberiandawn/sidebar.cpp | 18 ++++- tiberiandawn/sidebar.h | 4 ++ tiberiandawn/startup.cpp | 7 ++ tiberiandawn/tab.cpp | 7 +- 16 files changed, 357 insertions(+), 64 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d72cb933..fd159232 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,7 +154,7 @@ if(NDS) set(ARCH "-mthumb -mthumb-interwork -mcpu=arm946e-s -mtune=arm946e-s") set(CMAKE_C_FLAGS "${ARCH} ${CMAKE_C_CFLAGS} -fomit-frame-pointer -fno-rtti -fno-exceptions -ffast-math -fno-unwind-tables") - set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS} -DDS_RADAR_UPSCREEN") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -specs=ds_arm9.specs -mthumb -mthumb-interwork -Wl,-Map,vanilla.map") # Link with those libraries. diff --git a/common/video.h b/common/video.h index 6b095832..bf6ee009 100644 --- a/common/video.h +++ b/common/video.h @@ -9,6 +9,9 @@ enum GBC_Enum GBC_NONE = 0, GBC_VIDEOMEM = 1, GBC_VISIBLE = 2, +#ifdef _NDS + GBC_UPPERSCREEN = 4, +#endif }; class VideoSurface; @@ -105,5 +108,7 @@ unsigned Get_Video_Hardware_Capabilities(); void Wait_Vert_Blank(); void Set_DD_Palette(void* palette); - +#ifdef DS_RADAR_UPSCREEN +void Set_DD_Upscreen_Palette(const void *palette); +#endif #endif // VIDEO_H \ No newline at end of file diff --git a/common/video_nds.cpp b/common/video_nds.cpp index b99dc6b4..79287246 100644 --- a/common/video_nds.cpp +++ b/common/video_nds.cpp @@ -23,7 +23,21 @@ * into screen, with the consequence of losing a few lines. **/ -extern "C" void memcpy32(void* dst, const void* src, unsigned int wdcount); +extern "C" { +void memcpy32(void* dst, const void* src, unsigned int wdcount); +void nocashWrite(const char *, int len); +} + +void nocashPrintf(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + char buf[128]; + int len = vsnprintf(buf, 128, fmt, args); + va_end(args); + nocashWrite(buf, len); +} + void *tonccpy(void *dst, const void *src, size_t size); /* Function used to pause the console for debugging. */ @@ -45,6 +59,7 @@ void DS_Pause(const char* format, ...) // Background 3 identifier. Set on video initialization, and used on the seen // surface buffer. static int bg3; +static int bg3sub; // Mark the status of zoom. True means we are zoomed in, false means we are // zoomed out. @@ -302,12 +317,54 @@ void On_VBlank() Timer_VBlank(); } -bool Set_Video_Mode(int w, int h, int bits_per_pixel) +#ifdef DS_RADAR_UPSCREEN +static void Initialize_Upper_Screen(void) +{ + // Allocate 128Kb for the console on the upper screen. + vramSetBankC(VRAM_C_SUB_BG_0x06200000); + videoSetModeSub(MODE_3_2D); + + // Put pper screen into MODE5, which allows rotation and scaling on BG5 + bg3sub = bgInitSub(3, BgType_Bmp8, BgSize_B8_256x256, 0, 0); + + int scale_x = (256 * 256) / SCREEN_WIDTH; + int scale_y = (160 * 256) / SCREEN_HEIGHT; + + bgSetRotateScale(bg3sub, 0, scale_x, scale_y); + bgSetScroll(bg3sub, 0, 0); + + swiWaitForVBlank(); + bgUpdate(); + + char *surface = (char *)bgGetGfxPtr(bg3sub); + + for (int i = 0; i < 160; i++) { + for (int j = 0; j < 256; j++) { + if ((i + j) % 2 == 0) + surface[256 * i + j] = 98; + } + } +} +#else +static void Initialize_Upper_Console(void) { // Allocate memory for our console. This has to be static because it must // persists when this function exit, even if only used here. static PrintConsole cs0; + // Allocate 128Kb for the console on the upper screen. It is a bit + // overkill, but we got plenty of VRAM so far so it is OK. + vramSetBankC(VRAM_C_SUB_BG_0x06200000); + videoSetModeSub(MODE_0_2D); + + // Initialize the console on the top screen. + consoleInit(&cs0, 0, BgType_Text4bpp, BgSize_T_256x256, 2, 0, false, true); +} +#endif + +bool Set_Video_Mode(int w, int h, int bits_per_pixel) +{ + // Only turns on the 2D engine. The 3D chip is unused and disabling it // should save battery life. powerOn(POWER_ALL_2D); @@ -315,16 +372,14 @@ bool Set_Video_Mode(int w, int h, int bits_per_pixel) // If the ARM9 is set to 67MHz, set it to 133MHz now. setCpuClock(true); - // Allocate 128Kb for the console on the upper screen. It is a bit - // overkill, but we got plenty of VRAM so far so it is OK. - vramSetBankC(VRAM_C_SUB_BG_0x06200000); - videoSetModeSub(MODE_0_2D); +#ifdef DS_RADAR_UPSCREEN + Initialize_Upper_Screen(); +#else + Initialize_Upper_Console(); +#endif cpuStartTiming(0); - // Initialize the console on the top screen. - consoleInit(&cs0, 0, BgType_Text4bpp, BgSize_T_256x256, 2, 0, false, true); - // Setup what should run on a VBlank interrupt. irqSet(IRQ_VBLANK, On_VBlank); @@ -470,6 +525,20 @@ void Set_DD_Palette(void* palette) HWCursor.Set_Cursor_Palette(BG_PALETTE); } +void Set_Upperscreen_DD_Palette(const void *palette) +{ + unsigned char r, g, b; + + unsigned char* rcolors = (unsigned char*)palette; + for (int i = 0; i < 256; i++) { + r = (unsigned char)rcolors[i * 3] << 2; + g = (unsigned char)rcolors[i * 3 + 1] << 2; + b = (unsigned char)rcolors[i * 3 + 2] << 2; + + BG_PALETTE_SUB[i] = RGB8(r, g, b); + } +} + void Wait_Blit(void) { } @@ -526,9 +595,6 @@ void Update_HWCursor() class VideoSurfaceNDS; static VideoSurfaceNDS* frontSurface = nullptr; -// The hidden surface buffer. -static char HidSurfaceBuf[320 * 200]; - #define ALIGNED(ptr, n) (((uintptr_t)(ptr) % (n)) == 0) class VideoSurfaceNDS : public VideoSurface @@ -536,38 +602,39 @@ class VideoSurfaceNDS : public VideoSurface public: VideoSurfaceNDS(int w, int h, GBC_Enum flags) : flags(flags) - , windowSurface(nullptr) { - if (w == 320 && h == 200) { + if (flags & GBC_VISIBLE) { + if (flags & GBC_UPPERSCREEN) { + nocashWrite("Visible surface on upper screen\n", 100); + Pitch = w; + surface = (char*)bgGetGfxPtr(bg3sub); + } else { // The DS renderer works as follows: we pass the background // buffer in VRAM to the game's software engine, which draws // things there. The background is a 512x256 surface, but // only 512x200 pixels are used. - - if (flags & GBC_VISIBLE) { - Pitch = 512; - surface = (char*)bgGetGfxPtr(bg3); - windowSurface = surface; - frontSurface = this; - } else { - // The hid surface will be allocated in main RAM. The game - // uses a software engine that memcpy the graphics, and in - // this case it is faster to allocate this in main RAM. - Pitch = 320; - surface = HidSurfaceBuf; - } + nocashWrite("Visible surface on botom screen\n", 100); + Pitch = 512; + surface = (char*)bgGetGfxPtr(bg3); + frontSurface = this; + } } else { - swiWaitForVBlank(); - printf("ERROR - Unsupported surface size\n"); - while (1) - ; + // The hid surface will be allocated in main RAM. The game + // uses a software engine that memcpy the graphics, and in + // this case it is faster to allocate this in main RAM. + Pitch = w; + surface = (char *)malloc(w*h); + nocashWrite("Hidden suface\n", 100); } } virtual ~VideoSurfaceNDS() { - if (frontSurface == this) { - frontSurface = NULL; + // Do not call free on surfaces that are allocated on VRAM. + if ((uintptr_t)surface < 0x06000000) { + // Deallocate surface in main RAM. + free(surface); + surface = NULL; } } @@ -634,15 +701,13 @@ class VideoSurfaceNDS : public VideoSurface } } else { short dma = 0; - int flushrange = 320*(h - 1) + w; // Careful with alignment. if (ALIGNED(src_ptr, 4) && ALIGNED(dst_ptr, 4)) { - if (src_in_main_ram) { - DC_FlushRange(src_ptr, flushrange); - } + if (src_in_main_ram) + DC_FlushRange(src_ptr, src_pitch*(h - 1) + w); else if (dst_in_main_ram) - DC_FlushRange(dst_ptr, flushrange); + DC_FlushRange(dst_ptr, dst_pitch*(h - 1) + w); // Unroll iterations: short h_div = h / 4; @@ -673,9 +738,9 @@ class VideoSurfaceNDS : public VideoSurface } else if (ALIGNED(src_ptr, 2) && ALIGNED(dst_ptr, 2)) { if (src_in_main_ram) - DC_FlushRange(src_ptr, flushrange); + DC_FlushRange(src_ptr, src_pitch*(h - 1) + w); else if (dst_in_main_ram) - DC_FlushRange(dst_ptr, flushrange); + DC_FlushRange(dst_ptr, dst_pitch*(h - 1) + w); // Unroll iterations: short h_div = h / 4; @@ -816,7 +881,6 @@ class VideoSurfaceNDS : public VideoSurface private: int Pitch; char* surface; - char* windowSurface; GBC_Enum flags; }; diff --git a/tiberiandawn/conquer.cpp b/tiberiandawn/conquer.cpp index 09bafc0e..97024f3d 100644 --- a/tiberiandawn/conquer.cpp +++ b/tiberiandawn/conquer.cpp @@ -207,6 +207,7 @@ void Main_Game(int argc, char* argv[]) */ if (!Debug_Map) { TotalLocks = 0; + if (Main_Loop()) { break; } @@ -328,6 +329,10 @@ void Main_Game(int argc, char* argv[]) */ Fade_Palette_To(BlackPalette, FADE_PALETTE_SLOW, NULL); VisiblePage.Clear(); +#ifdef DS_RADAR_UPSCREEN + void Clumsy_Upperscreen_Menu(); + Clumsy_Upperscreen_Menu(); +#endif #ifndef DEMO /* diff --git a/tiberiandawn/credits.cpp b/tiberiandawn/credits.cpp index adb20783..0196cbec 100644 --- a/tiberiandawn/credits.cpp +++ b/tiberiandawn/credits.cpp @@ -88,6 +88,7 @@ void CreditClass::Graphic_Logic(bool forced) { int factor = Get_Resolution_Factor(); int xx = SeenBuff.Get_Width() - (120 << factor); + int yy = 0; if (forced || IsToRedraw) { /* @@ -117,8 +118,17 @@ void CreditClass::Graphic_Logic(bool forced) factor ? TPF_GREEN12_GRAD | TPF_CENTER | TPF_USE_GRAD_PAL : TPF_6PT_GRAD | TPF_CENTER | TPF_NOSHADOW; unsigned fore = factor ? 11 : WHITE; +#ifdef DS_RADAR_UPSCREEN + GraphicViewPortClass* oldpage = Set_Logic_Page(UpperHidBuff); + xx = 256 - (80 / 2); + yy = 160 - 8; +#endif TabClass::Draw_Credits_Tab(); - Fancy_Text_Print("%ld", xx, 0, fore, TBLACK, flags, Current); + Fancy_Text_Print("%ld", xx, yy, fore, TBLACK, flags, Current); + +#ifdef DS_RADAR_UPSCREEN + Set_Logic_Page(oldpage); +#endif IsToRedraw = false; IsAudible = false; diff --git a/tiberiandawn/externs.h b/tiberiandawn/externs.h index 8c09db9a..93514888 100644 --- a/tiberiandawn/externs.h +++ b/tiberiandawn/externs.h @@ -385,6 +385,15 @@ extern GraphicBufferClass ModeXBuff; extern GraphicViewPortClass HidPage; extern GraphicBufferClass LoResHidPage; extern GraphicBufferClass SysMemPage; +#ifdef DS_RADAR_UPSCREEN +extern GraphicBufferClass UpperVisiblePage; +extern GraphicBufferClass UpperHiddenPage; +extern GraphicViewPortClass UpperHidBuff; +extern GraphicViewPortClass UpperSeenBuff; + +extern void Set_Upperscreen_DD_Palette(const void *palette); + +#endif extern int MenuList[][8]; extern CountDownTimerClass FrameTimer; extern CountDownTimerClass CountDownTimer; diff --git a/tiberiandawn/globals.cpp b/tiberiandawn/globals.cpp index 23d9410c..b2657fb6 100644 --- a/tiberiandawn/globals.cpp +++ b/tiberiandawn/globals.cpp @@ -853,6 +853,13 @@ int MenuList[][8] = { GraphicBufferClass VisiblePage; GraphicBufferClass HiddenPage; +#ifdef DS_RADAR_UPSCREEN +GraphicBufferClass UpperVisiblePage; +GraphicBufferClass UpperHiddenPage; +GraphicViewPortClass UpperHidBuff(&UpperHiddenPage, 0, 0, 256, 160); +GraphicViewPortClass UpperSeenBuff(&UpperVisiblePage, 0, 0, 256, 160); +#endif + GraphicViewPortClass SeenBuff(&VisiblePage, 0, 0, GBUFF_INIT_WIDTH, GBUFF_INIT_HEIGHT); GraphicBufferClass ModeXBuff; GraphicViewPortClass HidPage(&HiddenPage, 0, 0, GBUFF_INIT_WIDTH, GBUFF_INIT_HEIGHT); diff --git a/tiberiandawn/gscreen.cpp b/tiberiandawn/gscreen.cpp index a79858f5..c88b7546 100644 --- a/tiberiandawn/gscreen.cpp +++ b/tiberiandawn/gscreen.cpp @@ -472,6 +472,9 @@ void GScreenClass::Blit_Display(void) #else //(0) WWMouse->Draw_Mouse(&HidPage); HidPage.Blit(SeenBuff, 0, 0, 0, 0, HidPage.Get_Width(), HidPage.Get_Height(), false); +#ifdef DS_RADAR_UPSCREEN + UpperHiddenPage.Blit(UpperVisiblePage, 0, 0, 0, 0, UpperHiddenPage.Get_Width(), UpperHiddenPage.Get_Height(), false); +#endif #ifdef CHEAT_KEYS Add_Current_Screen(); #endif diff --git a/tiberiandawn/init.cpp b/tiberiandawn/init.cpp index 0e01efb4..919099da 100644 --- a/tiberiandawn/init.cpp +++ b/tiberiandawn/init.cpp @@ -500,6 +500,11 @@ bool Init_Game(int, char*[]) Blit_Hid_Page_To_Seen_Buff(); } +#ifdef DS_RADAR_UPSCREEN + void Clumsy_Upperscreen_Menu(void); + Clumsy_Upperscreen_Menu(); +#endif + Hide_Mouse(); Wait_Vert_Blank(); if (!Special.IsFromInstall) { @@ -525,6 +530,7 @@ bool Init_Game(int, char*[]) } } } + Call_Back(); // malloc(2); @@ -1395,6 +1401,11 @@ bool Select_Game(bool fade) return (false); } CCDebugString("C&C95 - Scenario started OK.\n"); + +#ifdef DS_RADAR_UPSCREEN + UpperSeenBuff.Clear(); + UpperHidBuff.Fill_Rect(0, 0, 256, 160, GREY); +#endif } /* diff --git a/tiberiandawn/menus.cpp b/tiberiandawn/menus.cpp index b3db2012..a4cc6c99 100644 --- a/tiberiandawn/menus.cpp +++ b/tiberiandawn/menus.cpp @@ -437,6 +437,65 @@ int Do_Menu(char const** strings, bool blue) } #endif +#ifdef DS_RADAR_UPSCREEN +void Clumsy_Upperscreen_Menu(void) +{ + GraphicViewPortClass *old; + old = Set_Logic_Page(UpperHidBuff); + Set_Upperscreen_DD_Palette(MFCD::Retrieve("TEMPERAT.PAL")); + + unsigned char *buffer = (unsigned char *) UpperHidBuff.Get_Graphic_Buffer()->Get_Buffer(); + + memset(buffer, LTGREY, 256*160); + + for (int y = 0; y < 160; y++) { + for (int x = 0; x < 256; x++) { + if (Random_Pick(0, 20) == 0) { + buffer[256 * y + x] = DKGREY; + } + } + } + + int l = 10; + for (int x = -l; x <= l; x++) { + int color = (abs(x) == l || x == 0) ? DKGREY : BLACK; + + UpperHidBuff.Draw_Line(128 + x, 0, 128 + x, 20, color); + UpperHidBuff.Draw_Line(128 + x, 21, 152 + x, 40, color); + UpperHidBuff.Draw_Line(152 + x, 41, 152 + x, 60, color); + UpperHidBuff.Draw_Line(152 + x, 61, 128 + x, 80, color); + UpperHidBuff.Draw_Line(128 + x, 81, 104 + x, 100, color); + UpperHidBuff.Draw_Line(104 + x, 101, 104 + x, 120, color); + UpperHidBuff.Draw_Line(104 + x, 121, 128 + x, 140, color); + UpperHidBuff.Draw_Line(128 + x, 141, 128 + x, 160, color); + } + + + for (int y = 0; y < 160; y++) { + for (int x = 104 - l; x <= 152 + l; x++) { + if (buffer[256 * y + x] == BLACK) { + if ((10*x + 12*y + 50) % 200 < 100) { + buffer[256 * y + x] = BLACK; + } else { + buffer[256 * y + x] = YELLOW; + } + } + } + } + + const void *gdi = MFCD::Retrieve("RADAR.GDI"); + const void *nod = MFCD::Retrieve("RADAR.NOD"); + + if (gdi && nod) { + CC_Draw_Shape(gdi, 0, 10, 8, WINDOW_MAIN, SHAPE_NORMAL); + CC_Draw_Shape(nod, 1, 166, 83, WINDOW_MAIN, SHAPE_NORMAL); + } + UpperHidBuff.Blit(UpperSeenBuff); + + Set_Logic_Page(old); +} +#endif + /*************************************************************************** * Main_Menu -- Menu processing * * * @@ -826,6 +885,10 @@ int Main_Menu(unsigned int timeout) Blit_Hid_Page_To_Seen_Buff(); Show_Mouse(); +#ifdef DS_RADAR_UPSCREEN + Clumsy_Upperscreen_Menu(); +#endif + Set_Logic_Page(SeenBuff); startbtn.Draw_All(); if (ScreenWidth == 320) { diff --git a/tiberiandawn/power.cpp b/tiberiandawn/power.cpp index 5a5ecc2c..6bd12982 100644 --- a/tiberiandawn/power.cpp +++ b/tiberiandawn/power.cpp @@ -133,7 +133,11 @@ void PowerClass::One_Time(void) if (factor) { PowY = Map.RadY + Map.RadHeight + (13 << factor) - 4; } else { +#ifdef DS_RADAR_UPSCREEN + PowY = Map.Get_Tab_Height() + 12; +#else PowY = Map.RadY + Map.RadHeight + (13 << factor); +#endif } PowWidth = 8 << factor; PowHeight = SeenBuff.Get_Height() - PowY; @@ -214,8 +218,12 @@ void PowerClass::Draw_It(bool complete) int x1 = x0 + 7; int y0 = PowY + 1; int y1 = bottom; - +#ifdef DS_RADAR_UPSCREEN + LogicPage->Fill_Rect(x0, y0-1, x1, y1, LTGREY); //Inside power bar +#else LogicPage->Fill_Rect(x0, y0, x1, y1, LTGREY); //Inside power bar +#endif + LogicPage->Draw_Line(x0, y0, x0, y1, WHITE); //Left line LogicPage->Draw_Line(x0 + 1, y0, x0 + 1, y1, GREY); //Left shadow line LogicPage->Draw_Line(x0, y0, x1 - 1, y0, WHITE); //Upper line diff --git a/tiberiandawn/radar.cpp b/tiberiandawn/radar.cpp index ffacbd11..9d3da631 100644 --- a/tiberiandawn/radar.cpp +++ b/tiberiandawn/radar.cpp @@ -127,8 +127,13 @@ void RadarClass::One_Time(void) int factor = Get_Resolution_Factor(); RadWidth = 80 << factor; RadHeight = 70 << factor; +#ifdef DS_RADAR_UPSCREEN + RadX = (UpperSeenBuff.Get_Width() - RadWidth) / 2; + RadY = (UpperSeenBuff.Get_Height() - RadHeight) / 2; +#else RadX = SeenBuff.Get_Width() - RadWidth; RadY = Map.Get_Tab_Height() - (1 << factor); +#endif RadPWidth = MAP_CELL_W << factor; RadPHeight = MAP_CELL_H << factor; @@ -351,22 +356,34 @@ void RadarClass::Draw_It(bool forced) _house = PlayerPtr->ActLike; } +#ifdef DS_RADAR_UPSCREEN + GraphicViewPortClass* oldpage = Set_Logic_Page(UpperHidBuff); +#endif + /* ** If in player name mode, just draw player names */ if (IsPlayerNames) { Draw_Names(); IsToRedraw = false; +#ifdef DS_RADAR_UPSCREEN + Set_Logic_Page(oldpage); +#endif return; } if (IsRadarActivating || IsRadarDeactivating) { Radar_Anim(); IsToRedraw = false; +#ifdef DS_RADAR_UPSCREEN + Set_Logic_Page(oldpage); +#endif return; } +#ifndef DS_RADAR_UPSCREEN if (Map.IsSidebarActive) { +#endif if (IsRadarActive) { // HidPage.Lock(); @@ -425,8 +442,13 @@ void RadarClass::Draw_It(bool forced) Radar_Cursor(RadarCursorRedraw); } else { +#ifdef DS_RADAR_UPSCREEN + GraphicViewPortClass* oldpage = Set_Logic_Page(UpperHidBuff); +#else GraphicViewPortClass* oldpage = Set_Logic_Page(HidPage); +#endif // if (LogicPage->Lock()) { + CC_Draw_Shape(RadarAnim, RADAR_ACTIVATED_FRAME, RadX, RadY + 1, WINDOW_MAIN, SHAPE_NORMAL); if (BaseX || BaseY) { LogicPage->Fill_Rect(RadX + RadOffX, @@ -454,7 +476,11 @@ void RadarClass::Draw_It(bool forced) LogicPage->Unlock(); if (oldpage == &SeenBuff) { Hide_Mouse(); +#ifdef DS_RADAR_UPSCREEN + LogicPage->Blit(UpperSeenBuff, RadX, RadY, RadX, RadY, RadWidth, RadHeight); +#else LogicPage->Blit(SeenBuff, RadX, RadY, RadX, RadY, RadWidth, RadHeight); +#endif Show_Mouse(); } @@ -470,15 +496,27 @@ void RadarClass::Draw_It(bool forced) */ // if (forced) { int val = (DoesRadarExist) ? MAX_RADAR_FRAMES : 0; + +#ifdef DS_RADAR_UPSCREEN + GraphicViewPortClass* oldpage = Set_Logic_Page(UpperHidBuff); +#endif CC_Draw_Shape(RadarAnim, val, RadX, RadY + 1, WINDOW_MAIN, SHAPE_NORMAL); FullRedraw = false; IsToRedraw = false; + +#ifdef DS_RADAR_UPSCREEN + Set_Logic_Page(oldpage); +#endif // } } // HidPage.Unlock(); // Map.Activator.Draw_Me(true); +#ifndef DS_RADAR_UPSCREEN } +#else + Set_Logic_Page(oldpage); +#endif #endif } @@ -910,6 +948,10 @@ void RadarClass::Radar_Pixel(CELL cell) *=============================================================================================*/ int RadarClass::Click_In_Radar(int& ptr_x, int& ptr_y, bool change) { +#ifdef DS_RADAR_UPSCREEN + return 0; +#endif + int x = ptr_x; int y = ptr_y; @@ -1187,7 +1229,11 @@ void RadarClass::Radar_Cursor(int forced) ** setup a graphic view port class so we can write all the pixels relative ** to 0,0 rather than relative to full screen coordinates. */ +#ifdef DS_RADAR_UPSCREEN + oldpage = Set_Logic_Page(UpperHidBuff); +#else oldpage = Set_Logic_Page(HidPage); +#endif GraphicViewPortClass draw_window(LogicPage->Get_Graphic_Buffer(), RadX + RadOffX + BaseX + LogicPage->Get_XPos(), RadY + RadOffY + BaseY + LogicPage->Get_YPos(), @@ -1257,8 +1303,11 @@ void RadarClass::Radar_Anim(void) if (!Map.IsSidebarActive) return; - +#ifdef DS_RADAR_UPSCREEN + GraphicViewPortClass* oldpage = Set_Logic_Page(UpperHidBuff); +#else GraphicViewPortClass* oldpage = Set_Logic_Page(HidPage); +#endif GraphicViewPortClass draw_window(LogicPage->Get_Graphic_Buffer(), RadX + RadOffX + LogicPage->Get_XPos(), RadY + RadOffY + LogicPage->Get_YPos(), @@ -1368,6 +1417,10 @@ int RadarClass::TacticalClass::Action(unsigned flags, KeyNumType& key) ObjectClass* object = 0; // what object is in the cell ActionType action = ACTION_NONE; // Action possible with currently selected object. +#ifdef DS_RADAR_UPSCREEN + return false; // Clicking on map is not possible on upper screen. +#endif + /* ** Force any help label to disappear when the mouse is held over the ** radar map. @@ -1622,35 +1675,47 @@ void RadarClass::Set_Radar_Position(CELL cell) /* ** Blit the section that is actually overlapping. */ + +#ifdef DS_RADAR_UPSCREEN + UpperSeenBuff.Blit(UpperHiddenPage, + (((radx < 0) ? -radx : 0) * ZoomFactor) + RadX + RadOffX + BaseX, + (((rady < 0) ? -rady : 0) * ZoomFactor) + RadY + RadOffY + BaseY, + (((radx < 0) ? 0 : radx) * ZoomFactor) + RadX + RadOffX + BaseX, + (((rady < 0) ? 0 : rady) * ZoomFactor) + RadY + RadOffY + BaseY, + radw * ZoomFactor, + radh * ZoomFactor); +#else if (OverlappedVideoBlits || !HidPage.Get_IsDirectDraw()) { - HidPage.Blit(HidPage, - (((radx < 0) ? -radx : 0) * ZoomFactor) + RadX + RadOffX + BaseX, - (((rady < 0) ? -rady : 0) * ZoomFactor) + RadY + RadOffY + BaseY, - (((radx < 0) ? 0 : radx) * ZoomFactor) + RadX + RadOffX + BaseX, - (((rady < 0) ? 0 : rady) * ZoomFactor) + RadY + RadOffY + BaseY, - radw * ZoomFactor, - radh * ZoomFactor); + GraphicViewPortClass &Hid = HidPage; + Hid.Blit(Hid, + (((radx < 0) ? -radx : 0) * ZoomFactor) + RadX + RadOffX + BaseX, + (((rady < 0) ? -rady : 0) * ZoomFactor) + RadY + RadOffY + BaseY, + (((radx < 0) ? 0 : radx) * ZoomFactor) + RadX + RadOffX + BaseX, + (((rady < 0) ? 0 : rady) * ZoomFactor) + RadY + RadOffY + BaseY, + radw * ZoomFactor, + radh * ZoomFactor); } else { /* ** System does not support overlapped blitting of video surfaces. ** Blit it in 2 stages using an intermediate buffer. */ GraphicBufferClass temp_surface; + GraphicViewPortClass &Hid = HidPage; temp_surface.Init((RadarWidth + 16) & 0xfffffff0, (RadarHeight + 16) & 0xfffffff0, NULL, 0, (GBC_Enum)GBC_VIDEOMEM); - HidPage.Blit(temp_surface, - (((radx < 0) ? -radx : 0) * ZoomFactor) + RadX + RadOffX + BaseX, - (((rady < 0) ? -rady : 0) * ZoomFactor) + RadY + RadOffY + BaseY, - 0, - 0, - RadarWidth, - RadarHeight); + Hid.Blit(temp_surface, + (((radx < 0) ? -radx : 0) * ZoomFactor) + RadX + RadOffX + BaseX, + (((rady < 0) ? -rady : 0) * ZoomFactor) + RadY + RadOffY + BaseY, + 0, + 0, + RadarWidth, + RadarHeight); - temp_surface.Blit(HidPage, + temp_surface.Blit(Hid, 0, 0, (((radx < 0) ? 0 : radx) * ZoomFactor) + RadX + RadOffX + BaseX, @@ -1658,7 +1723,7 @@ void RadarClass::Set_Radar_Position(CELL cell) radw * ZoomFactor, radh * ZoomFactor); } - +#endif /* ** Now we need to flag the section of the map that is going to redraw. */ @@ -1863,9 +1928,16 @@ void RadarClass::Draw_Names(void) /* ** Do nothing if the sidebar isn't there */ + +#ifndef DS_RADAR_UPSCREEN if (!Map.IsSidebarActive) { return; } +#endif + +#ifdef DS_RADAR_UPSCREEN + GraphicViewPortClass* oldpage = Set_Logic_Page(UpperHidBuff); +#endif CC_Draw_Shape(RadarAnim, RADAR_ACTIVATED_FRAME, RadX, RadY + 1, WINDOW_MAIN, SHAPE_NORMAL); LogicPage->Fill_Rect( @@ -1954,4 +2026,8 @@ void RadarClass::Draw_Names(void) y += 6 * factor + 1; } } + +#ifdef DS_RADAR_UPSCREEN + Set_Logic_Page(oldpage); +#endif } diff --git a/tiberiandawn/sidebar.cpp b/tiberiandawn/sidebar.cpp index f76e29cd..1aa927d4 100644 --- a/tiberiandawn/sidebar.cpp +++ b/tiberiandawn/sidebar.cpp @@ -77,6 +77,9 @@ #include "function.h" #include "settings.h" +extern GraphicViewPortClass SeenBuff; +extern GraphicViewPortClass HidPage; + /* ** Define "_RETRIEVE" if the palette morphing tables are part of the loaded data. If this ** is undefined, then the files will be created. @@ -179,10 +182,14 @@ void SidebarClass::One_Time(void) int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; SideBarWidth = SIDEBARWIDTH * factor; SideX = SeenBuff.Get_Width() - SideBarWidth; +#ifdef DS_RADAR_UPSCREEN + SideY = Map.Get_Tab_Height(); +#else SideY = Map.RadY + Map.RadHeight + 1; +#endif SideWidth = SeenBuff.Get_Width() - SideX; SideHeight = SeenBuff.Get_Height() - SideY; - MaxVisible = 4; + MaxVisible = StripClass::MAX_VISIBLE; ButtonHeight = 9 * factor; TopHeight = ButtonHeight + (4 * factor); @@ -382,6 +389,11 @@ void SidebarClass::Init_IO(void) Zoom->Y = Upgrade->Y; Zoom->Width = 20; Zoom->Height = Upgrade->Height; +#ifdef DS_RADAR_UPSCREEN + Repair->Y = 10; + Upgrade->Y = 10; + Zoom->Y = 10; +#endif } Repair->IsSticky = true; @@ -1012,7 +1024,11 @@ bool SidebarClass::Activate(int control) bool old = IsSidebarActive; int sidex = SeenBuff.Get_Width() - SideBarWidth; +#ifdef DS_RADAR_UPSCREEN + int sidey = Map.Get_Tab_Height() + Map.RadHeight; +#else int sidey = Map.RadY + Map.RadHeight; +#endif int topheight = 13; int sidewidth = SeenBuff.Get_Width() - sidex; int sideheight = SeenBuff.Get_Height() - sidey; diff --git a/tiberiandawn/sidebar.h b/tiberiandawn/sidebar.h index b633a44e..481d9828 100644 --- a/tiberiandawn/sidebar.h +++ b/tiberiandawn/sidebar.h @@ -216,7 +216,11 @@ class SidebarClass : public PowerClass OBJECT_HEIGHT = 24, // Pixel height of each buildable object. OBJECT_WIDTH = 32, // Pixel width of each buildable object. STRIP_WIDTH = 35, // Width of strip (not counting border lines). +#ifdef DS_RADAR_UPSCREEN + MAX_VISIBLE = 7, // Number of object slots visible at any one time. +#else MAX_VISIBLE = 4, // Number of object slots visible at any one time. +#endif SCROLL_RATE = 8, // The pixel jump while scrolling (larger is faster). BUTTON_SPACING_OFFSET = 4, // spacing info for buttons UP_X_OFFSET = 2, // Scroll up arrow coordinates. diff --git a/tiberiandawn/startup.cpp b/tiberiandawn/startup.cpp index 1f78af6c..77b9ea30 100644 --- a/tiberiandawn/startup.cpp +++ b/tiberiandawn/startup.cpp @@ -391,6 +391,13 @@ int main(int argc, char** argv) SeenBuff.Attach(&VisiblePage, 0, 0, GBUFF_INIT_WIDTH, GBUFF_INIT_HEIGHT); HidPage.Attach(&HiddenPage, 0, 0, GBUFF_INIT_WIDTH, GBUFF_INIT_HEIGHT); +#ifdef DS_RADAR_UPSCREEN + UpperVisiblePage.Init(256, 160, NULL, 0, (GBC_Enum)(GBC_VISIBLE | GBC_VIDEOMEM | GBC_UPPERSCREEN)); + UpperHiddenPage.Init(256, 160, NULL, 0, (GBC_Enum)(GBC_UPPERSCREEN)); + UpperSeenBuff.Attach(&UpperVisiblePage, 0, 0, 256, 160); + UpperHidBuff.Attach(&UpperHiddenPage, 0, 0, 256, 160); +#endif + CCDebugString("C&C95 - Adjusting variables for resolution.\n"); Options.Adjust_Variables_For_Resolution(); diff --git a/tiberiandawn/tab.cpp b/tiberiandawn/tab.cpp index d8d8a537..7030cd17 100644 --- a/tiberiandawn/tab.cpp +++ b/tiberiandawn/tab.cpp @@ -110,7 +110,7 @@ void TabClass::Draw_It(bool complete) LogicPage->Fill_Rect(0, 0, rightx, Tab_Height - 2, BLACK); CC_Draw_Shape(TabShape, 0, 0, 0, WINDOW_MAIN, SHAPE_NORMAL); CC_Draw_Shape(TabShape, 0, width - Eva_Width, 0, WINDOW_MAIN, SHAPE_NORMAL); - Draw_Credits_Tab(); + //Draw_Credits_Tab(); // Why is this here? LogicPage->Draw_Line(0, Tab_Height - 1, rightx, Tab_Height - 1, BLACK); Fancy_Text_Print(TXT_TAB_BUTTON_CONTROLS, Eva_Width / 2, 0, fore, TBLACK, flags); @@ -127,8 +127,13 @@ void TabClass::Draw_It(bool complete) void TabClass::Draw_Credits_Tab(void) { +#ifdef DS_RADAR_UPSCREEN + unsigned x = 256 - 80; + CC_Draw_Shape(TabShape, 0, x, 160 - 8, WINDOW_MAIN, SHAPE_NORMAL); +#else unsigned x = Get_Resolution_Factor() ? 320 : 160; CC_Draw_Shape(TabShape, 0, x, 0, WINDOW_MAIN, SHAPE_NORMAL); +#endif } /***********************************************************************************************