[Post] Game Development 4 Based on Nokia s60

Source: Internet
Author: User
Tags export class
Generally, the application uses the cwsscreendevice Graphics Device to describe on the screen, which is associated with the cwindowgc graphics context. Cone provides a cwindowgc instance as the standard graphical context of the Drawing Control. It is created by ccoeenv and can be accessed using the ccoecontrols: systemgc method. The cwindowgc method is used to buffer the client window Server Buffer. <Br>
It is either a system initial transaction or an application initial transaction. The initial tracing is triggered when the window is created, or when the window content fails due to overlapping windows. In the latter case, the window server maintains an invalid area for each window. If a window needs to be re-painted, the window server sends a re-painting event to an application with an invalid window. Cone then uses the invalid region to create the controls to be repainted and call their draw method. This is why each control should implement the draw method to redraw itself. By default, draw in ccoecontrol is empty. The following code illustrates the example of the draw method: <br>
<Table width = "100%" bgcolor = # ffffff>
<Tbody>
<Tr>
<TD> void cexamplecontrol: Draw (const trect & amp;/* arect */) const <br >{< br> // get the system graphics context <br> cwindowgc & amp; GC = systemgc (); <br> // set drawing Settings <br> GC. setbrushstyle (cgraphicscontext: esolidbrush); <br> GC. setbrushcolor (krgbred); <br> // draw <br> GC. drawline (tpoint (10, 10), tpoint (30, 10 )); <br >}</TD> </tr> </tbody> </table> <br> the trect parameter of the draw method specifies the invalid region to be repainted. However, most controls ignore the rectangle because it is very simple and it is not very slow to redraw the entire control. <Br> when the data or status of an application changes, you need to initialize the application and update the screen. Ccoecontrol provides a non-virtual drawnow method, indicating the window server to be drawn by the control, calling the draw method of the control, and finally specifying the window server to complete the painting. Ccoecontrol also provides the drawdeferred method to invalidate the window and trigger a new re-painting event on the window server. The difference between the two methods is that drawnow forces the control to re-draw itself immediately, and drawdeferred causes a re-draw event to use a low-priority operation. Since cone uses a higher priority level to process user input events, any unspecified user input events will be handled first. However, because the entire control needs to be re-painted, it is a very heavy operation. Generally, only the changed part needs to be re-painted. This can be done using the following code: <br>
<Table width = "100%" bgcolor = # ffffff>
<Tbody>
<Tr>
<TD> void cexamplecontrol: drawbitmap (const tpoint & amp; apoint, <br> const cfbsbitmap * abitmap) <br >{< br> // get the system graphics context and control rectangle <br> cwindowgc & amp; GC = systemgc (); <br> // establish drawing rectangle <br> trect rect = trect (apoint, <br> tsize (abitmap. iwidth, abitmap. iheight); <br> // activate graphics context <br> activategc (); <br> // invalidate window <br> Window (). invalidate (rect); <br> window (). beginredraw (rect); <br> // draw a bitmap <br> GC. drawbitmap (apoint, abitmap); <br> window (). endredraw (); <br> // deactivate graphics context <br> deactivategc (); <br >}</TD> </tr> </tbody> </table> <br> the preceding Sample Code draws a cfbsbitmap at the position defined by the apoint parameter. In the example, it is worth noting that the graphic context needs to be activated before use and disabled after the painting is completed. In addition, the window server needs to obtain information about the client that is about to start the re-painting, which is completed using the beginredraw method. The invalidate method is required because the window server allows only one application to be illustrated in an invalid area. In a system initial re-painting, cone activates the graphic context and calls the beginredraw method for the application. If the window is no longer valid, the invalidate method does not have to be called-that is why the system needs to be first illustrated. <Br>

Sub-graphics (genie)

A child image is a masked (mask) bitmap that can be moved without re-drawing the underlying window. If the game does not need to update the background frequently, it would be better to use subgraphs. For example, a game like Pacman moves in a non-scroll and fixed background. The re-painting is performed by the window server, replacing a high priority task. This kind of game should consider smooth animation and sub-graphics movement. Symbian OS provides two different subgraphs: pointer and animated bitmap. Figure 1 shows the hierarchy of the sub-graphics class.


Figure 1 Hierarchy of sub-graphics classes

Rwsspritebase is an abstract basic class for sub-graphics. It has one or more tspritemembers that contain bitmap data of sub-graphs. By specifying multiple members with different bitmaps, the child image can be active. Tspritemember also defines the mask of the bitmap. The time interval between the position of the bitmap and the display of the bitmap in the subgraph. Rwssprite is a class used for subgraphics. In addition to the constructor, it provides only one setposition Method for moving subgraphs. The following code illustrates how to create a subgraph using a bitmap loaded from an MBM file.

Rwssprite sprite = rwssprite (ieikonenv-> wssession ());
User: leaveiferror (sprite. Construct (window (), tpoint (0, 0), 0 );
For (tint I = 0; I <8; I + = 2)
{
Imember [I/2]. ibitmap = new (eleave) cfbsbitmap ();
User: leaveiferror (member. ibitmap-> load (kbitmapfile, I, efalse ));
Imember [I/2]. ibitmap = new (eleave) cfbsbitmap ();
User: leaveiferror (member. imaskbitmap-> load (kbitmapfile, I + 1, efalse ));
Imember [I/2]. iinvertmask = efalse;
Imember [I/2]. ioffset = tpoint (0, 0 );
Imember [I/2]. iinterval = ttimeintervalmicrosecond32 (100000 );
User: leaveiferror (sprite. appendmember (imember [I/2]);
}

After the child graph member has been updated and attached to the rwssprite class, the Child graph can be activated by calling rwsspritebase: Activate. After that, the child image is displayed on the screen and ready to move. The content of the Child image can be changed using the rwsspritebase: updatemember method. Cfbsbitmaps can also access the window server, so only the bitmap handle of the Child image is sent to the window server. This allows the bitmap of the Child image to be updated quite quickly. When the child image is no longer needed, the window server needs to call rwsspritebase: close to release the resource. However, the client member data to be deleted is not released. Rwspointercursor is a class used to create a cursor for an application.

Double Buffering

If a game's graphics consist of multiple motion objects that need to be updated frequently, the client buffer of the window server may be filled and overflow may occur when all objects are updated. The screen may flash. If a view is still being updated, it may flash or have other undesirable effects. The solution to these problems is dual buffering. The image is first painted on an off-screen bitmap and then painted on the screen as a single window server. Especially for games that redraw screens several times in one second, using off-screen bitmaps can improve their performance.

An out-of-screen bitmap can be created using bitmap graphics context and graphics equipment class: cfbsbitgc and cfbsbitmapdevice. They are created and used using other context and device classes. For extra performance, the bitmap itself should be a cwsbitmap bitmap. After the screen bitmap is updated, it can be painted in the window using the normal method of the window server.

When an application draws a bitmap in a window, it is converted to the same display mode as the window. This is a very time-consuming operation, which may actually reduce the plotting speed. Therefore, the game that uses bitmaps for animation should complete the conversion before the animation starts. The conversion can be performed by using an off-screen bitmap, as shown in the following example:

Cfbsbitmap * cexamplecontrol: loadandconvertbitmapl (
Const tdesc & afilename, tint abitmapid)
{
// Load the bitmap
Cfbsbitmap * originalbitmap = new (eleave) cfbsbitmap ();
Cleanupstack: pushl (originalbitmap );
User: leaveiferror (originalbitmap-> load (afilename, abitmapid, efalse ));
// Create a new bitmap, Graphics Device and context
Cfbsbitmap * newbitmap = new (eleave) cfbsbitmap ();
Cleanupstack: pushl (newbitmap );
Newbitmap-> Create (originalbitmap-> sizeinpixels (), window ()-> displaymode ());
Cfbsbitmapdevice * graphicsdevice = cfbsbitmapdevice: newl (bitmapconverted );
Cleanupstack: pushl (graphicsdevice );
Cfbsbitgc * graphicscontext;
User: leaveiferror (graphicsdevice-> createcontext (graphicscontext ));
Tpoint zero (0, 0 );

// Bmap the loaded bitmap to the new bitmap
Bitmapcontext-> bitblt (zero, originalbitmap );
Cleanupstack: Pop (3 );
Delete bitmapcontext;
Delete bitmapdevice;
Delete originalbitmap;
Return newbitmap;
}

The example uses a file name and a bitmap ID as the parameter, and loads the corresponding bitmap from an MBM file. If a game has many bitmaps that should be converted, it should be converted at the game or LEVEL initialization stage. Therefore, the user will not see this operation.

Direct plotting

Using a window server to draw images on the screen requires a context conversion, which slows down the painting speed. To bypass the window server, you can directly access the screen without tedious context conversion. This is called a direct picture. There are two methods in Symbian OS to draw images directly on the screen.

Cfbsscreendevice is a graphical device that can be sent to the screen driver scdv. dll. After creating a cfbsbitgc image context, it can be used like any other graphics device. However, you can draw images directly on the screen without using a window server. Another method of drawing directly on the screen is to query the screen memory address from the system. This can be achieved using the usersrv class:

Tpckgbuf <tscreeninfov01> infopckg;
Tscreeninfov01 & screeninfo = infopckg ();
Usersvr: screeninfo (infopckg );
Tuint16 * screenmemory = screeninfo. iscreenaddress + 16;

The screen memory has a 32-byte header.

Even if writing data in the screen memory is a little faster than cfbsscreendevice, the function may vary depending on the hardware and the driver of the screen. In some Symbian OS-based terminals, the screen is automatically updated from the screen memory when the memory changes. In other terminals, explicit activation is required. The screen memory address is only valid for the target hardware. Therefore, the plotting code must be divided into two parts: hardware and simulator. In the simulator environment, you can draw an out-of-screen bitmap instead of the screen memory, and then use the normal window server to draw a method block to transfer it to the screen. The environment can be detected by using the _ wins _ definition.

# Ifdef _ wins _ // emulator Environment
// Draw to an off-screen bitmap
# Else // hardware environment
// Draw directly to the screen memory
# Endif

One common problem between the two direct tracing methods is that the window server does not understand the tracing, so it cannot notify the application whether there is another window or window group. Even if an application gets an event when it loses focus, it cannot stop Directly Plotting because it is too fast and the screen content may be messed up. This may happen when a phone call comes in during a game.
The latest GT 6.1 version provides an Application Programming Interface for direct plotting, which can solve the problems mentioned above. This application programming interface consists of two classes: An mdirectscreenaccess class, which provides callback methods for applications, and a cdirectscreenaccess class for communication with the window server. The following code describes how the cdirectscreenaccess instance is constructed and how the direct drawing support is activated.

Idrawer = cdirectscreenaccess: newl (ieikonenv-> wssession (), * ieikonenv-> screendevice (), window (), * This );
Ieikonenv-> wssession (). Flush ();
Idrawer-> startl ();
Idrawer-> screendevice ()-> setautoupdate (etrue );

The newl method of cdirectscreenaccess obtains a window Server session, cone graphical device, application window, and a pointer to the mdirectedscreenaccess export class as a parameter. Before cdirectscreenaccess: startl is called to activate direct plotting, the client window Server Buffer should overflow. To automatically update the screen, the setautoupdate method of the screen device must use the etrue parameter. When direct plotting supports activation, cdirectscreenaccess generates a cfbsbitgc graphical context that can be used by applications to draw images on the screen.

Idrawer-> GC ()-> bitblt (tpoint (0, 0), ibitmap );

When another window appears in the application window, cdirectscreenaccess obtains an event from the window server to interrupt the profiling. Cdirectscreenaccess then calls the abortnow method of the derived class of mdirectscreenaccess. This method must be reloaded by the application to interrupt plotting. To prevent screen clutter, the window server does not draw overlapping windows until the trace interruption event is handled.

Prepared by Wayne Li Juan
Time: 2004-04-13
Source: yesky

Tpckgbuf <tscreeninfov01> infopckg;
Tscreeninfov01 & screeninfo = infopckg ();
Usersvr: screeninfo (infopckg );
Tuint16 * screenmemory = screeninfo. iscreenaddress + 16;

The screen memory has a 32-byte header.

Even if writing data in the screen memory is a little faster than cfbsscreendevice, the function may vary depending on the hardware and the driver of the screen. In some Symbian OS-based terminals, the screen is automatically updated from the screen memory when the memory changes. In other terminals, explicit activation is required. The screen memory address is only valid for the target hardware. Therefore, the plotting code must be divided into two parts: hardware and simulator. In the simulator environment, you can draw an out-of-screen bitmap instead of the screen memory, and then use the normal window server to draw a method block to transfer it to the screen. The environment can be detected by using the _ wins _ definition.

# Ifdef _ wins _ // emulator Environment
// Draw to an off-screen bitmap
# Else // hardware environment
// Draw directly to the screen memory
# Endif

One common problem between the two direct tracing methods is that the window server does not understand the tracing, so it cannot notify the application whether there is another window or window group. Even if an application gets an event when it loses focus, it cannot stop Directly Plotting because it is too fast and the screen content may be messed up. This may happen when a phone call comes in during a game.
The latest GT 6.1 version provides an Application Programming Interface for direct plotting, which can solve the problems mentioned above. This application programming interface consists of two classes: An mdirectscreenaccess class, which provides callback methods for applications, and a cdirectscreenaccess class for communication with the window server. The following code describes how the cdirectscreenaccess instance is constructed and how the direct drawing support is activated.

Idrawer = cdirectscreenaccess: newl (ieikonenv-> wssession (), * ieikonenv-> screendevice (), window (), * This );
Ieikonenv-> wssession (). Flush ();
Idrawer-> startl ();
Idrawer-> screendevice ()-> setautoupdate (etrue );

The newl method of cdirectscreenaccess obtains a window Server session, cone graphical device, application window, and a pointer to the mdirectedscreenaccess export class as a parameter. Before cdirectscreenaccess: startl is called to activate direct plotting, the client window Server Buffer should overflow. To automatically update the screen, the setautoupdate method of the screen device must use the etrue parameter. When direct plotting supports activation, cdirectscreenaccess generates a cfbsbitgc graphical context that can be used by applications to draw images on the screen.

Idrawer-> GC ()-> bitblt (tpoint (0, 0), ibitmap );

When another window appears in the application window, cdirectscreenaccess obtains an event from the window server to interrupt the profiling. Cdirectscreenaccess then calls the abortnow method of the derived class of mdirectscreenaccess. This method must be reloaded by the application to interrupt plotting. To prevent screen clutter, the window server does not draw overlapping windows until the trace interruption event is handled.

Prepared by Wayne Li Juan
Time: 2004-04-13
Source: yesky

Rwssprite sprite = rwssprite (ieikonenv-> wssession ());
User: leaveiferror (sprite. Construct (window (), tpoint (0, 0), 0 );
For (tint I = 0; I <8; I + = 2)
{
Imember [I/2]. ibitmap = new (eleave) cfbsbitmap ();
User: leaveiferror (member. ibitmap-> load (kbitmapfile, I, efalse ));
Imember [I/2]. ibitmap = new (eleave) cfbsbitmap ();
User: leaveiferror (member. imaskbitmap-> load (kbitmapfile, I + 1, efalse ));
Imember [I/2]. iinvertmask = efalse;
Imember [I/2]. ioffset = tpoint (0, 0 );
Imember [I/2]. iinterval = ttimeintervalmicrosecond32 (100000 );
User: leaveiferror (sprite. appendmember (imember [I/2]);
}

After the child graph member has been updated and attached to the rwssprite class, the Child graph can be activated by calling rwsspritebase: Activate. After that, the child image is displayed on the screen and ready to move. The content of the Child image can be changed using the rwsspritebase: updatemember method. Cfbsbitmaps can also access the window server, so only the bitmap handle of the Child image is sent to the window server. This allows the bitmap of the Child image to be updated quite quickly. When the child image is no longer needed, the window server needs to call rwsspritebase: close to release the resource. However, the client member data to be deleted is not released. Rwspointercursor is a class used to create a cursor for an application.

Double Buffering

If a game's graphics consist of multiple motion objects that need to be updated frequently, the client buffer of the window server may be filled and overflow may occur when all objects are updated. The screen may flash. If a view is still being updated, it may flash or have other undesirable effects. The solution to these problems is dual buffering. The image is first painted on an off-screen bitmap and then painted on the screen as a single window server. Especially for games that redraw screens several times in one second, using off-screen bitmaps can improve their performance.

An out-of-screen bitmap can be created using bitmap graphics context and graphics equipment class: cfbsbitgc and cfbsbitmapdevice. They are created and used using other context and device classes. For extra performance, the bitmap itself should be a cwsbitmap bitmap. After the screen bitmap is updated, it can be painted in the window using the normal method of the window server.

When an application draws a bitmap in a window, it is converted to the same display mode as the window. This is a very time-consuming operation, which may actually reduce the plotting speed. Therefore, the game that uses bitmaps for animation should complete the conversion before the animation starts. The conversion can be performed by using an off-screen bitmap, as shown in the following example:

Cfbsbitmap * cexamplecontrol: loadandconvertbitmapl (
Const tdesc & afilename, tint abitmapid)
{
// Load the bitmap
Cfbsbitmap * originalbitmap = new (eleave) cfbsbitmap ();
Cleanupstack: pushl (originalbitmap );
User: leaveiferror (originalbitmap-> load (afilename, abitmapid, efalse ));
// Create a new bitmap, Graphics Device and context
Cfbsbitmap * newbitmap = new (eleave) cfbsbitmap ();
Cleanupstack: pushl (newbitmap );
Newbitmap-> Create (originalbitmap-> sizeinpixels (), window ()-> displaymode ());
Cfbsbitmapdevice * graphicsdevice = cfbsbitmapdevice: newl (bitmapconverted );
Cleanupstack: pushl (graphicsdevice );
Cfbsbitgc * graphicscontext;
User: leaveiferror (graphicsdevice-> createcontext (graphicscontext ));
Tpoint zero (0, 0 );

// Bmap the loaded bitmap to the new bitmap
Bitmapcontext-> bitblt (zero, originalbitmap );
Cleanupstack: Pop (3 );
Delete bitmapcontext;
Delete bitmapdevice;
Delete originalbitmap;
Return newbitmap;
}

The example uses a file name and a bitmap ID as the parameter, and loads the corresponding bitmap from an MBM file. If a game has many bitmaps that should be converted, it should be converted at the game or LEVEL initialization stage. Therefore, the user will not see this operation.

Direct plotting

Using a window server to draw images on the screen requires a context conversion, which slows down the painting speed. To bypass the window server, you can directly access the screen without tedious context conversion. This is called a direct picture. There are two methods in Symbian OS to draw images directly on the screen.

Cfbsscreendevice is a graphical device that can be sent to the screen driver scdv. dll. After creating a cfbsbitgc image context, it can be used like any other graphics device. However, you can draw images directly on the screen without using a window server. Another method of drawing directly on the screen is to query the screen memory address from the system. This can be achieved using the usersrv class:

Tpckgbuf <tscreeninfov01> infopckg;
Tscreeninfov01 & screeninfo = infopckg ();
Usersvr: screeninfo (infopckg );
Tuint16 * screenmemory = screeninfo. iscreenaddress + 16;

The screen memory has a 32-byte header.

Even if writing data in the screen memory is a little faster than cfbsscreendevice, the function may vary depending on the hardware and the driver of the screen. In some Symbian OS-based terminals, the screen is automatically updated from the screen memory when the memory changes. In other terminals, explicit activation is required. The screen memory address is only valid for the target hardware. Therefore, the plotting code must be divided into two parts: hardware and simulator. In the simulator environment, you can draw an out-of-screen bitmap instead of the screen memory, and then use the normal window server to draw a method block to transfer it to the screen. The environment can be detected by using the _ wins _ definition.

# Ifdef _ wins _ // emulator Environment
// Draw to an off-screen bitmap
# Else // hardware environment
// Draw directly to the screen memory
# Endif

One common problem between the two direct tracing methods is that the window server does not understand the tracing, so it cannot notify the application whether there is another window or window group. Even if an application gets an event when it loses focus, it cannot stop Directly Plotting because it is too fast and the screen content may be messed up. This may happen when a phone call comes in during a game.
The latest GT 6.1 version provides an Application Programming Interface for direct plotting, which can solve the problems mentioned above. This application programming interface consists of two classes: An mdirectscreenaccess class, which provides callback methods for applications, and a cdirectscreenaccess class for communication with the window server. The following code describes how the cdirectscreenaccess instance is constructed and how the direct drawing support is activated.

Idrawer = cdirectscreenaccess: newl (ieikonenv-> wssession (), * ieikonenv-> screendevice (), window (), * This );
Ieikonenv-> wssession (). Flush ();
Idrawer-> startl ();
Idrawer-> screendevice ()-> setautoupdate (etrue );

The newl method of cdirectscreenaccess obtains a window Server session, cone graphical device, application window, and a pointer to the mdirectedscreenaccess export class as a parameter. Before cdirectscreenaccess: startl is called to activate direct plotting, the client window Server Buffer should overflow. To automatically update the screen, the setautoupdate method of the screen device must use the etrue parameter. When direct plotting supports activation, cdirectscreenaccess generates a cfbsbitgc graphical context that can be used by applications to draw images on the screen.

Idrawer-> GC ()-> bitblt (tpoint (0, 0), ibitmap );

When another window appears in the application window, cdirectscreenaccess obtains an event from the window server to interrupt the profiling. Cdirectscreenaccess then calls the abortnow method of the derived class of mdirectscreenaccess. This method must be reloaded by the application to interrupt plotting. To prevent screen clutter, the window server does not draw overlapping windows until the trace interruption event is handled.

Prepared by Wayne Li Juan
Time: 2004-04-13
Source: yesky

Tpckgbuf <tscreeninfov01> infopckg;
Tscreeninfov01 & screeninfo = infopckg ();
Usersvr: screeninfo (infopckg );
Tuint16 * screenmemory = screeninfo. iscreenaddress + 16;

The screen memory has a 32-byte header.

Even if writing data in the screen memory is a little faster than cfbsscreendevice, the function may vary depending on the hardware and the driver of the screen. In some Symbian OS-based terminals, the screen is automatically updated from the screen memory when the memory changes. In other terminals, explicit activation is required. The screen memory address is only valid for the target hardware. Therefore, the plotting code must be divided into two parts: hardware and simulator. In the simulator environment, you can draw an out-of-screen bitmap instead of the screen memory, and then use the normal window server to draw a method block to transfer it to the screen. The environment can be detected by using the _ wins _ definition.

# Ifdef _ wins _ // emulator Environment
// Draw to an off-screen bitmap
# Else // hardware environment
// Draw directly to the screen memory
# Endif

One common problem between the two direct tracing methods is that the window server does not understand the tracing, so it cannot notify the application whether there is another window or window group. Even if an application gets an event when it loses focus, it cannot stop Directly Plotting because it is too fast and the screen content may be messed up. This may happen when a phone call comes in during a game.
The latest GT 6.1 version provides an Application Programming Interface for direct plotting, which can solve the problems mentioned above. This application programming interface consists of two classes: An mdirectscreenaccess class, which provides callback methods for applications, and a cdirectscreenaccess class for communication with the window server. The following code describes how the cdirectscreenaccess instance is constructed and how the direct drawing support is activated.

Idrawer = cdirectscreenaccess: newl (ieikonenv-> wssession (), * ieikonenv-> screendevice (), window (), * This );
Ieikonenv-> wssession (). Flush ();
Idrawer-> startl ();
Idrawer-> screendevice ()-> setautoupdate (etrue );

The newl method of cdirectscreenaccess obtains a window Server session, cone graphical device, application window, and a pointer to the mdirectedscreenaccess export class as a parameter. Before cdirectscreenaccess: startl is called to activate direct plotting, the client window Server Buffer should overflow. To automatically update the screen, the setautoupdate method of the screen device must use the etrue parameter. When direct plotting supports activation, cdirectscreenaccess generates a cfbsbitgc graphical context that can be used by applications to draw images on the screen.

Idrawer-> GC ()-> bitblt (tpoint (0, 0), ibitmap );

When another window appears in the application window, cdirectscreenaccess obtains an event from the window server to interrupt the profiling. Cdirectscreenaccess then calls the abortnow method of the derived class of mdirectscreenaccess. This method must be reloaded by the application to interrupt plotting. To prevent screen clutter, the window server does not draw overlapping windows until the trace interruption event is handled.

Prepared by Wayne Li Juan
Time: 2004-04-13
Source: yesky

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.