VM_SIN_SCALE
is a GBVM instruction used to calculate the sine of a given angle, scaled by a specified factor, and store the result in a variable.
Purpose:
Trigonometric functions like sine are essential for many game mechanics, especially those involving circular motion, waves, or angles. VM_SIN_SCALE
is particularly useful for:
This instruction takes an angle and a scale factor. The angle is typically represented in a Game Boy-specific format (0-255 for a full circle, where 64 units represent 90 degrees). The SCALE
parameter affects the precision of the calculation.
Syntax:
VM_SIN_SCALE IDX, IDX_ANGLE, SCALE
IDX
: The target variable (a GBVM variable) that will receive the calculated sine value. This variable also acts as the sine scale, meaning the result of the sine function will be multiplied by the value initially in IDX
.IDX_ANGLE
: The variable that contains the angle to be passed into the sine function. This angle is typically an 8-bit unsigned integer, where:
0
(or 255
) represents 0 degrees (pointing up).64
represents 90 degrees (pointing right).128
represents 180 degrees (pointing down).192
represents 270 degrees (pointing left).SCALE
: The accuracy of the calculation, an integer between 0 and 7. A higher value generally means more precision but might take slightly longer to compute.Usage Example: Creating a Circular Orbiting Object
Imagine a small object (e.g., a fairy, a satellite) orbiting around a central point. You can use VM_SIN_SCALE
(for Y-coordinate) and VM_COS_SCALE
(for X-coordinate) to calculate its position based on a continuously increasing angle.
; In your orbiting object's update script:
; Assume ORBITING_ACTOR_ID is the actor ID for the orbiting object
ORBITING_ACTOR_ID:
.R_INT8 70 ; Example Actor ID
; Variables for angle, radius, and center position
VAR_ORBIT_ANGLE:
.R_INT8 0 ; Current angle for orbiting (0-255)
VAR_ORBIT_RADIUS:
.R_INT8 32 ; Radius of the orbit (e.g., 32 pixels)
VAR_CENTER_X:
.R_INT16 80 ; X-coordinate of the center of orbit
VAR_CENTER_Y:
.R_INT16 72 ; Y-coordinate of the center of orbit
VAR_OFFSET_X:
.R_INT16 0 ; Calculated X offset
VAR_OFFSET_Y:
.R_INT16 0 ; Calculated Y offset
VAR_ORBIT_X:
.R_INT16 0 ; Orbiting object's current X position
VAR_ORBIT_Y:
.R_INT16 0 ; Orbiting object's current Y position
ORBIT_LOOP:
; Increment the angle for continuous motion
VM_RPN
.R_REF_MEM .R_INT8, VAR_ORBIT_ANGLE
.R_INT8 1 ; Increment by 1 each frame (adjust for speed)
.R_OPERATOR +
.R_INT8
VM_STOP
VM_SET_INT8 VAR_ORBIT_ANGLE, 0
; Calculate X offset using cosine (scaled by radius)
VM_SET_INT8 VAR_OFFSET_X, VAR_ORBIT_RADIUS ; Set IDX to radius
VM_COS_SCALE VAR_OFFSET_X, VAR_ORBIT_ANGLE, 4 ; Calculate cosine, scale by radius, accuracy 4
; Calculate Y offset using sine (scaled by radius)
VM_SET_INT8 VAR_OFFSET_Y, VAR_ORBIT_RADIUS ; Set IDX to radius
VM_SIN_SCALE VAR_OFFSET_Y, VAR_ORBIT_ANGLE, 4 ; Calculate sine, scale by radius, accuracy 4
; Add offsets to center position to get new object position
VM_RPN
.R_REF_MEM .R_INT16, VAR_CENTER_X
.R_REF_MEM .R_INT16, VAR_OFFSET_X
.R_OPERATOR +
.R_INT16
VM_STOP
VM_SET_INT16 VAR_ORBIT_X, 0
VM_RPN
.R_REF_MEM .R_INT16, VAR_CENTER_Y
.R_REF_MEM .R_INT16, VAR_OFFSET_Y
.R_OPERATOR +
.R_INT16
VM_STOP
VM_SET_INT16 VAR_ORBIT_Y, 0
; Set the orbiting object's new position
VM_ACTOR_SET_POS ORBITING_ACTOR_ID, VAR_ORBIT_X, VAR_ORBIT_Y
VM_IDLE 1 ; Yield control for one frame
VM_JUMP ORBIT_LOOP
In this example, VM_SIN_SCALE
(for Y) and VM_COS_SCALE
(for X) are used together to calculate the X
and Y
offsets from a central point. As VAR_ORBIT_ANGLE
continuously increments, the sine and cosine values change, causing the ORBITING_ACTOR_ID
to move in a smooth circular path around (VAR_CENTER_X, VAR_CENTER_Y)
. The VAR_ORBIT_RADIUS
determines the size of the circle.
Analogy to other programming languages/game engines:
This is analogous to using Math.sin()
or sinf()
in C/C++ or math.sin()
in Python to calculate a value based on an angle, and then multiplying it by an amplitude (radius) to get a desired range. When combined with cosine, it’s the fundamental mathematical approach for simulating circular or elliptical motion in games.