////////////////////////////////////////////////////////////////////////////////////////// // // // SCRIPT NAME : UIUtil // // AUTHOR : Taylor Wright // // DESCRIPTION : Util to help manage Script UI // // // ////////////////////////////////////////////////////////////////////////////////////////// USING "commands_graphics.sch" USING "commands_pad.sch" USING "hud_drawing.sch" // Used for screen position, size and scaling methods CONST_INT DEFAULT_SCREEN_WIDTH 1280 CONST_INT DEFAULT_SCREEN_HEIGHT 720 // Used for gamepad input methods CONST_INT STICK_DEAD_ZONE 28 CONST_INT DELAY_BEFORE_REACTIVATED 250 //////////////////////////////////// // PIXEL & FLOAT CONVERSION TOOLS // //////////////////////////////////// /// PURPOSE: /// Convert an x pixel position to a screen float position /// PARAMS: /// x - X position /// iScreenWidth - Screen width, when passed in prevents a call to GET_SCREEN_RESOLUTION /// RETURNS: /// x position as a screen float FUNC FLOAT PIXEL_X_TO_FLOAT(FLOAT x, INT iScreenWidth = 0) IF iScreenWidth = 0 INT iScreenHeight GET_SCREEN_RESOLUTION(iScreenWidth, iScreenHeight) ENDIF RETURN x / iScreenWidth ENDFUNC /// PURPOSE: /// Convert an y pixel position to a screen float position /// PARAMS: /// y - Y position /// iScreenHeight - Screen height, when passed in prevents a call to GET_SCREEN_RESOLUTION /// RETURNS: /// y position as a screen float FUNC FLOAT PIXEL_Y_TO_FLOAT(FLOAT y, INT iScreenHeight = 0) IF iScreenHeight = 0 INT iScreenWidth GET_SCREEN_RESOLUTION(iScreenWidth, iScreenHeight) ENDIF RETURN y / iScreenHeight ENDFUNC /// PURPOSE: /// Convert a x screen float position to a x pixel position /// PARAMS: /// x - X position /// iScreenWidth - Screen width, when passed in prevents a call to GET_SCREEN_RESOLUTION /// rounded - Rounds float value to nearest pixel (default = true) /// RETURNS: /// x positon as a pixel FUNC FLOAT FLOAT_X_TO_PIXEL(FLOAT x, INT iScreenWidth = 0, BOOL rounded = TRUE) IF iScreenWidth = 0 INT iScreenHeight GET_SCREEN_RESOLUTION(iScreenWidth, iScreenHeight) ENDIF FLOAT pixel = x * iScreenWidth IF rounded RETURN TO_FLOAT(ROUND(pixel)) ENDIF RETURN pixel ENDFUNC /// PURPOSE: /// Convert a y screen float position to a y pixel position /// PARAMS: /// y - Y position /// iScreenHeight - Screen height, when passed in prevents a call to GET_SCREEN_RESOLUTION /// rounded - Rounds float value to nearest pixel (default = true) /// RETURNS: /// y positon as a pixel FUNC FLOAT FLOAT_Y_TO_PIXEL(FLOAT y, INT iScreenHeight = 0, BOOL rounded = TRUE) IF iScreenHeight = 0 INT iScreenWidth GET_SCREEN_RESOLUTION(iScreenWidth, iScreenHeight) ENDIF FLOAT pixel = y * iScreenHeight IF rounded RETURN TO_FLOAT(ROUND(pixel)) ENDIF RETURN pixel ENDFUNC ///////////////////////////////// // RECT: POSITION, SIZE & COLOR// ///////////////////////////////// /// PURPOSE: /// Position Rect with pixel values (based on 720p source) /// PARAMS: /// target - Rect to manipulate /// x - X positon as pixel of 1280 /// y - Y positon as pixel of 720 /// fromTopLeft - Register positon from Top Left or Center PROC PIXEL_POSITION_RECT(RECT &target, FLOAT x, FLOAT y, BOOL fromTopLeft = FALSE) target.x = PIXEL_X_TO_FLOAT(x, DEFAULT_SCREEN_WIDTH) target.y = PIXEL_Y_TO_FLOAT(y, DEFAULT_SCREEN_HEIGHT) IF fromTopLeft target.x += target.w/2 target.y += target.h/2 ENDIF ENDPROC /// PURPOSE: /// Size Rect with pixel values (based on 720p source) /// PARAMS: /// target - Rect to manipulate /// w - Width as pixel of 1280 /// h - Height as pixel of 720 PROC PIXEL_SIZE_RECT(RECT &target, FLOAT w, FLOAT h) target.w = PIXEL_X_TO_FLOAT(w, DEFAULT_SCREEN_WIDTH) target.h = PIXEL_Y_TO_FLOAT(h, DEFAULT_SCREEN_HEIGHT) ENDPROC /// PURPOSE: /// Position and size a Rect with pixel values (based on 720p source) /// PARAMS: /// target - Rect to manipulate /// x - X positon as pixel of 1280 /// y - Y positon as pixel of 720 /// w - Width as pixel of 1280 /// h - Height as pixel of 720 /// fromTopLeft - Register positon from Top Left or Center PROC PIXEL_POSITION_AND_SIZE_RECT(RECT &target, FLOAT x, FLOAT y, FLOAT w, FLOAT h, BOOL fromTopLeft = FALSE) PIXEL_SIZE_RECT(target, w, h) PIXEL_POSITION_RECT(target, x, y, fromTopLeft) ENDPROC /// PURPOSE: /// Set Color of RECT /// PARAMS: /// target - Rect to manipulate /// r - red /// g - green /// b - blue /// a - alpha PROC RECT_COLOR(RECT &target, INT r = 255, INT g = 255, INT b = 255, INT a = 255) target.r = r target.g = g target.b = b target.a = a ENDPROC /////////////////////////////////////////// // SPRITE: POSITION, SIZE, SCALE & COLOR // /////////////////////////////////////////// /// PURPOSE: /// Position sprite with pixel values (based on 720p source) /// PARAMS: /// target - Sprite to manipulate /// x - X positon as pixel of 1280 /// y - Y positon as pixel of 720 /// fromTopLeft - Register positon from Top Left or Center PROC PIXEL_POSITION_SPRITE(SPRITE_PLACEMENT &target, FLOAT x, FLOAT y, BOOL fromTopLeft = FALSE) target.x = PIXEL_X_TO_FLOAT(x, DEFAULT_SCREEN_WIDTH) target.y = PIXEL_Y_TO_FLOAT(y, DEFAULT_SCREEN_HEIGHT) IF fromTopLeft target.x += target.w/2 target.y += target.h/2 ENDIF ENDPROC /// PURPOSE: /// Size sprite with pixel values (based on 72p source) /// PARAMS: /// target - Sprite to manipulate /// w - Width as pixel of 1280 /// h - Height as pixel of 720 PROC PIXEL_SIZE_SPRITE(SPRITE_PLACEMENT &target, FLOAT w, FLOAT h) target.w = PIXEL_X_TO_FLOAT(w, DEFAULT_SCREEN_WIDTH) target.h = PIXEL_Y_TO_FLOAT(h, DEFAULT_SCREEN_HEIGHT) ENDPROC /// PURPOSE: /// Position and size a sprite with pixel values (based on 720p source) /// PARAMS: /// target - Sprite to manipulate /// x - X positon as pixel of 1280 /// y - Y positon as pixel of 720 /// w - Width as pixel of 1280 /// h - Height as pixel of 720 /// fromTopLeft - Register positon from Top Left or Center PROC PIXEL_POSITION_AND_SIZE_SPRITE(SPRITE_PLACEMENT &target, FLOAT x, FLOAT y, FLOAT w, FLOAT h, BOOL fromTopLeft = FALSE) PIXEL_SIZE_SPRITE(target, w, h) PIXEL_POSITION_SPRITE(target, x, y, fromTopLeft) ENDPROC /// PURPOSE: /// Size sprite with pixel values (based on 72p source) /// PARAMS: /// target - Sprite to manipulate /// w - Width as pixel of 1280 /// h - Height as pixel of 720 PROC PIXEL_SCALE_SPRITE(STRING pTextureDictionaryName, STRING pSpriteName, SPRITE_PLACEMENT &target, FLOAT w = 1.0, FLOAT h = 1.0) VECTOR vTexture = GET_TEXTURE_RESOLUTION(pTextureDictionaryName, pSpriteName) target.w = PIXEL_X_TO_FLOAT(vTexture.x, DEFAULT_SCREEN_WIDTH) * w target.h = PIXEL_Y_TO_FLOAT(vTexture.y, DEFAULT_SCREEN_HEIGHT) * h ENDPROC /// PURPOSE: /// Position a sprite with pixel values and size with float scale values /// PARAMS: /// pTextureDictionaryName - Texture Dictionary Name /// pSpriteName - Sprite Name /// target - Sprite to manipulate /// x - X positon as pixel /// y - Y positon as pixel /// w - Width as scale of texture (Default 1.0 = 100%) /// h - Height as scale of texture (Default 1.0 = 100%) /// fromTopLeft - Register positon from Top Left or Center PROC PIXEL_POSITION_AND_SCALE_SPRITE(STRING pTextureDictionaryName, STRING pSpriteName, SPRITE_PLACEMENT &target, FLOAT x, FLOAT y, FLOAT w = 1.0, FLOAT h = 1.0, BOOL fromTopLeft = FALSE) PIXEL_SCALE_SPRITE(pTextureDictionaryName, pSpriteName, target, w, h) PIXEL_POSITION_SPRITE(target, x, y, fromTopLeft) ENDPROC /// PURPOSE: /// Simple expansion of DRAW_2D_SPRITE to draw texture to scale (initial scale is determiend in relation to 1280x720 but will scale propperly to other resolutions) /// PARAMS: /// pTextureDictionaryName - Texture Dictionary Name /// pSpriteName - Sprite Name /// target - Sprite to manipulate /// DoScreenScaling - ??? /// option - Choice between the following options: /// HIGHLIGHT_OPTION_NORMAL /// HIGHLIGHT_OPTION_NOTSELECTED_ACTIVE /// HIGHLIGHT_OPTION_EMPTY_SELECTED /// HIGHLIGHT_OPTION_EMPTY_NOTSELECTED /// HIGHLIGHT_OPTION_NUMBER_SELECTED /// HIGHLIGHT_OPTION_NUMBER_NOTSELECTED /// HIGHLIGHT_OPTION_SELECTED_GREY /// bDrawBeforeFade - ??? PROC DRAW_2D_SPRITE_UNSCALED(STRING pTextureDictionaryName, STRING pSpriteName, SPRITE_PLACEMENT &target, BOOL DoScreenScaling = TRUE, HIGHLIGHT_OPTION option = HIGHLIGHT_OPTION_NORMAL, BOOL bDrawBeforeFade = FALSE) PIXEL_SCALE_SPRITE(pTextureDictionaryName, pSpriteName, target) DRAW_2D_SPRITE(pTextureDictionaryName, pSpriteName, target, DoScreenScaling, option, bDrawBeforeFade) ENDPROC /// PURPOSE: /// Set Color of SPRITE /// PARAMS: /// target - Rect to manipulate /// r - red /// g - green /// b - blue /// a - alpha PROC SPRITE_COLOR(SPRITE_PLACEMENT &target, INT r = 255, INT g = 255, INT b = 255, INT a = 255) target.r = r target.g = g target.b = b target.a = a ENDPROC /// PURPOSE: /// Set the rotation of a SPRITE_PLACEMENT /// PARAMS: /// target - the SPRITE_PLACEMENT to manipulate. /// fRotation - the new rotation to give the sprite. PROC SPRITE_ROTATION(SPRITE_PLACEMENT &target, FLOAT fRotation = 0.0) target.fRotation = fRotation ENDPROC //////////////////// // TEXT: POSITION // //////////////////// /// PURPOSE: /// Position Text with pixel values (based on 720p source) /// PARAMS: /// target - Text to manipulate /// x - X positon as pixel of 1280 /// y - Y positon as pixel of 720 /// fromTopLeft - Register positon from Top Left or Center PROC PIXEL_POSITION_TEXT(TEXT_PLACEMENT &target, FLOAT x, FLOAT y, BOOL fromTopLeft = TRUE) target.x = PIXEL_X_TO_FLOAT(x, DEFAULT_SCREEN_WIDTH) target.y = PIXEL_Y_TO_FLOAT(y, DEFAULT_SCREEN_HEIGHT) IF NOT fromTopLeft // TODO: enable fromTopLeft false -TAYLOR PRINTLN("Unable to position from middle center") // target.x -= target.w/2 // target.y -= target.h/2 ENDIF ENDPROC ////////////////////// // CONTROLLER INPUT // ////////////////////// /// PURPOSE: Stores data used for Analog as DPad support STRUCT UI_INPUT_DATA BOOL bAcceptLeftStickInput = TRUE INT iLastUpdateLeftStick = 0 ENDSTRUCT ENUM eLeftAnalogAsDpad LEFT_ANALOG_AS_DPAD_UP, LEFT_ANALOG_AS_DPAD_DOWN, LEFT_ANALOG_AS_DPAD_LEFT, LEFT_ANALOG_AS_DPAD_RIGHT ENDENUM /// PURPOSE: /// Allows you to evaluate the left analog stick like it's a DPAD /// PARAMS: /// PadNumber - Game Pad number /// ButtonNumber - Pad Button number (only tests for: LEFT_ANALOG_AS_DPAD_UP, LEFT_ANALOG_AS_DPAD_DOWN, LEFT_ANALOG_AS_DPAD_LEFT, LEFT_ANALOG_AS_DPAD_RIGHT) /// RETURNS: /// True = Current analog equivelent active, False = Current analog equivelent not active FUNC BOOL IS_LEFT_ANALOG_AS_DPAD(eLeftAnalogAsDpad ButtonNumber, UI_INPUT_DATA &inputData) BOOL returnValue = FALSE INT iLSX, iLSY iLSX = GET_CONTROL_VALUE(FRONTEND_CONTROL, INPUT_FRONTEND_AXIS_X) iLSY = GET_CONTROL_VALUE(FRONTEND_CONTROL, INPUT_FRONTEND_AXIS_Y) // If stick goes to deadzone method fails but enables stick for next time called IF ABSI(iLSX) < STICK_DEAD_ZONE AND ABSI(iLSY) < STICK_DEAD_ZONE inputData.bAcceptLeftStickInput = TRUE inputData.iLastUpdateLeftStick = 0 RETURN FALSE ENDIF // If delay time hasn't elapsed method fails IF GET_GAME_TIMER() < inputData.iLastUpdateLeftStick + DELAY_BEFORE_REACTIVATED inputData.bAcceptLeftStickInput = FALSE RETURN FALSE ELSE inputData.bAcceptLeftStickInput = TRUE ENDIF // Failsafe, This should never fire given above conditions IF NOT inputData.bAcceptLeftStickInput RETURN FALSE ENDIF SWITCH ButtonNumber CASE LEFT_ANALOG_AS_DPAD_UP returnValue = iLSY < (128 - STICK_DEAD_ZONE) BREAK CASE LEFT_ANALOG_AS_DPAD_DOWN returnValue = iLSY > (128 + STICK_DEAD_ZONE) BREAK CASE LEFT_ANALOG_AS_DPAD_LEFT returnValue = iLSX < (128 - STICK_DEAD_ZONE) BREAK CASE LEFT_ANALOG_AS_DPAD_RIGHT returnValue = iLSX > (128 + STICK_DEAD_ZONE) BREAK ENDSWITCH IF returnValue inputData.iLastUpdateLeftStick = GET_GAME_TIMER() inputData.bAcceptLeftStickInput = FALSE ENDIF RETURN returnValue ENDFUNC FUNC FLOAT SET_RECT_DYNAMIC_TO_STRING(RECT& rectToSet, STRING sText, TEXT_PLACEMENT& textPlacement, TEXT_STYLE & tStyle, FLOAT fLineHeight, FLOAT fLineSpace, INT iLinesDown, FLOAT fStartingPixelTL) // Have to set the style first! SET_TEXT_STYLE(tStyle) // Figure out how any rows the text is going to take, given that it's wrapped to this rect, and using the given font. BEGIN_TEXT_COMMAND_GET_NUMBER_OF_LINES_FOR_STRING(sText) INT iLines = END_TEXT_COMMAND_GET_NUMBER_OF_LINES_FOR_STRING(textPlacement.x, textPlacement.y) PRINTLN("Num lines: ", iLines) // Set the height. INT iScreenHeight = 720 IF NOT GET_IS_WIDESCREEN() iScreenHeight = 480 ENDIF rectToSet.h = PIXEL_Y_TO_FLOAT((TO_FLOAT(iLines) * fLineHeight) - fLineSpace, iScreenHeight) // Need to place the rect at the top of the text. rectToSet.y = PIXEL_Y_TO_FLOAT(fStartingPixelTL + ((TO_FLOAT(iLinesDown) + TO_FLOAT(iLines) * 0.5) * fLineHeight) - fLineSpace * 0.5, iScreenHeight) RETURN 0.0 ENDFUNC PROC FIXUP_SPRITE_FOR_NON_WIDESCREEN(SPRITE_PLACEMENT & sprPlacement, BOOL bWidthOnly = FALSE) IF NOT bWidthOnly sprPlacement.x = ((sprPlacement.x - 0.5) * 1.33) + 0.5 ENDIF sprPlacement.w = (sprPlacement.w * 1.33) ENDPROC PROC FIXUP_TEXT_FOR_NON_WIDESCREEN(TEXT_PLACEMENT & txtPlacement, TEXT_STYLE & txtStyle) txtPlacement.x = ((txtPlacement.x - 0.5) * 1.33) + 0.5 txtStyle.WrapStartX = ((txtStyle.WrapStartX - 0.5) * 1.33) + 0.5 txtStyle.WrapEndX = ((txtStyle.WrapEndX - 0.5) * 1.33) + 0.5 ENDPROC PROC FIXUP_RECT_FOR_NON_WIDESCREEN(RECT & rectPlacement) rectPlacement.x = ((rectPlacement.x - 0.5) * 1.33) + 0.5 rectPlacement.w = (rectPlacement.w * 1.33) ENDPROC