From e891377c96aaf892c2784f583d6f905b7ad70ea4 Mon Sep 17 00:00:00 2001 From: Justin Marshall Date: Thu, 4 Jun 2020 15:10:30 -0700 Subject: [PATCH] Added WSA code from CC, Map Selection Works, temp disabled keyboard input for score screen. --- REDALERT/FUNCTION.H | 2 + REDALERT/GADGET.CPP | 38 +- REDALERT/MAPSEL.CPP | 11 +- REDALERT/RedAlert.vcxproj | 1 + REDALERT/RedAlert.vcxproj.filters | 3 + REDALERT/SCORE.CPP | 126 ++-- REDALERT/WIN32LIB/WSA.CPP | 1153 +++++++++++++++++++++++++++++ REDALERT/WINSTUB.CPP | 42 ++ 8 files changed, 1272 insertions(+), 104 deletions(-) create mode 100644 REDALERT/WIN32LIB/WSA.CPP diff --git a/REDALERT/FUNCTION.H b/REDALERT/FUNCTION.H index 6d99d8c..67086f5 100644 --- a/REDALERT/FUNCTION.H +++ b/REDALERT/FUNCTION.H @@ -1072,6 +1072,8 @@ extern DynamicVectorClass xxx3; template <>class DynamicVectorClass; extern DynamicVectorClass whatever; +void WWSDL_ProcessEvents(KeyNumType& key, int& flags); + /* ** Debug output. ST - 6/27/2019 10:00PM */ diff --git a/REDALERT/GADGET.CPP b/REDALERT/GADGET.CPP index 55842f6..1a449f2 100644 --- a/REDALERT/GADGET.CPP +++ b/REDALERT/GADGET.CPP @@ -460,7 +460,6 @@ void GadgetClass::Draw_All(bool forced) } } - /*************************************************************************** * GADGETCLASS::PROCESSLIST -- Check list for a mouse click within a gadget* * * @@ -535,42 +534,7 @@ KeyNumType GadgetClass::Input(void) */ // jmarshall int flags = 0; - SDL_GetMouseState(&mousex, &mousey); - - Keyboard->MouseQX = mousex; - Keyboard->MouseQY = mousey; - -// if (flags == LEFTRELEASE || flags == RIGHTRELEASE) -// flags = 0; - - SDL_Event event; - while (SDL_PollEvent(&event)) { - switch (event.type) - { - case SDL_MOUSEBUTTONDOWN: - if (event.button.button == SDL_BUTTON_LEFT) { - flags = LEFTPRESS; - key = KN_LMOUSE; - } - else if (event.button.button == SDL_BUTTON_RIGHT) { - flags = RIGHTPRESS; - key = KN_LMOUSE; - } - break; - - case SDL_MOUSEBUTTONUP: - if (event.button.button == SDL_BUTTON_LEFT) { - flags = LEFTRELEASE; - } - else if (event.button.button == SDL_BUTTON_RIGHT) { - flags = RIGHTRELEASE; - } - break; - case SDL_KEYDOWN: - Keyboard->Put_Element(event.key.keysym.sym); - break; - } - } + WWSDL_ProcessEvents(key, flags); // jmarshall end /* diff --git a/REDALERT/MAPSEL.CPP b/REDALERT/MAPSEL.CPP index 55ffa60..d96c588 100644 --- a/REDALERT/MAPSEL.CPP +++ b/REDALERT/MAPSEL.CPP @@ -107,8 +107,6 @@ extern short StreamLowImpact; #endif char const * Map_Selection(void) { - return NULL; -#if (0)//PG static char scenarioname[_MAX_FNAME+_MAX_EXT]; #ifdef FIXIT_ANTS @@ -147,14 +145,14 @@ char const * Map_Selection(void) void const * country1 = MFCD::Retrieve("TONEY10.AUD"); #ifdef WIN32 - GraphicBufferClass *pseudoseenbuff = new GraphicBufferClass(320, 200, (void*)NULL); + GraphicBufferClass* pseudoseenbuff = &VisiblePage; // GraphicBufferClass(320, 200, (void*)NULL); #endif // fixed oldvolume = Options.ScoreVolume; // Options.Set_Score_Volume(fixed(4, 10)); Theme.Queue_Song(THEME_MAP); - void *anim = Open_Animation(_filename, NULL, 0L, (WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE), mappalette); + void *anim = Open_Animation(_filename, NULL, 0L, (WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE), (unsigned char *)mappalette.Get_Data()); Keyboard->Clear(); SeenPage.Clear(); @@ -174,7 +172,7 @@ char const * Map_Selection(void) int frame = 1; - StreamLowImpact = true; + //StreamLowImpact = true; #ifdef WIN32 Play_Sample(appear1, 255, Options.Normalize_Volume(170)); #else @@ -221,7 +219,7 @@ char const * Map_Selection(void) break; } } - StreamLowImpact = false; + //StreamLowImpact = false; Call_Back(); Close_Animation(anim); Show_Mouse(); @@ -317,7 +315,6 @@ char const * Map_Selection(void) // Scen.ScenVar = (ScenarioVarType)selection; //Mono_Printf("Chose variant %d \n", selection); return(scenarioname); -#endif } int Mouse_Over_Spot(int house, int scenario) diff --git a/REDALERT/RedAlert.vcxproj b/REDALERT/RedAlert.vcxproj index 81a1e5c..9d76d96 100644 --- a/REDALERT/RedAlert.vcxproj +++ b/REDALERT/RedAlert.vcxproj @@ -453,6 +453,7 @@ + diff --git a/REDALERT/RedAlert.vcxproj.filters b/REDALERT/RedAlert.vcxproj.filters index 137b854..45979bb 100644 --- a/REDALERT/RedAlert.vcxproj.filters +++ b/REDALERT/RedAlert.vcxproj.filters @@ -939,6 +939,9 @@ Source Files\libsmacker + + Source Files\win32lib + diff --git a/REDALERT/SCORE.CPP b/REDALERT/SCORE.CPP index 385970f..c2d474b 100644 --- a/REDALERT/SCORE.CPP +++ b/REDALERT/SCORE.CPP @@ -1421,66 +1421,72 @@ void ScoreClass::Input_Name(char str[], int xpos, int ypos, char const pal[]) ** with black. */ HidPage.Blit(HidPage, 0, 100*RESFACTOR, 0, 0, 100*RESFACTOR, 100*RESFACTOR); - - do { - Call_Back(); - Animate_Score_Objs(); - Animate_Cursor(index, ypos); - if (Keyboard->Check()) { - key = Keyboard->To_ASCII(Keyboard->Get()) & 0xFF; - Call_Back(); - - if (index == MAX_FAMENAME_LENGTH-2) { - while (Keyboard->Check()) { - Keyboard->Get(); - } - } - - /* - ** If they hit 'backspace' when they're on the last letter, - ** turn it into a space instead. - */ - if ((key == KA_BACKSPACE) && (index == MAX_FAMENAME_LENGTH-2) ) { - if (str[index] && str[index]!=32) key = 32; - } - if (key == KA_BACKSPACE) { //if (key == KN_BACKSPACE) { - if (index) { - str[--index] = 0; - - int xposindex6 = (xpos+(index*6))*RESFACTOR; - HidPage.Blit(SeenPage, xposindex6, (ypos-100)*RESFACTOR, xposindex6, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); - #ifdef WIN32 - HidPage.Blit(*PseudoSeenBuff, xposindex6, (ypos-100)*RESFACTOR, xposindex6, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); - #endif - HidPage.Blit(HidPage, xposindex6, (ypos-100)*RESFACTOR, xposindex6, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); - } - - } else if (key != KA_RETURN) { //else if (key != KN_RETURN && key!=KN_KEYPAD_RETURN) { - ascii = key; //ascii = KN_To_KA(key); - if (ascii >= 'a' && ascii <= 'z') ascii -= ('a' - 'A'); - if ( (ascii >= '!' && ascii <= KA_TILDA) || ascii == ' ') { - HidPage.Blit(SeenPage, (xpos + (index*6))*RESFACTOR, (ypos-100)*RESFACTOR, (xpos + (index*6))*RESFACTOR, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); - #ifdef WIN32 - HidPage.Blit(*PseudoSeenBuff, (xpos + (index*6))*RESFACTOR, (ypos-100)*RESFACTOR, (xpos + (index*6))*RESFACTOR, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); - #endif - HidPage.Blit(HidPage, (xpos + (index*6))*RESFACTOR, (ypos-100)*RESFACTOR, (xpos + (index*6))*RESFACTOR, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); - str[index] = ascii; - str[index+1] = 0; - - int objindex; -#ifdef WIN32 - Play_Sample(keystrok, 255, Options.Normalize_Volume(150)); -#else - Play_Sample(keystrok, 255, Options.Normalize_Volume(105)); -#endif - objindex = Alloc_Object(new ScoreScaleClass(str+index, xpos+(index*6), ypos, pal)); - while (ScoreObjs[objindex]) Call_Back_Delay(1); - - if (index < (MAX_FAMENAME_LENGTH-2) ) index++; - } - } - } - } while (key != KA_RETURN); // } while(key != KN_RETURN && key!=KN_KEYPAD_RETURN); +// jmarshall - temp disable high school writing. +// do { +//// jmarshall +// KeyNumType _key; +// int flags; +// WWSDL_ProcessEvents(_key, flags); +//// jmarshall end +// Call_Back(); +// Animate_Score_Objs(); +// Animate_Cursor(index, ypos); +// if (Keyboard->Check()) { +// key = Keyboard->To_ASCII(Keyboard->Get()) & 0xFF; +// Call_Back(); +// +// if (index == MAX_FAMENAME_LENGTH-2) { +// while (Keyboard->Check()) { +// Keyboard->Get(); +// } +// } +// +// /* +// ** If they hit 'backspace' when they're on the last letter, +// ** turn it into a space instead. +// */ +// if ((key == KA_BACKSPACE) && (index == MAX_FAMENAME_LENGTH-2) ) { +// if (str[index] && str[index]!=32) key = 32; +// } +// if (key == KA_BACKSPACE) { //if (key == KN_BACKSPACE) { +// if (index) { +// str[--index] = 0; +// +// int xposindex6 = (xpos+(index*6))*RESFACTOR; +// HidPage.Blit(SeenPage, xposindex6, (ypos-100)*RESFACTOR, xposindex6, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); +// #ifdef WIN32 +// HidPage.Blit(*PseudoSeenBuff, xposindex6, (ypos-100)*RESFACTOR, xposindex6, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); +// #endif +// HidPage.Blit(HidPage, xposindex6, (ypos-100)*RESFACTOR, xposindex6, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); +// } +// +// } else if (key != KA_RETURN) { //else if (key != KN_RETURN && key!=KN_KEYPAD_RETURN) { +// ascii = key; //ascii = KN_To_KA(key); +// if (ascii >= 'a' && ascii <= 'z') ascii -= ('a' - 'A'); +// if ( (ascii >= '!' && ascii <= KA_TILDA) || ascii == ' ') { +// HidPage.Blit(SeenPage, (xpos + (index*6))*RESFACTOR, (ypos-100)*RESFACTOR, (xpos + (index*6))*RESFACTOR, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); +// #ifdef WIN32 +// HidPage.Blit(*PseudoSeenBuff, (xpos + (index*6))*RESFACTOR, (ypos-100)*RESFACTOR, (xpos + (index*6))*RESFACTOR, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); +// #endif +// HidPage.Blit(HidPage, (xpos + (index*6))*RESFACTOR, (ypos-100)*RESFACTOR, (xpos + (index*6))*RESFACTOR, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); +// str[index] = ascii; +// str[index+1] = 0; +// +// int objindex; +//#ifdef WIN32 +// Play_Sample(keystrok, 255, Options.Normalize_Volume(150)); +//#else +// Play_Sample(keystrok, 255, Options.Normalize_Volume(105)); +//#endif +// objindex = Alloc_Object(new ScoreScaleClass(str+index, xpos+(index*6), ypos, pal)); +// while (ScoreObjs[objindex]) Call_Back_Delay(1); +// +// if (index < (MAX_FAMENAME_LENGTH-2) ) index++; +// } +// } +// } +// } while (key != KA_RETURN); // } while(key != KN_RETURN && key!=KN_KEYPAD_RETURN); +// jmarshall end } diff --git a/REDALERT/WIN32LIB/WSA.CPP b/REDALERT/WIN32LIB/WSA.CPP new file mode 100644 index 0000000..3dcc2f9 --- /dev/null +++ b/REDALERT/WIN32LIB/WSA.CPP @@ -0,0 +1,1153 @@ +// +// Copyright 2020 Electronic Arts Inc. +// +// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free +// software: you can redistribute it and/or modify it under the terms of +// the GNU General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. + +// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed +// in the hope that it will be useful, but with permitted additional restrictions +// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT +// distributed with this program. You should have received a copy of the +// GNU General Public License along with permitted additional restrictions +// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection + +/* $Header: g:/library/source/rcs/./wsa.c 1.16 1994/05/20 15:35:27 joe_bostic Exp $ */ +/*************************************************************************** + ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** + *************************************************************************** + * * + * Project Name : Library Animation System * + * * + * File Name : WSA.C * + * * + * Programmer : Michael Legg * + * * + * Start Date : November 20, 1991 * + * * + *-------------------------------------------------------------------------* + * There are many different ways that the user can use the WSA library * + * module. The options are as follows : * + * * + * System Allocation vs User Buffer - The user may request that the * + * system allocate the needed buffer from the heap or the user may * + * pass his own buffer in for the animator to use. * + * * + * Resident vs File based - If there is enough RAM, the user may put the * + * entire animation into RAM for fastest animations. If there is * + * not enouph RAM, the system will automatically make it so each * + * frame will be read off disk when needed. * + * * + * Direct to Page vs Use of a user buffer -- Noramally Direct to page * + * is the best method both in speed and in RAM need to hold anim. * + * One may want to use the write to user buffer method if they * + * are using the animation in a non sequencial order. * + * * + *-------------------------------------------------------------------------* + * Functions: * + * Animate_Frame -- Displays a frame of a given animation * + * Get_Animation_Frame_Count -- Return Number of frames in an animation. * + * Get_Animation_X -- Gets the x from an animation * + * Get_Animation_Y -- Gets the y from an animation * + * Get_Animation_Width -- Gets the width from an animation * + * Get_Animation_Height -- The height of the animation we are processing * + * Apply_Delta -- Copies frame into delta buffer, then applies to target * + * Close_Animation -- Close the animation, freeing the space if necessary* + * Get_File_Frame_Offset -- Get offset of a delta frame from animate file* + * Get_Resident_Frame_Offset -- Gets frame offset of animate file in RAM * + * Open_Animation -- Opens an animation file and reads into buffer * + *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +#include +#include "wsa.h" +#include +#include +#include +#include +//#include +#include + +// +// WSA animation header allocation type. +// If we need more then 8 flags for the flags variable, we can combine +// USER_ALLOCATED with SYS_ALLOCATED and combine FILE with RESIDENT. +// +#define WSA_USER_ALLOCATED 0x01 +#define WSA_SYS_ALLOCATED 0x02 +#define WSA_FILE 0x04 +#define WSA_RESIDENT 0x08 +#define WSA_TARGET_IN_BUFFER 0x10 +#define WSA_LINEAR_ONLY 0x20 +#define WSA_FRAME_0_ON_PAGE 0x40 +#define WSA_AMIGA_ANIMATION 0x80 +#define WSA_PALETTE_PRESENT 0x100 +#define WSA_FRAME_0_IS_DELTA 0x200 + +// These are used to call Apply_XOR_Delta_To_Page_Or_Viewport() to setup flags parameter. If +// These change, make sure and change their values in lp_asm.asm. +#define DO_XOR 0x0 +#define DO_COPY 0x01 +#define TO_VIEWPORT 0x0 +#define TO_PAGE 0x02 + + + + +typedef struct { + unsigned short current_frame; + unsigned short total_frames; + unsigned short pixel_x; + unsigned short pixel_y; + unsigned short pixel_width; + unsigned short pixel_height; + unsigned short largest_frame_size; + char *delta_buffer; + char *file_buffer; + char file_name[ 13 ]; + short flags; + // New fields that animate does not know about below this point. SEE EXTRA_charS_ANIMATE_NOT_KNOW_ABOUT + short file_handle; + unsigned long anim_mem_size; +} SysAnimHeaderType; + +// NOTE:"THIS IS A BAD THING. SINCE sizeof(SysAnimHeaderType) CHANGED, THE ANIMATE.EXE +// UTILITY DID NOT KNOW I UPDATED IT, IT ADDS IT TO largest_frame_size BEFORE SAVING +// IT TO THE FILE. THIS MEANS I HAVE TO ADD THESE charS ON NOW FOR IT TO WORK. +#define EXTRA_charS_ANIMATE_NOT_KNOW_ABOUT (sizeof(short) + sizeof(unsigned long)) + + +// +// Header structure for the file. +// NOTE: The 'total_frames' field is used to differentiate between Amiga and IBM +// animations. Amiga animations have the HIGH bit set. +// +typedef struct { + unsigned short total_frames; + unsigned short pixel_x; + unsigned short pixel_y; + unsigned short pixel_width; + unsigned short pixel_height; + unsigned short largest_frame_size; + short flags; + unsigned long frame0_offset; + unsigned long frame0_end; + /* unsigned long data_seek_offset, unsigned short frame_size ... */ +} WSA_FileHeaderType; + +#define WSA_FILE_HEADER_SIZE ( sizeof(WSA_FileHeaderType) - (2 * sizeof(unsigned long)) ) + +/*=========================================================================*/ +/* The following PRIVATE functions are in this file: */ +/*=========================================================================*/ + +PRIVATE unsigned long Get_Resident_Frame_Offset( char *file_buffer, int frame ); +PRIVATE unsigned long Get_File_Frame_Offset( int file_handle, int frame, int palette_adjust); +PRIVATE BOOL Apply_Delta(SysAnimHeaderType *sys_header, int curr_frame, char *dest_ptr, int dest_w); +/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ + + +/*************************************************************************** + * OPEN_ANIMATION -- Opens an animation file and reads into buffer * + * * + * INPUT: char *file_name of animation sequence file. * + * char *user_buffer pointer if one exists (NULL ok) * + * unsigned long user_buffer_size if known (NULL ok) * + * WSAOpenType user_flags - flags on how to open. * + * unsigned char *palette - pointer to palette space for return (NULL ok) * + * * + * OUTPUT: void *pointer to animation data. Must be used for all * + * other WSA calls. * + * * + * WARNINGS: May return NULL, please check. * + * * + * HISTORY: * + * 11/26/1991 SB : Created. * + *=========================================================================*/ +void * __cdecl Open_Animation(char const *file_name, char *user_buffer, long user_buffer_size, WSAOpenType user_flags, unsigned char *palette) +{ + int fh, anim_flags; + int palette_adjust; + unsigned int offsets_size; + unsigned int frame0_size; + long target_buffer_size, delta_buffer_size, file_buffer_size; + long max_buffer_size, min_buffer_size; + char *sys_anim_header_buffer; + char *target_buffer; + char *delta_buffer, *delta_back; + SysAnimHeaderType *sys_header; + WSA_FileHeaderType file_header; + + /*======================================================================*/ + /* Open the file to get the header information */ + /*======================================================================*/ + + anim_flags = 0; + fh = Open_File(file_name, READ); + Read_File(fh, (char *) &file_header, sizeof(WSA_FileHeaderType)); + + /*======================================================================*/ + /* If the file has an attached palette then if we have a valid palette */ + /* pointer we need to read it in. */ + /*======================================================================*/ + + if (file_header.flags & 1) { + anim_flags |= WSA_PALETTE_PRESENT; + palette_adjust = 768; + + if (palette != NULL) { + Seek_File(fh, sizeof(unsigned long) * (file_header.total_frames), SEEK_CUR); + Read_File(fh, palette, 768L); + } + + } else { + palette_adjust = 0; + } + + // Check for flag from ANIMATE indicating that this animation was + // created from a .LBM and a .ANM. These means that the first + // frame is a XOR Delta from a picture, not black. + if (file_header.flags & 2) { + anim_flags |= WSA_FRAME_0_IS_DELTA; + } + + + // Get the total file size minus the size of the first frame and the size + // of the file header. These will not be read in to save even more space. + file_buffer_size = Seek_File(fh, 0L, SEEK_END); + + if (file_header.frame0_offset) { + long tlong; + + tlong = file_header.frame0_end - file_header.frame0_offset; + frame0_size = (unsigned short) tlong; + } + else { + anim_flags |= WSA_FRAME_0_ON_PAGE; + frame0_size = 0; + } + + file_buffer_size -= palette_adjust + frame0_size + WSA_FILE_HEADER_SIZE; + + // We need to determine the buffer sizes required for the animation. At a + // minimum, we need a target buffer for the uncompressed frame and a delta + // buffer for the delta data. We may be able to make the file resident, + // so we will determine the file size. + // + // If the target buffer is in the user buffer + // Then figure its size + // and set the allocation flag + // Else size is zero. + // + if (user_flags & WSA_OPEN_DIRECT) { + target_buffer_size = 0L; + } + else { + anim_flags |= WSA_TARGET_IN_BUFFER; + target_buffer_size = (unsigned long) file_header.pixel_width * file_header.pixel_height; + } + + // NOTE:"THIS IS A BAD THING. SINCE sizeof(SysAnimHeaderType) CHANGED, THE ANIMATE.EXE + // UTILITY DID NOT KNOW I UPDATED IT, IT ADDS IT TO largest_frame_size BEFORE SAVING + // IT TO THE FILE. THIS MEANS I HAVE TO ADD THESE charS ON NOW FOR IT TO WORK. + delta_buffer_size = (unsigned long) file_header.largest_frame_size + EXTRA_charS_ANIMATE_NOT_KNOW_ABOUT; + min_buffer_size = target_buffer_size + delta_buffer_size; + max_buffer_size = min_buffer_size + file_buffer_size; + + // check to see if buffer size is big enough for at least min required + if (user_buffer && (user_buffer_size < min_buffer_size)) { + Close_File(fh); + return(NULL); + } + + // A buffer was not passed in, so do allocations + if (user_buffer == NULL) { + + // If the user wants it from the disk, then let us give it to him, + // otherwise, try to give a max allocation he can have. + if (user_flags & WSA_OPEN_FROM_DISK) { + user_buffer_size = min_buffer_size; + } + // else no buffer size, then try max configuration. + else if (!user_buffer_size) { + user_buffer_size = max_buffer_size; + } + // else if buffer specified is less then max needed, give min. + else if (user_buffer_size < max_buffer_size) { + user_buffer_size = min_buffer_size; + } + // otherwise we only want to alloc what we need. + else { + user_buffer_size = max_buffer_size; + } + + + // Check to see if enough RAM available for buffer_size. + if (user_buffer_size > Ram_Free(MEM_NORMAL)) { + + // If not enough room for even the min, return no buffer. + + if (min_buffer_size > Ram_Free(MEM_NORMAL)) { + Close_File(fh); + return(NULL); + } + + // Else make buffer size the min and allocate it. + user_buffer_size = min_buffer_size; + } + + // allocate buffer needed + user_buffer = (char *) Alloc(user_buffer_size, MEM_CLEAR); + + anim_flags |= WSA_SYS_ALLOCATED; + } + else { + // Check to see if the user_buffer_size should be min or max. + if ((user_flags & WSA_OPEN_FROM_DISK) || (user_buffer_size < max_buffer_size)) { + user_buffer_size = min_buffer_size; + } + else { + user_buffer_size = max_buffer_size; + } + anim_flags |= WSA_USER_ALLOCATED; + } + + + // Set the pointers to the RAM buffers + sys_anim_header_buffer = user_buffer; + target_buffer = (char *) Add_Long_To_Pointer(sys_anim_header_buffer, sizeof(SysAnimHeaderType)); + delta_buffer = (char *) Add_Long_To_Pointer(target_buffer, target_buffer_size); + + // Clear target buffer if it is in the user buffer. + if (target_buffer_size) { + memset( target_buffer, 0, (unsigned short) target_buffer_size ); + } + + // Poke data into the system animation header (start of user_buffer) + // current_frame is set to total_frames so that Animate_Frame() knows that + // it needs to clear the target buffer. + + sys_header = ( SysAnimHeaderType * ) sys_anim_header_buffer; + sys_header -> current_frame = + sys_header -> total_frames = file_header.total_frames; + sys_header -> pixel_x = file_header.pixel_x; + sys_header -> pixel_y = file_header.pixel_y; + sys_header -> pixel_width = file_header.pixel_width; + sys_header -> pixel_height = file_header.pixel_height; + sys_header -> anim_mem_size = user_buffer_size; + sys_header -> delta_buffer = delta_buffer; + sys_header -> largest_frame_size = + (unsigned short) (delta_buffer_size - sizeof(SysAnimHeaderType)); + + strcpy(sys_header->file_name, file_name); + + // Figure how much room the frame offsets take up in the file. + // Add 2 - one for the wrap around and one for the final end offset. + offsets_size = (file_header.total_frames + 2) << 2; + + // Can the user_buffer_size handle the maximum case buffer? + if ( user_buffer_size == max_buffer_size) { + + // + // set the file buffer pointer, + // Skip over the header information. + // Read in the offsets. + // Skip over the first frame. + // Read in remaining frames. + // + + sys_header->file_buffer = (char *)Add_Long_To_Pointer(delta_buffer,sys_header->largest_frame_size); + Seek_File( fh, WSA_FILE_HEADER_SIZE, SEEK_SET); + Read_File( fh, sys_header->file_buffer, offsets_size); + Seek_File( fh, frame0_size + palette_adjust, SEEK_CUR); + Read_File( fh, sys_header->file_buffer + offsets_size, + file_buffer_size - offsets_size); + + // + // Find out if there is an ending value for the last frame. + // If there is not, then this animation will not be able to + // loop back to the beginning. + // + if (Get_Resident_Frame_Offset( sys_header->file_buffer, sys_header->total_frames + 1)) + anim_flags |= WSA_RESIDENT; + else + anim_flags |= WSA_LINEAR_ONLY | WSA_RESIDENT; + } + else { // buffer cannot handle max_size of buffer + + if(Get_File_Frame_Offset( fh, sys_header->total_frames + 1, palette_adjust)) + anim_flags |= WSA_FILE; + else + anim_flags |= WSA_LINEAR_ONLY | WSA_FILE; +//// + sys_header->file_buffer = NULL; + } + + // Figure where to back load frame 0 into the delta buffer. + delta_back = (char *)Add_Long_To_Pointer(delta_buffer, + sys_header->largest_frame_size - frame0_size); + + // Read the first frame into the delta buffer and uncompress it. + // Then close it. + Seek_File( fh, WSA_FILE_HEADER_SIZE + offsets_size + palette_adjust, SEEK_SET); + Read_File( fh, delta_back, frame0_size); + + // We do not use the file handle when it is in RAM. + if (anim_flags & WSA_RESIDENT) { + sys_header -> file_handle = (short) -1; + Close_File(fh); + } + else { + sys_header -> file_handle = (short)fh; + } + + LCW_Uncompress(delta_back, delta_buffer, sys_header->largest_frame_size); + + // Finally set the flags, + sys_header->flags = (short)anim_flags; + + // return valid handle + return( user_buffer ); +} + + +/*************************************************************************** + * CLOSE_ANIMATION -- Close the animation, freeing the space if necessary. * + * * + * INPUT: void *handle to the animation data buffer * + * * + * OUTPUT: none * + * * + * WARNINGS: handle MUST have been returned by Open_Animation * + * * + * HISTORY: * + * 11/23/1991 ML : Created. * + *=========================================================================*/ +void __cdecl Close_Animation( void *handle ) +{ + SysAnimHeaderType *sys_header; + + // Assign our local system header pointer to the beginning of the handle space + sys_header = (SysAnimHeaderType *) handle; + + // Close the WSA file in it was disk based. + if (sys_header->flags & WSA_FILE) { + Close_File(sys_header->file_handle); + } + + // Check to see if the buffer was allocated OR the programmer provided the buffer + if (handle && sys_header->flags & WSA_SYS_ALLOCATED) { + Free(handle); + } +} + +/*************************************************************************** + * ANIMATE_FRAME -- Displays a frame of a given animation * + * * + * INPUT: void *handle to the animation. * + * int frame_number wanted to be displayed * + * int x_pixel position of left side of animation on page * + * int y_pixel position of top of animation on page * + * * + * OUTPUT: BOOL if successfull or not. * + * * + * WARNINGS: * + * * + * HISTORY: * + * 11/27/1991 SB : Created. * + *=========================================================================*/ +//#pragma off (unreferenced) +BOOL __cdecl Animate_Frame(void *handle, GraphicViewPortClass& view, + int frame_number, int x_pixel, int y_pixel, + WSAType flags_and_prio, void *magic_cols, void *magic) +{ + SysAnimHeaderType *sys_header; // fix up the void pointer past in. + int curr_frame; // current frame we are on. + int total_frames; // number of frames in anim. + int distance; // distance to desired frame. + int search_dir; // direcion to search for desired frame. + int search_frames; // How many frames to search. + int loop; // Just a loop varible. + char *frame_buffer; // our destination. + BOOL direct_to_dest; // are we going directly to the destination? + int dest_width; // the width of the destination buffer or page. + + + // Assign local pointer to the beginning of the buffer where the system information + // resides + sys_header = (SysAnimHeaderType *)handle; + + // Get the total number of frames + total_frames = sys_header->total_frames; + + // Are the animation handle and the frame number valid? + if (!handle || (total_frames <= frame_number)) { + return FALSE; + } + + if (view.Lock()!=TRUE) return (FALSE); + + // Decide if we are going to a page or a viewport (part of a buffer). + dest_width = view.Get_Width() + view.Get_XAdd() + view.Get_Pitch(); + + // + // adjust x_pixel and y_pixel by system pixel_x and pixel_y respectively. + // + x_pixel += (short)sys_header->pixel_x; + y_pixel += (short)sys_header->pixel_y; + + // + // Check to see if we are using a buffer inside of the animation buffer or if + // it is being drawn directly to the destination page or buffer. + // + if (sys_header->flags & WSA_TARGET_IN_BUFFER) { + // Get a pointer to the frame in animation buffer. + frame_buffer = (char *)Add_Long_To_Pointer(sys_header, sizeof(SysAnimHeaderType)); + direct_to_dest = FALSE; + } + else { + frame_buffer = (char *)view.Get_Offset(); + frame_buffer += (y_pixel * dest_width) + x_pixel; + direct_to_dest = TRUE; + } + // + // If current_frame is equal to tatal_frames, then no animations have taken place + // so must uncompress frame 0 in delta buffer to the frame_buffer/page if it + // exists. + // + if (sys_header->current_frame == total_frames) { + + // Call apply delta telling it wether to copy or to xor depending on if the + // target is a page or a buffer. + + if (!(sys_header->flags & WSA_FRAME_0_ON_PAGE)) { + if (direct_to_dest) { + + // The last parameter says weather to copy or to XOR. If the + // first frame is a DELTA, then it must be XOR'd. A TRUE is + // copy while FALSE is XOR. + + Apply_XOR_Delta_To_Page_Or_Viewport(frame_buffer, sys_header->delta_buffer, + sys_header->pixel_width, dest_width, //dest_width - sys_header->pixel_width, + (sys_header->flags & WSA_FRAME_0_IS_DELTA)? DO_XOR : DO_COPY); + } + else { + Apply_XOR_Delta(frame_buffer, sys_header->delta_buffer); + } + } + sys_header->current_frame = 0; + } + + // + // Get the current frame + // If no looping aloud, are the trying to do it anyways? + // + curr_frame = sys_header->current_frame; +#if (FALSE) + // This is commented out since we will let them loop even though they should + // not - it will be slower. + if ( (sys_header->flags & WSA_LINEAR_ONLY) && (frame_number < cur_frame) ) { + view.Unlock(); + return FALSE; + } +#endif + + // Get absoulte distance from our current frame to the target frame + distance = ABS(curr_frame - frame_number); + + // Assume we are searching right + search_dir = 1; + + // Calculate the number of frames to search if we go right and wrap + + if (frame_number > curr_frame) { + search_frames = total_frames - frame_number + curr_frame; + + // Is going right faster than going backwards? + // Or are they trying to loop when the should not? + if ((search_frames < distance) && !(sys_header->flags & WSA_LINEAR_ONLY)) { + search_dir = -1; // No, so go left + } + else { + search_frames = distance; + } + } + else { + search_frames = total_frames - curr_frame + frame_number; + + // Is going right faster than going backwards? + // Or are they trying to loop when the should not? + if ((search_frames >= distance) || (sys_header->flags & WSA_LINEAR_ONLY)) { + search_dir = -1; // No, so go left + search_frames = distance; + } + } + + // Take care of the case when we are searching right (possibly right) + + if (search_dir > 0) { + for (loop = 0; loop < search_frames; loop++) { + + // Move the logical frame number ordinally right + curr_frame += search_dir; + + Apply_Delta(sys_header, curr_frame, frame_buffer, dest_width); + + // Adjust the current frame number, taking into consideration that we could + // have wrapped + + if (curr_frame == total_frames) { + curr_frame = 0; + } + } + } + else { + for (loop = 0; loop < search_frames; loop++) { + + // If we are going backwards and we are on frame 0, the delta to get + // to the last frame is the n + 1 delta (wrap delta) + + if (curr_frame == 0) { + curr_frame = total_frames; + } + + Apply_Delta(sys_header, curr_frame, frame_buffer, dest_width); + + curr_frame += search_dir; + } + } + + sys_header->current_frame = (short)frame_number; + + // If we did this all in a hidden buffer, then copy it to the desired page or viewport. + if (sys_header->flags & WSA_TARGET_IN_BUFFER) { +#if TRUE + + Buffer_To_Page(x_pixel, y_pixel, sys_header->pixel_width, sys_header->pixel_height, frame_buffer, view); + +#else + int flags = ((unsigned short)flags_and_prio & 0xFF00u) >> 12u; + int pri = flags_and_prio & 0x00FF; + + Buffer_Bitblit_To_LogicPage(x_pixel, y_pixel, sys_header->pixel_width, + sys_header->pixel_height, 0, flags, frame_buffer, pri, + magic_cols, magic); +#endif + } + + view.Unlock(); + return TRUE; +} +/*************************************************************************** + * ANIMATE_FRAME -- Displays a frame of a given animation * + * * + * INPUT: void *handle to the animation. * + * int frame_number wanted to be displayed * + * int x_pixel position of left side of animation on page * + * int y_pixel position of top of animation on page * + * * + * OUTPUT: BOOL if successfull or not. * + * * + * WARNINGS: * + * * + * HISTORY: * + * 11/27/1991 SB : Created. * + *=========================================================================*/ +//#pragma argsused +#ifdef cuts +BOOL __cdecl Animate_Frame(void *handle, GraphicViewPortClass& view, + int frame_number, int x_pixel, int y_pixel, + WSAType flags_and_prio, void *magic_cols, void *magic) +{ + SysAnimHeaderType *sys_header; // fix up the void pointer past in. + int curr_frame; // current frame we are on. + int total_frames; // number of frames in anim. + int distance; // distance to desired frame. + int search_dir; // direcion to search for desired frame. + int search_frames; // How many frames to search. + int loop; // Just a loop varible. + char *frame_buffer; // our destination. + BOOL direct_to_dest; // are we going directly to the destination? + int dest_width; // the width of the destination buffer or page. + + // Assign local pointer to the beginning of the buffer where the system information + // resides + sys_header = (SysAnimHeaderType *)handle; + + // Get the total number of frames + total_frames = sys_header->total_frames; + + // Are the animation handle and the frame number valid? + if (!handle || (total_frames <= frame_number)) { + return FALSE; + } + + + // Decide if we are going to a page or a viewport (part of a buffer). + dest_width = view.Get_Width() + view.Get_XAdd(); + + // + // adjust x_pixel and y_pixel by system pixel_x and pixel_y respectively. + // + x_pixel += (short)sys_header->pixel_x; + y_pixel += (short)sys_header->pixel_y; + + // + // Check to see if we are using a buffer inside of the animation buffer or if + // it is being drawn directly to the destination page or buffer. + // + if (sys_header->flags & WSA_TARGET_IN_BUFFER) { + // Get a pointer to the frame in animation buffer. + frame_buffer = (char *)Add_Long_To_Pointer(sys_header, sizeof(SysAnimHeaderType)); + direct_to_dest = FALSE; + } + else { + frame_buffer = (char *)view.Get_Offset(); + frame_buffer += (y_pixel * dest_width) + x_pixel; + direct_to_dest = TRUE; + } + // + // If current_frame is equal to tatal_frames, then no animations have taken place + // so must uncompress frame 0 in delta buffer to the frame_buffer/page if it + // exists. + // + if (sys_header->current_frame == total_frames) { + + // Call apply delta telling it wether to copy or to xor depending on if the + // target is a page or a buffer. + + if (!(sys_header->flags & WSA_FRAME_0_ON_PAGE)) { + if (direct_to_dest) { + + // The last parameter says weather to copy or to XOR. If the + // first frame is a DELTA, then it must be XOR'd. A TRUE is + // copy while FALSE is XOR. + Apply_XOR_Delta_To_Page_Or_Viewport(frame_buffer, sys_header->delta_buffer, + sys_header->pixel_width, dest_width, //dest_width - sys_header->pixel_width, + (sys_header->flags & WSA_FRAME_0_IS_DELTA)? DO_XOR : DO_COPY); + } + else { + Apply_XOR_Delta(frame_buffer, sys_header->delta_buffer); + } + } + sys_header->current_frame = 0; + } + + // + // Get the current frame + // If no looping aloud, are the trying to do it anyways? + // + curr_frame = sys_header->current_frame; +#if (FALSE) + // This is commented out since we will let them loop even though they should + // not - it will be slower. + if ( (sys_header->flags & WSA_LINEAR_ONLY) && (frame_number < cur_frame) ) { + return FALSE; + } +#endif + + // Get absoulte distance from our current frame to the target frame + distance = ABS(curr_frame - frame_number); + + // Assume we are searching right + search_dir = 1; + + // Calculate the number of frames to search if we go right and wrap + + if (frame_number > curr_frame) { + search_frames = total_frames - frame_number + curr_frame; + + // Is going right faster than going backwards? + // Or are they trying to loop when the should not? + if ((search_frames < distance) && !(sys_header->flags & WSA_LINEAR_ONLY)) { + search_dir = -1; // No, so go left + } + else { + search_frames = distance; + } + } + else { + search_frames = total_frames - curr_frame + frame_number; + + // Is going right faster than going backwards? + // Or are they trying to loop when the should not? + if ((search_frames >= distance) || (sys_header->flags & WSA_LINEAR_ONLY)) { + search_dir = -1; // No, so go left + search_frames = distance; + } + } + + // Take care of the case when we are searching right (possibly right) + + if (search_dir > 0) { + for (loop = 0; loop < search_frames; loop++) { + + // Move the logical frame number ordinally right + curr_frame += search_dir; + + Apply_Delta(sys_header, curr_frame, frame_buffer, dest_width); + + // Adjust the current frame number, taking into consideration that we could + // have wrapped + + if (curr_frame == total_frames) { + curr_frame = 0; + } + } + } + else { + for (loop = 0; loop < search_frames; loop++) { + + // If we are going backwards and we are on frame 0, the delta to get + // to the last frame is the n + 1 delta (wrap delta) + + if (curr_frame == 0) { + curr_frame = total_frames; + } + + Apply_Delta(sys_header, curr_frame, frame_buffer, dest_width); + + curr_frame += search_dir; + } + } + + sys_header->current_frame = frame_number; + + // If we did this all in a hidden buffer, then copy it to the desired page or viewport. + if (sys_header->flags & WSA_TARGET_IN_BUFFER) { +#if TRUE + + Buffer_To_Page(x_pixel, y_pixel, sys_header->pixel_width, sys_header->pixel_height, frame_buffer, view); + +#else + int flags = ((unsigned short)flags_and_prio & 0xFF00u) >> 12u; + int pri = flags_and_prio & 0x00FF; + + Buffer_Bitblit_To_LogicPage(x_pixel, y_pixel, sys_header->pixel_width, + sys_header->pixel_height, 0, flags, frame_buffer, pri, + magic_cols, magic); +#endif + } + + + return TRUE; +} +#endif + + +/*************************************************************************** + * ANIMATE_FRAME_COUNT -- Return Number of frames in an animation. * + * * + * INPUT: void *handle to the animation. * + * * + * OUTPUT: int number of frames in animation. * + * * + * WARNINGS: * + * * + * HISTORY: * + * 12/05/1991 SB : Created. * + *=========================================================================*/ +int __cdecl Get_Animation_Frame_Count(void *handle) +{ + SysAnimHeaderType *sys_header; + + if (!handle) { + return FALSE; + } + sys_header = (SysAnimHeaderType *) handle; + return((short)sys_header->total_frames); +} + + +/*************************************************************************** + * GET_ANIM_X -- Gets the x from an animation * + * * + * * + * INPUT: void * to the animation that we are processing * + * * + * OUTPUT: int the x of the animation we are processing * + * * + * WARNINGS: * + * * + * HISTORY: * + * 07/03/1992 DRD : Created. * + *=========================================================================*/ +int __cdecl Get_Animation_X(void const *handle) +{ + SysAnimHeaderType const *sys_header; + + if (!handle) { + return FALSE; + } + sys_header = (SysAnimHeaderType *) handle; + return(sys_header->pixel_x); +} + +/*************************************************************************** + * GET_ANIM_Y -- Gets the y from an animation * + * * + * * + * INPUT: void * to the animation that we are processing * + * * + * OUTPUT: int the y of the animation we are processing * + * * + * WARNINGS: * + * * + * HISTORY: * + * 10/14/1992 PWG : Created. * + *=========================================================================*/ +int __cdecl Get_Animation_Y(void const *handle) +{ + SysAnimHeaderType const *sys_header; + + if (!handle) { + return FALSE; + } + sys_header = (SysAnimHeaderType *) handle; + return(sys_header->pixel_y); +} + +/*************************************************************************** + * GET_ANIM_WIDTH -- Gets the width from an animation * + * * + * * + * INPUT: void * to the animation that we are processing * + * * + * OUTPUT: int the width of the animation we are processing * + * * + * WARNINGS: * + * * + * HISTORY: * + * 10/14/1992 PWG : Created. * + *=========================================================================*/ +int __cdecl Get_Animation_Width(void const *handle) +{ + SysAnimHeaderType const *sys_header; + + if (!handle) { + return FALSE; + } + sys_header = (SysAnimHeaderType *) handle; + return(sys_header->pixel_width); +} + +/*************************************************************************** + * GET_ANIM_HEIGHT -- The height of the animation we are processing * + * * + * INPUT: void * to the animation that we are processing * + * * + * OUTPUT: int the height of the animation we are processing * + * * + * HISTORY: * + * 10/14/1992 PWG : Created. * + *=========================================================================*/ +int __cdecl Get_Animation_Height(void const *handle) +{ + SysAnimHeaderType const *sys_header; + + if (!handle) { + return FALSE; + } + sys_header = (SysAnimHeaderType *) handle; + return(sys_header->pixel_height); +} + + +/*************************************************************************** + * GET_ANIM_PALETTE -- Returns true if the anim had an attached palette * + * * + * INPUT: void * to the animation that we are processing * + * * + * OUTPUT: int True if the animation has a set palette. False if the * + * animation does not. * + * * + * HISTORY: * + * 10/14/1992 PWG : Created. * + *=========================================================================*/ +int __cdecl Get_Animation_Palette(void const *handle) +{ + SysAnimHeaderType const *sys_header; + + if (!handle) { + return FALSE; + } + sys_header = (SysAnimHeaderType *) handle; + return(sys_header->flags & WSA_PALETTE_PRESENT); +} + + +/*************************************************************************** + * GET_ANIMATION_SIZE -- Return the amount of memory the animation is using* + * * + * * + * INPUT: void * to the animation that we are processing * + * * + * OUTPUT: unsigned long number of byte used by animation. * + * * + * WARNINGS: * + * * + * HISTORY: * + * 05/23/1994 SKB : Created. * + *=========================================================================*/ +unsigned long __cdecl Get_Animation_Size(void const *handle) +{ + SysAnimHeaderType const *sys_header; + + if (!handle) { + return FALSE; + } + sys_header = (SysAnimHeaderType *) handle; + return(sys_header->anim_mem_size); +} + +/* :::::::::::::::::::::::::::: PRIVATE FUNCTIONS :::::::::::::::::::::::::::::: */ + + +/*************************************************************************** + * GET_RESIDENT_FRAME_OFFSET -- Gets frame offset of animate file in RAM * + * * + * INPUT: char *file_buffer in RAM of animation file. * + * int frame number that we need the offset of. * + * * + * OUTPUT: int offset of frame requested. * + * * + * WARNINGS: * + * * + * HISTORY: * + * 11/26/1991 SB : Created. * + *=========================================================================*/ +PRIVATE unsigned long Get_Resident_Frame_Offset( char *file_buffer, int frame ) +{ + unsigned long frame0_size; + unsigned long *lptr; + + // If there is a frame 0, the calculate its size. + lptr = (unsigned long *) file_buffer; + + if (*lptr) { + frame0_size = lptr[1] - *lptr; + } else { + frame0_size = 0; + } + + // Return the offset into RAM for the frame. + lptr += frame; + if (*lptr) + return (*lptr - (frame0_size + WSA_FILE_HEADER_SIZE)); + else + return (0L); +} + + +/*************************************************************************** + * GET_FILE_FRAME_OFFSET -- Get offset of a delta frame from animate file. * + * * + * INPUT: int file_handle of animation file. * + * int frame number that we need the offset of. * + * * + * OUTPUT: int offset of frame requested. * + * * + * WARNINGS: * + * * + * HISTORY: * + * 11/26/1991 SB : Created. * + *=========================================================================*/ +PRIVATE unsigned long Get_File_Frame_Offset( int file_handle, int frame, int palette_adjust) +{ + unsigned long offset; + + Seek_File(file_handle, (frame << 2) + WSA_FILE_HEADER_SIZE, SEEK_SET); + + if (Read_File(file_handle, (char *) &offset, sizeof(unsigned long)) != sizeof(unsigned long)) { + offset = 0L; + } + offset += palette_adjust; + return( offset ); +} + + +/*************************************************************************** + * APPLY_DELTA -- Copies frame into delta buffer, then applies to target * + * * + * INPUT: SysAnimHeaderType *sys_header - pointer to animation buffer.* + * int curr_frame - frame to put into target buffer. * + * * + * OUTPUT: BOOL - Return wether or not it worked. * + * * + * WARNINGS: * + * * + * HISTORY: * + * 11/26/1991 SB : Created. * + *=========================================================================*/ +PRIVATE BOOL Apply_Delta(SysAnimHeaderType *sys_header, int curr_frame, char *dest_ptr, int dest_w) +{ + char *data_ptr, *delta_back; + int file_handle, palette_adjust; + unsigned long frame_data_size, frame_offset; + + + palette_adjust = ((sys_header->flags & WSA_PALETTE_PRESENT) ? 768 : 0); + delta_back = sys_header->delta_buffer; + + if (sys_header->flags & WSA_RESIDENT) { + // Get offset of the given frame in the resident file + // Get the size of the frame <- (frame+1 offset) - (offset) + // Point at the delta data + // figure offset to load data into end of delta buffer + // copy it into buffer + + frame_offset = Get_Resident_Frame_Offset(sys_header->file_buffer, curr_frame); + frame_data_size = Get_Resident_Frame_Offset(sys_header->file_buffer, curr_frame + 1) - frame_offset; + + data_ptr = (char *)Add_Long_To_Pointer(sys_header->file_buffer, frame_offset); + delta_back = (char *)Add_Long_To_Pointer(delta_back, + sys_header->largest_frame_size - frame_data_size); + + Mem_Copy( data_ptr, delta_back, frame_data_size ); + + } else if (sys_header -> flags & WSA_FILE) { + + // Open up file because not file not in RAM. + // Get offset of the given frame in the file on disk + // Get the size of the frame <- (frame+1 offset) - (offset) + // Return if Get_.._offset() failed. -- need error handling???? + // Seek to delta data. + // figure offset to load data into end of delta buffer + // Read it into buffer -- Return if correct amount not read.-- errors?? + + file_handle = sys_header->file_handle; + Seek_File(file_handle, 0L, SEEK_SET); + + frame_offset = Get_File_Frame_Offset(file_handle, curr_frame, palette_adjust); + frame_data_size = Get_File_Frame_Offset(file_handle, curr_frame + 1, palette_adjust) - frame_offset; + + if (!frame_offset || !frame_data_size) { + return(FALSE); + } + + Seek_File(file_handle, frame_offset, SEEK_SET); + delta_back = (char *)Add_Long_To_Pointer(delta_back, sys_header->largest_frame_size - frame_data_size); + + if (Read_File(file_handle, delta_back, frame_data_size) != frame_data_size) { + return(FALSE); + } + } + + // Uncompress data at end of delta buffer to the beginning of delta buffer. + // Find start of target buffer. + // Apply the XOR delta. + + LCW_Uncompress(delta_back, sys_header->delta_buffer, sys_header->largest_frame_size); + + if (sys_header->flags & WSA_TARGET_IN_BUFFER) { + Apply_XOR_Delta(dest_ptr, sys_header->delta_buffer); + } + else { + Apply_XOR_Delta_To_Page_Or_Viewport(dest_ptr, sys_header->delta_buffer, + sys_header->pixel_width, dest_w, DO_XOR); + } + + return(TRUE); +} + diff --git a/REDALERT/WINSTUB.CPP b/REDALERT/WINSTUB.CPP index e3e2834..619e703 100644 --- a/REDALERT/WINSTUB.CPP +++ b/REDALERT/WINSTUB.CPP @@ -711,6 +711,48 @@ void __cdecl SetPalette(unsigned char *palette, long, unsigned long) } +void WWSDL_ProcessEvents(KeyNumType& key, int& flags) { + extern int mousex, mousey; + SDL_GetMouseState(&mousex, &mousey); + + Keyboard->MouseQX = mousex; + Keyboard->MouseQY = mousey; + + // if (flags == LEFTRELEASE || flags == RIGHTRELEASE) + // flags = 0; + + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) + { + case SDL_MOUSEBUTTONDOWN: + if (event.button.button == SDL_BUTTON_LEFT) { + flags = GadgetClass::LEFTPRESS; + key = KN_LMOUSE; + } + else if (event.button.button == SDL_BUTTON_RIGHT) { + flags = GadgetClass::RIGHTPRESS; + key = KN_LMOUSE; + } + break; + + case SDL_MOUSEBUTTONUP: + if (event.button.button == SDL_BUTTON_LEFT) { + flags = GadgetClass::LEFTRELEASE; + } + else if (event.button.button == SDL_BUTTON_RIGHT) { + flags = GadgetClass::RIGHTRELEASE; + } + break; + case SDL_KEYDOWN: + Keyboard->Put_Element(event.key.keysym.sym); + break; + } + } +} + + + #ifndef NDEBUG /*********************************************************************************************** * Assert_Failure -- display the line and source file where a failed assert occurred *