// // Basic video functions // //! \file tonc_oam.h //! \author J Vijn //! \date 20060604 - 20060604 // // === NOTES === // * Basic video-IO, color, background and object functionality #ifndef TONC_OAM #define TONC_OAM #include "tonc_memmap.h" #include "tonc_memdef.h" #include "tonc_core.h" #ifdef CODE_COMPILED_AS_PART_OF_TEST #include "tonc_math_stub.h" #else #include "tonc_math.h" #endif // -------------------------------------------------------------------- // OBJECTS // -------------------------------------------------------------------- //! \addtogroup grpVideoObj /*! \{ */ #define OAM_CLEAR() memset32(oam_mem, 0, OAM_SIZE/4) // --- Prototypes ----------------------------------------------------- // --- Full OAM --- void oam_init(OBJ_ATTR *obj, uint count); INLINE void oam_copy(OBJ_ATTR *dst, const OBJ_ATTR *src, uint count); // --- Obj attr only --- INLINE OBJ_ATTR *obj_set_attr(OBJ_ATTR *obj, u16 a0, u16 a1, u16 a2); INLINE void obj_set_pos(OBJ_ATTR *obj, int x, int y); INLINE void obj_hide(OBJ_ATTR *oatr); INLINE void obj_unhide(OBJ_ATTR *obj, u16 mode); INLINE const u8 *obj_get_size(const OBJ_ATTR *obj); INLINE int obj_get_width(const OBJ_ATTR *obj); INLINE int obj_get_height(const OBJ_ATTR *obj); void obj_copy(OBJ_ATTR *dst, const OBJ_ATTR *src, uint count); void obj_hide_multi(OBJ_ATTR *obj, u32 count); void obj_unhide_multi(OBJ_ATTR *obj, u16 mode, uint count); // --- Obj affine only --- void obj_aff_copy(OBJ_AFFINE *dst, const OBJ_AFFINE *src, uint count); INLINE void obj_aff_set(OBJ_AFFINE *oaff, FIXED pa, FIXED pb, FIXED pc, FIXED pd); INLINE void obj_aff_identity(OBJ_AFFINE *oaff); INLINE void obj_aff_scale(OBJ_AFFINE *oaff, FIXED sx, FIXED sy); INLINE void obj_aff_shearx(OBJ_AFFINE *oaff, FIXED hx); INLINE void obj_aff_sheary(OBJ_AFFINE *oaff, FIXED hy); void obj_aff_rotate(OBJ_AFFINE *oaff, u16 alpha); void obj_aff_rotscale(OBJ_AFFINE *oaff, FIXED sx, FIXED sy, u16 alpha); void obj_aff_premul(OBJ_AFFINE *dst, const OBJ_AFFINE *src); void obj_aff_postmul(OBJ_AFFINE *dst, const OBJ_AFFINE *src); void obj_aff_rotscale2(OBJ_AFFINE *oaff, const AFF_SRC *as); void obj_rotscale_ex(OBJ_ATTR *obj, OBJ_AFFINE *oaff, const AFF_SRC_EX *asx); // inverse (object -> screen) functions, could be useful // inverses (prototypes) INLINE void obj_aff_scale_inv(OBJ_AFFINE *oa, FIXED wx, FIXED wy); INLINE void obj_aff_rotate_inv(OBJ_AFFINE *oa, u16 theta); INLINE void obj_aff_shearx_inv(OBJ_AFFINE *oa, FIXED hx); INLINE void obj_aff_sheary_inv(OBJ_AFFINE *oa, FIXED hy); /*! \} */ // -------------------------------------------------------------------- // INLINES // -------------------------------------------------------------------- /*! \addtogroup grpVideoObj */ /*! \{ */ //! Set the attributes of an object. INLINE OBJ_ATTR *obj_set_attr(OBJ_ATTR *obj, u16 a0, u16 a1, u16 a2) { obj->attr0= a0; obj->attr1= a1; obj->attr2= a2; return obj; } //! Set the position of \a obj INLINE void obj_set_pos(OBJ_ATTR *obj, int x, int y) { BFN_SET(obj->attr0, y, ATTR0_Y); BFN_SET(obj->attr1, x, ATTR1_X); } //! Copies \a count OAM entries from \a src to \a dst. INLINE void oam_copy(OBJ_ATTR *dst, const OBJ_ATTR *src, uint count) { memcpy32(dst, src, count*2); } //! Hide an object. INLINE void obj_hide(OBJ_ATTR *obj) { BFN_SET2(obj->attr0, ATTR0_HIDE, ATTR0_MODE); } //! Unhide an object. /*! \param obj Object to unhide. * \param mode Object mode to unhide to. Necessary because this affects * the affine-ness of the object. */ INLINE void obj_unhide(OBJ_ATTR *obj, u16 mode) { BFN_SET2(obj->attr0, mode, ATTR0_MODE); } //! Get object's sizes as a byte array INLINE const u8 *obj_get_size(const OBJ_ATTR *obj) { return oam_sizes[obj->attr0>>14][obj->attr1>>14]; } //! Get object's width INLINE int obj_get_width(const OBJ_ATTR *obj) { return obj_get_size(obj)[0]; } //! Gets object's height INLINE int obj_get_height(const OBJ_ATTR *obj) { return obj_get_size(obj)[1]; } // --- Affine only --- //! Set the elements of an \a object affine matrix. INLINE void obj_aff_set(OBJ_AFFINE *oaff, FIXED pa, FIXED pb, FIXED pc, FIXED pd) { oaff->pa= pa; oaff->pb= pb; oaff->pc= pc; oaff->pd= pd; } //! Set an object affine matrix to the identity matrix INLINE void obj_aff_identity(OBJ_AFFINE *oaff) { oaff->pa= 0x0100l; oaff->pb= 0; oaff->pc= 0; oaff->pd= 0x0100; } //! Set an object affine matrix for scaling. INLINE void obj_aff_scale(OBJ_AFFINE *oaff, FIXED sx, FIXED sy) { oaff->pa= sx; oaff->pb= 0; oaff->pb= 0; oaff->pd= sy; } INLINE void obj_aff_shearx(OBJ_AFFINE *oaff, FIXED hx) { oaff->pa= 0x0100; oaff->pb= hx; oaff->pc= 0; oaff->pd= 0x0100; } INLINE void obj_aff_sheary(OBJ_AFFINE *oaff, FIXED hy) { oaff->pa= 0x0100; oaff->pb= 0; oaff->pc= hy; oaff->pd= 0x0100; } // --- Inverse operations --- INLINE void obj_aff_scale_inv(OBJ_AFFINE *oaff, FIXED wx, FIXED wy) { obj_aff_scale(oaff, ((1<<24)/wx)>>8, ((1<<24)/wy)>>8); } INLINE void obj_aff_rotate_inv(OBJ_AFFINE *oaff, u16 theta) { obj_aff_rotate(oaff, -theta); } INLINE void obj_aff_shearx_inv(OBJ_AFFINE *oaff, FIXED hx) { obj_aff_shearx(oaff, -hx); } INLINE void obj_aff_sheary_inv(OBJ_AFFINE *oaff, FIXED hy) { obj_aff_sheary(oaff, -hy); } /*! \} */ void obj_aff_copy(OBJ_AFFINE *dst, const OBJ_AFFINE *src, u32 count) { int ii; for(ii=0; iipa= src->pa; dst->pb= src->pb; dst->pc= src->pc; dst->pd= src->pd; src++; dst++; } } //! Set obj matrix to counter-clockwise rotation. /*! \param oaff Object affine struct to set. \param alpha CCW angle. full-circle is 10000h. */ void obj_aff_rotate(OBJ_AFFINE *oaff, u16 alpha) { int ss= lu_sin(alpha)>>4, cc= lu_cos(alpha)>>4; oaff->pa= cc; oaff->pb= -ss; oaff->pc= ss; oaff->pd= cc; } //! Post-multiply \a dst by \a src: D= D*S void obj_aff_postmul(OBJ_AFFINE *dst, const OBJ_AFFINE *src) { FIXED tmp_a, tmp_b, tmp_c, tmp_d; tmp_a= dst->pa; tmp_b= dst->pb; tmp_c= dst->pc; tmp_d= dst->pd; dst->pa= (tmp_a*src->pa + tmp_b*src->pc)>>8; dst->pb= (tmp_a*src->pb + tmp_b*src->pd)>>8; dst->pc= (tmp_c*src->pa + tmp_d*src->pc)>>8; dst->pd= (tmp_c*src->pb + tmp_d*src->pd)>>8; } #endif // TONC_OAM