SGL User's ManualSupplementary Manual
SGL REFERENCE / SGL Supplementary Manual

■ About event registration and execution

When slInitEvent () is executed, the execution list is cleared, so you must register the event you want to execute in the list.
Use slSetEvent () or slSetEventNext () to register the event.

    void * eventtbl [] = {
        init_camera,
        init_player1,
        init_player2,
        init_enemyctrl
    };;

    void InitGame () {
        void ** evrdptr;
        EVENT * evptr;
        int cnt;

        slInitEvent (); / * Initialize event management variables * /
        evrptr = eventtbl;
        for (cnt = sizeof (eventtbl) / sizeof (void *); cnt-> 0;) {
            evptr = slSetEvent (* evrptr ++);
        }
        slSetSprTVMode ( TV_320x224 );
    }

    void Game () {
        slExecuteEvent (); / * Execute event * /
        slSynch (); / * Polygon data output and video display synchronization * /
    }

The event is executed each time you call the slExecuteEvent () function.
Each event is basically executed in the order in which it was registered.
The event registered first is defined in the EventTop variable of the system, and starting from this, the processing function of each event is called while sequentially defining the event pointers in the EventNow variable. The processing function is defined in the following format.

  void function ( EVENT * evptr) {
        ... / * Event processing * /
  }

  When writing in assembly language, _function:
        ...; Event processing; Event pointer is set in r4 register rts
        nop

When one event is finished, put the next pointer in the structure of that event into the EventNow variable and transfer the execution to the processing function as well. These are repeated until the next pointer is null.

  EventTop : ---- +
                 |
                 | + ------------------ +
                 +-> | * work = NULL |
                     | * before = NULL |
                +-| * next |
                | | * exit () |
                | | user [] |
                | + ------------------ +
                |
                | + ------------------ + + ------------------ +
                +-> | * Work | ---> | * next |-+
                     | * before | | | |
                +-| * next | | | |
                | | * exit () | + ------------------ + |
                | | user [] | + ------------------------- +
                | + ------------------ + |
                | | + ------------------ +
                | + ------------------ + +-> | * next = NULL | 
  EventLast : --- +-> | * work | | |
                     | * before | | |
                     | * next = NULL | + ------------------ +
                     | * exit () |
                     | user [] |
                     + ------------------ +

The EventLast variable defines a pointer to the last event to be executed and is used when adding the event.
To use RAM for a user, define a structure for the user and cast user [] in the event RAM to that structure.

example)
    typedef struct rob {
        FIXED posX, posY, posZ;
        ANGLE angX, angY, angZ;
        PDATA * pat;
    } ROBOT; / * This structure should not exceed 112 bytes * /

    void rob_control ( EVENT * evptr) {
        ROBOT * rbptr;

        rbptr = (ROBOT *) evptr-> user;
        rbptr-> posX = to_fixed (0);
        rbptr-> posY = to_fixed (0);
        rbptr-> posZ = to_fixed (0);
        rbptr-> pat = & PD_Robot;
    }

The works can be held by connecting them with a list of pointers.
If you want to move multiple characters in one event, use the work to allocate RAM.

    typedef struct road {
        struct road * next;
        FIXED posX, posY, posZ;
        PDATA * pat;
    } ROAD;

    typedef struct rdat {
        Sint16 px, py, pz;
        Uint16 pn;
    } ROAD_DAT;

    ROAD_DAT roadtbl [] = {
        {0, 0, 0, PN_ROAD},
        {0, 0, 100, PN_ROAD},
        {0, 0, 200, PN_ROAD}
    };;

    void InitRoadControl ( EVENT * evptr) {
        WORK * wkptr;
        ROAD * rdptr;
        ROAD_DAT * rdtptr;
        int cnt;

        rdptr = (ROAD *) evptr;
        rdtptr = roadtbl;
        for (cnt = sizeof (roadtbl) / sizeof (ROAD_DAT); cnt-> 0;) {
            if ((wkptr = slGetWork ()) == NULL ) {
                break;
            }
            rdptr-> next = (ROAD *) wkptr; / * The first pointer is * /
                                                / * Enter the work of the event * /
            rdptr = (ROAD *) wkptr;
            rdptr-> posX = rdtptr-> px << 16; / * Position * /
            rdptr-> posY = rdtptr-> py >> 16;
            rdptr-> posZ = rdtptr-> pz >> 16;
            rdptr-> pat = pattbl [rdptr-> pn]; / * Pattern data * /
            rdtptr ++;
        }
        rdptr-> next = NULL ; / * End mark * /
        evptr-> exit = (void *) RoadControl;
    }

■ Notes on clock change

◆ RAM guaranteed at the time of clock change

◆ RAM not guaranteed at the time of clock change

Therefore, it is necessary to reinitialize the unguaranteed memory after the clock change.
In particular, if there is data in LOW-RAM or SOUND RAM before the clock change, the validity of the data is not guaranteed, so be sure to perform processing such as reloading the data.
From SGL 3.10, if a clock change occurs in slInitSystem, a dummy empty loop will be registered to keep the MC68000 running, so be sure to reload the sound driver after the clock change.
In addition, slInitSystem resets each status and register to the initial state, so please reinitialize each parameter in the user program.

■ About initialization of BSS area and system variable area

When programming in C language, an area called BSS is always secured. When you use an uninitialized variable programmatically, you allocate a portion of this memory space called BSS for that variable.
When defining an uninitialized variable in a normal program, it is a prerequisite that some value is assigned later, but in rare cases, it may be used as it is. In that case (although these operations are usually programming mistakes), it is common to assume 0 for the operation. If an undefined value is written in this area, the behavior when using the uninitialized variable as it is becomes undefined and becomes a hotbed of bugs. Therefore, in the SGL sample program, the program is linked to return / sample / common / cinit.c and the BSS area is cleared to 0 in it.
This is why the SGL sample starts with ss_main, and the main function performs this kind of initialization.
Also, the "system variable area" used inside SGL is the same. In this case, depending on the BOOT ROM, the stack may be set in the place where it overlaps with this area, and the contents are undefined. You may think that the SGL function slInitSystem initializes everything, but in reality, this function does not initialize all areas, and in some cases, the SGL function may be used. It may also refer to an indefinite value.
Since 0 clear of this "system variable area" is also performed in "cinit.c" above, the above two problems can be solved by linking this file. If you do not link this file in your program, be sure to do these initializations.
Note that this cinit.c has a bug until recently, and the "system variable area" could not be initialized, so your cinit.c is

        / * 3.SGL System Variable Clear * /
        for (dst = (Uint8 *) SystemWork, i = 0; i <SystemSize; i ++) {
                * dst = 0;
        }

If it is, change it as follows.

        / * 3.SGL System Variable Clear * /
        for (dst = (Uint8 *) SystemWork, i = 0; i <SystemSize; i ++) {
                * dst ++ = 0;
                / * ^^ * /
        }

■ About blanking interrupt processing

The blanking start interrupt executes scroll data transfer, executes the DMA transfer table created by slTransferEntry, and executes the user function registered by slIntFunction [a]. Of these, scrolling data transfer can be prohibited by the PauseFlag variable.

PauseFlag is a Uint8 type flag variable that works to prohibit the above forwarding except for 0.

The blanking end interrupt performs modes such as erase write and frame change of the sprite frame buffer, DMA transfer of sprite data, capture of peripheral data, and subtraction of the interrupt wait counter. Of these, the part related to sprites can be prohibited by the above Pause Flag.

■ About FRT used in SGL

SGL uses FRT (Free Running Timer) to issue commands to SMPC. At this time, the FRT division ratio is 128, and it is prohibited for the user to change this.
This is because the FRT is weighted for that time so that SMPC requests are not made during the time when access to the SMPC of 300 μs is prohibited after V-Blank In.

■ About arithmetic library and system library

The numbers used in the library are based on the following usage:

Fixed-point data such as positions and trigonometric functions:
The upper 16 bits are the integer part and the lower 16 bits are the decimal part. Total 32 bits (signed) Type name FIXED

example)
When representing 16.5
0x0010_8000
━━━━━━━━
↑↑ 
      │ └── Decimal part └──────── Integer part

The coordinates are the X-axis (plus is right) in the left-right direction, the Y-axis (plus is down) in the up-down direction, and the Z-axis (plus is back) in the depth direction.

Angle: When expressing 360 degrees in 16 bits
Model name ANGLE

example)
90.0 °: 0x4000
45.0 °: 0x2000
22.5 °: 0x1000
11.25 °: 0x0800

If you create a rotation matrix, the positive direction of the angle will rotate clockwise with respect to the axis.

queue :
FIXED is used for the numerical value. It is a 3x4 matrix, and the layout on the memory is as follows.
    M00 , M01 , M02 ,
    M10 , M11 , M12 ,
    M20 , M21 , M22 ,
    M30 , M31 , M32

■ Overview of peripheral library

◆ This will tell you everything! Peripheral control sample program
  void main ()
  {
    slInitSystem ( TV_320x224 , NULL , 1);
    {
      slSetLanguage ( SMPC_JAPAN );
      slSetSoundOutput ( SMPC_SOUND_STEREO );
      (void) slSetSmpcMemory ();
    }

    {
      SmpcDateTime * dt = & ( Smpc_Status- > rtc);

      dt-> year = 0x1999;
      dt-> month = SMPC_FRI | SMPC_DEC ;
      dt-> date = 0x31;
      dt-> hour = 0x23;
      dt-> minute = 0x59;
      dt-> second = 0x59;
      (void) slSetDateTime ();
    }

    (void) slResetDisable ();

    while ( TRUE ) {
      if ( slCheckReset () == SMPC_RES_ON ) {
      (void) slClearReset ();
      break;
    }

    if ( Per_Connect1 ) {
      PerDigital * pad;

      pad = Smpc_Peripheral + 0;
      if (! (Pad-> data & PER_DGT_ST )) break;
    }
    slSynch ();
  }

  (void) slResetEnable ();
  (void) slIntBackCancel ();

  while ( TRUE ) slSynch ();
}

■ Forbidden hands when using the library and
Example of execution failure due to function call procedure

☆ Calls from slave SH2 are prohibited.
Since the internal work area is not taken as the cache-through area, the behavior is undefined.
In particular, since exclusive control is not performed normally, problems such as deadlock of SMPC will occur.

After executing "slGetPeripheral " and "slGetStatus ", if the importback command is being executed when the following functions are called, the execution will fail.
This happens because SMPC command requests in weight mode assume that they do not use the command cache.
      slNMIRequestWait
      slResetDisableWait
      slResetEnableWait
      slSetDateTimeWait
      slSetSmpcMemoryWait

To avoid the above execution failure, call "slIntBackCancel " and issue the command in the next frame.

The following functions will fail to execute even if the intoback command is not being executed.
This is because SMPC prohibits the issuance of importback commands outside the default settings.

      slSetPortDir1,2
      slSetPortExt1,2
      slSetPortSelect1,2

To avoid the above execution failure, call "slIntBackCancel".

  ◆ If the following conditions are set after executing "slIntBackCancel"
     Calling " slGetPeripheral " fails.

     " SlSetPortSelect1 , 2" for the port, which was to SMPC control mode in the " SlSetPortDir1 , 2" and the output set in.
     External latch input was allowed with " slSetPortExt1,2".

In either of the above cases or when both are set.

This is because SMPC prohibits the issuance of importback commands outside the default settings.
Both ports 1 and 2 were set to SH2 direct mode with " slSetPortSelect1 and 2".

This is because SMPC prohibits the issuance of importback commands that return only peripheral data when both port select is in SH2 direct mode regardless of the port I / O settings.

  ◆ If the following conditions are set after executing "slIntBackCancel"
     Calling " slGetStatus " fails.

     " SlSetPortSelect1 , 2" for the port, which was to SMPC control mode in the " SlSetPortDir1 , 2" and the output set in.
     External latch input was allowed with " slSetPortExt1,2".

In either of the above cases or when both are set.
This is because SMPC prohibits the issuance of importback commands outside the default settings.

◆ Limit performance
☆ Maximum number of caching commands ... 31 ☆ Maximum peripheral data size ... 15 bytes * 30 ports

Supports data acquisition in 15-byte mode from peripheral devices released as of April 1, 1995 and peripheral devices to be released in the future.

Data can be acquired in 255-byte mode by registering the user-defined buffer address in the system variables " Smpc_Status " and " Smpc_Peripheral".
However, library support is required for device-specific data conversion processing.

■ About command issuance of sound function and success or failure.

The sound driver has eight command buffers.
The SGL sound function first transfers a command to a buffer inside the library instead of sending it to the driver's buffer each time it is requested.
When the slSndFlush function is called or the slSynch function is called, it is transferred to the command buffer using CPU-DMA.
In addition, the timing flag handshake is used for communication with the sound driver, and before the data in the buffer is transferred by DMA, the data is transferred after waiting until the timing flag of the sound driver becomes 0.
Generally, if the sound function is unsuccessful, it happens when there are not enough pronunciation control numbers or PCM channels.

■ About polygon data

The polygon data used by slPutPolygon () has the following format.

    .data.l point_tbl; Table of vertex coordinates .data.l NbPoint; Number of vertices to be calculated .data.l polygon_tbl; Table of normal vector and vertex number of each polygon .data.l NbPolygon; Number of polygons to be calculated. data.l attribute_tbl; Table of attributes for each polygon point_tbl:
    .data.l X, Y, Z; Coordinate data of vertex number 0 .data.l X, Y, Z; Coordinate data of vertex number 1 ...
    .data.l X, Y, Z; Coordinate data of vertex number NbPoint -1

When creating a table in C language, the POINT type is declared, and the above data table can be created by using the POStoFIXED macro.

example)
        static POINT point_CUBE [] = {
            POStoFIXED (-80, -80, -80),
            POStoFIXED (80, -80, -80),
            POStoFIXED (80, 80, -80),
            POStoFIXED (-80, 80, -80),

            POStoFIXED (80, -80, 80),
            POStoFIXED (-80, -80, 80),
            POStoFIXED (-80, 80, 80),
            POStoFIXED (80, 80, 80)
        };;

 polygon_tbl:
    .data.l Nx, Ny, Nz; Normal vector of polygon number 0 .data.w P0, P1, P2, P3; Number of vertices used in polygon number 0 (for triangular polygons, P2 and P3 are the same Become a number)
        ...
    .data.l Nx, Ny, Nz; Normal vector of polygon number NbPolygon --1 .data.w P0, P1, P2, P3; Vertex number used in polygon number NbPolygon --1; Number

When creating a table in C language, the POLYGON type is declared, and the above data table can be created by using the POStoFIXED macro.

example)
        static POLYGON polygon_CUBE [] = {
            { POStoFIXED (0, 0, -1), {0, 1, 2, 3}},
                | __ | __
            { POStoFIXED (1, 0, 0), {1, 4, 7, 2}},
            { POStoFIXED (-1, 0, 0), {5, 0, 3, 6}},
            { POStoFIXED (0, -1, 0), {4, 1, 0, 5}},
            { POStoFIXED (0, 1, 0), {2, 7, 6, 3}},
            { POStoFIXED (0, 0, 1), {4, 5, 6, 7}},
        };;

 attribute_tbl:
    .DATA.B Revcheck; whether Kano flag to display a surface which is on the back side by front and back determination Single_Plane and Dual_Plane specify one of.
    .data.b SortMode; Declares how to calculate the position to be used as the basis for sorting and the use of optional functions.
                        SORT_CEN , SORT_MIN , SORT_MAX , SORT_BFR SORT_CEN : Uses the average of the specified 4 Z positions as the sorting reference SORT_MIN : Uses the smallest Z position of the 4 points SORT_MAX : 4 points Uses the largest Z position among them SORT_BFR : Uses the Z position of the previously displayed polygon Always displayed in front of the previous polygon Options are specified in addition to these UseTexture , UseLight , UseClip options Can be specified more than once.
        UseTexture : Specify when using a texture (transformation sprite).
        UseLight : The color of the polygon is offset by the inner product of the light source vector and the normal vector to express lightness and darkness.
                   Cannot be used at the same time as UseTexture.
        UseClip : When using a large polygon, use it when the display position overflows and cannot be displayed correctly.

    .data.w TextNum; When using a texture, use it as the registration number of the character.
    .data.w DispMode; Specifies the polygon display mode.
                               The display modes that can be specified are as follows: MSBon : Set only the most significant bit to 1 when writing to the frame buffer. (Shadow on sprites usually uses this)
        HSSon : High speed shrink enabled HSSoff : High speed shrink disabled (default)
        Window_In : Display inside the specified window.
        Window_Out : Display outside the window.
        No_Window : (default) Display without being affected by the window.
        MESHon : Display as a mesh.
        MESHoff : (default) Normal display.
        ECdis : Disables end code when using textures.
        ECenb : (default) Enables end code when using textures.
        SPdis : Disables spaces (displayed in palette 0 color) when using textures.
                However, if the data written to the frame buffer becomes 0000, it will not be displayed, so adjust the value such as priority so that it does not become 0000.
        SPenb : (default) Enables space when using textures.

        CL16Bnk : (default) Sets the color mode of the texture to the 16-color color bank method.
        CL16Look: Sets the texture color mode to a 16-color look-up table.
        CL64Bnk : Set the color mode of the texture to the 64 color bank method.
        CL128Bnk : Set the color mode of the texture to the 128 color bank method.
        CL256Bnk : Sets the color mode of the texture to the 256-color color bank method.
        CL32KRGB : Set the color mode of the texture to the RGB method of 32000 colors.

        CL_Replace : (default) Enter rewrite mode.
        CL_Trans : Display semi-transparently.
        CL_Half : Display at half brightness.
        CL_Shadow : Show shadow.
        CL_Gouraud : Specifies Gouraud shading.

        Specify one of each group as the display mode.

    .data.w Color; Specifies the display color.
        If it is affected by a light source, or if you specify a display mode other than CL_Replace , it must be in RGB mode.
        Also, when using textures and in CL32KRGB mode, the indication here is ignored.

    .data.w GouraudTable; Specifies the Gouraud shading table.
        If CL_Gouraud is specified, it indicates the offset position of the Gouraud shading table. The offset position is specified by setting SpriteVRAM (0x25c00000) to 0 and advancing by 1 every 8 bytes.
        For example, if there is data in 0x25c12000 (0x25c12000 --0x25c00000) / 0x08 = 0x2400

    .data.w Function; Specifies the sprite display function.
        Specifies whether to display as polygons, textures, or polylines.
        Select one from the following six to specify.
        sprNoflip: Shows the texture.
        sprHflip: Displays the texture horizontally inverted.
        sprVflip: Inverts the texture vertically and displays it.
        sprHVflip: Inverts the texture both vertically and horizontally.
        sprPolygon : Display as a polygon.
        sprPolyLine : Shows polylines (polygon contours only).

    When creating a table in C language, ATTR type is declared and ATTRIBUTE
    You can create the above data table by using macros.
  example)
        static ATTR attr_CUBE [] = {
            ATTRIBUTE ( Single_Plane , SORT_MIN , No_Texture , CD_MediumGreen ,
                      No_Gouraud , Window_In , sprPolygon , UseLight ),
            ATTRIBUTE ( Single_Plane , SORT_MIN , No_Texture , CD_MediumBlue ,
                      No_Gouraud , Window_In , sprPolygon , UseLight ),
            ATTRIBUTE ( Single_Plane , SORT_MIN , No_Texture , CD_MediumMagenta ,
                      No_Gouraud , Window_In , sprPolygon , UseLight ),
            ATTRIBUTE ( Single_Plane , SORT_MIN , No_Texture , CD_MediumWhite ,
                      No_Gouraud , Window_In , sprPolygon , UseLight ),
            ATTRIBUTE ( Single_Plane , SORT_MIN , No_Texture , CD_MediumYellow ,
                      No_Gouraud , Window_In , sprPolygon , UseLight ),
            ATTRIBUTE ( Single_Plane , SORT_MIN , No_Texture , CD_MediumRed ,
                      No_Gouraud , Window_In , sprPolygon , UseLight )
        };

■ About attributes for sprite display functions

The attribute table used by slPutSprite () and slDispSprite () is almost the same as the one for Poligon above, but the first two data are missing.
When creating this table in C, the SPR_ATTR type is declared and you can use the SPR_ATTRIBUTE macro.

example)
        SPR_ATTR attr_AM2Logo = {
            SPR_ATTRIBUTE (PN_AM2_Logo, CL_AM2_Logo, No_Gouraud , Window_In | ECdis ,
                sprNoflip | _ZmCB )
        };;

_ZmCB specifies which position of the sprite the position points to, and the following 9 are defined.
     _ZmLT _ZmCT _ZmRT
           + ------- + ------- +
           | | |
     _ZmLC + ---- _ZmCC ------ + _ZmRC
           | | |
           + ------- + ------- +
     _ZmLB _ZmCB _ZmRB

■ Sprite display sample

 #define CGtop 0x10000
 #define TEXTBL (hs, vs, cga) {hs, vs, (cga) >> 3, ((hs) & 0x1f8) >> 5 | (vs)}
 #define AdjCG (cga, hs, vs, col) ((cga + (((hs) * (vs) * 4) >> (col)) + 0x1f) & 0x7ffe0)
 #define PICTBL (txno, cmod, cga) {txno, cmod, cga}
 #define CL_Triangle 0x00

 static const Uint16 triangle [] = {
   0x0000,0x0001,0x1000,0x0000, / * Sprite character data * /
   0x0000,0x0012,0x2100,0x0000,
   0x0000,0x0123,0x3210,0x0000,
   0x0000,0x1234,0x4321,0x0000,
   0x0001,0x2344,0x4432,0x1000,
   0x0012,0x3333,0x3333,0x2100,
   0x0122,0x2222,0x2222,0x2210,
   0x1111,0x1111,0x1111,0x1111
 };

 enum patn {
   PN_Triangle, / * Sprite pattern number * /
   Max_Texture, / * Total number of patterns * /
   Max_Picture = Max_Texture / * Total number of characters * /
 };

 enum cga {/ * character address * /
   CG_Triangle = CGtop,
   CG_Next = AdjCG (CG_Triangle, 16, 8, COL_16 )
 };

 TEXTURE form_tbl [] = {/ * Pattern size data * /
   TEXTBL (16, 8, CG_Triangle)
 };

 PICTURE pic_tbl [] = {/ * Character definition table * /
   PICTBL (PN_Triangle, COL_16 , triangle)
 };

 static const Sint16 Triangle_Color [] = {/ * color data * /
                    RGB (0, 0, 31), RGB (0, 0, 29), RGB (0, 0, 27),
   RGB (0, 0, 25), RGB (0, 0, 23), RGB (0, 0, 21), RGB (0, 0, 19),
   RGB (0, 0, 17), RGB (0, 0, 15), RGB (0, 0, 13), RGB (0, 0, 11),
   RGB (0, 0, 9), RGB (0, 0, 7), RGB (0, 0, 5), RGB (0, 0, 3)
 };

 typedef struct {/ * structure for color definition * /
   Sint16 * src;
   void * dst;
   Sint16 size;
 } COLMAP;

 static const COLMAP ctrns_list [] = {/ * color definition table * /
   {Triangle_Color,
     (void *) ( VDP2_COLRAM + (CL_Triangle + 1) * 2),
     sizeof (Triangle_Color)
   }
 };

 extern TEXTURE * FormTbl ;

 / * * /
 / * Character data transfer * /
 / * * /

 void SetTexture (PICTURE * pcptr, Uint32 NbPicture) {
   TEXTURE * txptr;

   for (; NbPicture-> 0; pcptr ++) {
     txptr = FormTbl + pcptr-> texno;
     slDMACopy (pcptr-> pcsrc,
                (void *) ( SpriteVRAM + ((txptr-> CGadr) >> 3)),
                (txptr-> Hsize * txptr-> Vsize * 4) >> (pcptr-> cmode));
   }
 }

 / * * /
 / * Color data transfer * /
 / * * /

 void SetColor () {
   COLMAP * cmptr;
   Sint16 cnt;

   slTVOff ();
   cmptr = ctrns_list;
   for (cnt = sizeof (ctrns_list) / sizeof (COLMAP); cnt-> 0; cmptr ++) {
    slDMACopy (cmptr-> src, cmptr-> dst, cmptr-> size);
   }
   slTVOn ();
 }

 / * Sample character display position * /
   FIXED tpos [] = { toFIXED (1.0), toFIXED (2.0), toFIXED (2.0), toFIXED (4.0)};
 / * | | | | _ Display scale * /
 / * X position Y position Y position ( toFIXED ( ORIGINAL ) for 1x magnification)
                                                        Please specify) * /

 / * Sample character data * /
   SPR_ATTR tattr = SPR_ATTRIBUTE (PN_Triangle, CL_Triangle, No_Gouraud , CL16Bnk , sprNoflip | _ZmCC );
 / * | | | | | | __ Rotation center position * /
 / * | | | | | __ No character inversion * /
 / * | | | | __ 16-color color bank mode * /
 / * | | | ___ Do not use Gouraud shading * /
 / * Pattern number Color bank number * /

 main () {
   ANGLE ang = DEGtoANG (0.0);

   * ( Uint32 *) (0x06002500) = ( Uint32 ) (0x060007f0);
   / * During the clock change, 68K for sound reads the switch data,
      It seems that data will be prepared at the address set here,
      It seems that it is not working well, so for the time being, enter the address with the data 0xFFFF that has not been pressed * /

   slInitSystem ( TV_320x224 , form_tbl, 1); / * System initialization * /
   SetTexture (pic_tbl, Max_Picture); / * Set character data * /
   SetColor (); / * Set color data * /
   while (-1) {
     slDispSprite (tpos, & tattr, ang); / * Sprite registration * /
     ang + = DEGtoANG (3.0);
     slSynch (); / * Sprite output with synchronization to screen display * /
   }
 }

■ Real-time goo usage procedure

The following four processes are required to realize real-time goo-net.

(1) Add the following 3 to the attribute table
  1. Specify " CL_Gouraud " for MODE.
  2. Specify the storage position of the glow table in GOURAUD.
  3. Specify " UseGouraud " for OPTION.
<Example>
     ATTRIBUTE ( Single_Plane , SORT_CEN , 0, 0xffa0, 0xe000,
            CL16Look | MESHoff | CL_Gouraud , sprNoflip , UseGouraud )

(2) Specification of normal vector
Specify the normal vector of each vertex and the polygon model data table called "XPDATA"
<Example >>
         VECTOR gr_point [] = {/ * Vertex normal vector data * /
           toFIXED (-0.873), toFIXED (0.436), toFIXED (0.217),
           toFIXED (-0.873), toFIXED (-0.436), toFIXED (0.217),
                                ::
                                ::
         };
         XPDATA PD_BOX = {/ * Model table specification * /
           point_BOX, / * Vertex position data table * /
           sizeof (point_BOX) / sizeof ( POINT ), / * Number of vertices * /
           polygon_BOX, / * Polygon definition table * /
           sizeof (polygon_BOX) / sizeof ( POLYGON ), / * Number of polygons * /
           attribute_BOX2, / * Polygon attribute table * /
           gr_point / * Vertex normal vector data * /
         };

(3) Initialization of real-time gourd program
(a) Specify the position and size of the gourd table to be used.
<Example>
       slInitGouraud (( GOURAUDTBL *) gr_tab, ( Uint32 ) 300, 0xe000, addr);

(b) Register the Glow program in the V blank
<Example>
       slIntFunction ( slGouraudTblCopy );

(4) Designation of light source vector
<Example>
         FIXED light [ XYZ ];
         light [ X ] = toFIXED (1.0);
         light [ Y ] = toFIXED (0.0);
         light [ Z ] = toFIXED (0.0);
         slPutPolygonX (& PD_BOXx, ( FIXED *) light);

(5) Actual program usage example
<Example>
 static GOURAUDTBL gr_tab [300];

 void ss_main (void)
 {
   FIXED light [ XYZ ];
          ::
   / * Initialization of real-time glow program * /
   slInitGouraud (( GOURAUDTBL *) gr_tab, ( Uint32 ) 300, 0xe000, addr);
   slGouraudTblCopy ();
   slSynch ();
               ::
   light [ X ] = toFIXED (1.0);
   light [ Y ] = toFIXED (0.0);
   light [ Z ] = toFIXED (0.0);
   while (1)
   {
           ::
     slPushMatrix ();
     {
        ::
       / ** /
       slPutPolygonX (& PD_BOX, ( FIXED *) light);
     }
     slPopMatrix ();
     slSynch ();
   }
 }

■ Near clipping

If "UseNearClip " is specified for OPTION of the attribute table, near clipping processing is performed. " UseClip " has been replaced with "UseNearClip " by adding the same function from Ver3.0.

<Example>
  ATTRIBUTE ( Single_Plane , SORT_CEN , 1, No_Palet , No_Gouraud , 
              CL32KRGB | MESHoff , sprNoflip , UseNearClip );

■ Differences between SGL Ver2.1x and SGL Ver3.00

(1) Change of light source calculation method for flat shading
The light source calculation method for flat shading has been changed as follows.
<Light source calculation method up to Ver2.1x>
Angle between light source and surface → 0 ------ 45 ------ 90 ----- 135 ----- 180
Goo table → 31 ----- 16 ------ -0 ------ 0 ------ 0
<Light source calculation method from Ver3.0>
Angle between light source and surface → 0 ------ 45 ------ 90 ----- 135 ----- 180
Goo table → 31 ----- 24 ----- -16 ------ -8 ------ 0

(2) Resizing the color development data table due to the influence of the light source
By adding a function to the light source processing, the size to secure the color development data table (CLOfsfBuf) area has been increased.

32x32 (0x400) to 32x32x3 (0xC00)

It was changed to.

Therefore, the change of sglarea.o in the saturn / sgl / lib directory where the initial value was set, and the user custom

saturn \ sgl \ sample \ workarea

Files such as workarea.c in the directory have also been modified in the calculation part. Be sure to change it when migrating from SGL Ver2.1x.

(3) Remove the UseClip option
The attribute option UseClip has been replaced with UseNearClip by adding the function of SGL Ver3.0.
SGL User's ManualSupplementary Manual
Copyright SEGA ENTERPRISES, LTD., 1997