dwTerm 2.3
Users' and Programmers' Manual

  1. Introduction

    dwTerm is a software terminal to programs, since it is a minimal GUI to let programmers concentrate on what programs do. Build only the core of your project as a DLL, and let dwTerm load and run it. The windows of dwTerm maintain the outputs, and decompose input command strings to call handlers in the DLL. Furthermore, dwTerm provides DLL programmers with functions for files and 2D/3D graphics, and provides users with scripting which runs many commands in a file right after loading the DLL.

    For example, if your program is to receive users' commands, and to simply display some texts or graphs and you don't want any complex or luxurious design of the main window with many child windows, dwTerm will satisfy you. This may be the case, especially if you are going to program to calculate or do a numerical analysis but you know nothing about creating a window and even don't want to learn it. The output display window and the command input window of dwTerm.exe interact with your DLL.

    This method not only lets dwTerm take other parts of the whole program, but also saves the computer's memory if you want to run mutiple instances of the whole program, which cannot be expected when it is built as an EXE.

    According to dwTerm API (Application Programming Interface), handlers in your DLL can be called by dwTerm at events (including the start, the end, and the command-input), and various functions in dwTerm can be called by your codes in the DLL. The prototypes of these routines and the related data structures are defined in a header file written in C and should be included in compliling your DLL.

    Some functions help you read or write formatted numbers. Other functions can provide you with useful objects to ease Win32 GDI or OpenGL programming, so that beginners in graphics can use dwTerm as a good toolkit. Furthermore, the display window is capable of anaglyph (3D visualization using 2-color stereoscopic images overlapped to view with 2 color glasses), and the related functions are included.

    Programming is easy to begin, since example DLLs with the source codes are included in the package, from "hello" to differential equations and graphics.

    dwTerm can run the DLL by way of a script file where the DLL and input commands are specified. This is helpful if results you want to see can be achieved after many input commands.

    Throughout the manual, "using" means running dwTerm, letting it load and run a DLL directly or through a script, and editting the script to see the effects. "Programming" means writing a DLL source and building the DLL binary by your compiler.

  2. Installation

    1. Upgrading

      If you have used a previous version, you don't have to uninstall it. Just install this version as described in the next sections, selecting OK in the box asking your confirmation of overwriting. If you have a license file, it will be effective also for this version.

    2. System Requirements

      • CPU: Intel 80486 or higher

      • OS: Windows 95, Windows NT 4.0 or higher

    3. Trial Version

      dwTerm is distributed as a compressed file, *.zip, without a full license key. That is, the zip file is for the trial version. The installation process is simple. Just extract all of the files contained in it into a folder and run the installer(Install.exe).

      In the second box in the installer, be sure not to choose the product folder but the parent folder! For example, choose "C:\Program Files" if you want dwTerm to be installed in "C:\Program Files\dwTerm". If you are a new user, the product folder does not exist and the installer will create it.

      A new user now has the trial license. That is, there are restrictions on some features, before you acquire and install a full license key.

    4. Full License Key

      Go to http://www.softbattery.net and acquire a key, a small file. Then put it into the folder in which the trial version is installed.

  3. How to Use

    The following is the screenshot of the dwTerm's main window, after the default script intro.dsc (model.dll) is loaded right after you run dwTerm. You can load other DLL by the menu as decribed in this chapter.

    All the example DLLs in the package came with source codes and are mainly tutorials for programming. But, like this example, some of them may also attract users who need a few graphs, 3D models or stereoscopic (anaglyph) images. This example is described here to help you understand dwTerm, and the others are described in the next chapter.

    All the configuration including the main window's size (adjustable unless fixed by the DLL) and location, and options specified by menus, are saved in a file named "conf" and are used in the next run of dwTerm.

    1. Controls

      If a script or a DLL is loaded, the title bar string shows it's path prefixed by "Script=" or "DLL=" and also shows the title "dwTerm". If the sub-title is provided by DLL, it appears between them. These 3 entities are separated by " - ".

      Below the menu bar is located the output display window, the input command window and the status bar. As well as the DLL can draw multi-line texts and graphics in the display window, the DLL may display single-line texts in the status bar.

      Right after a DLL is loaded, dwTerm calls the "Load" handler in the DLL if found. Just before calling a handler, the status bar informs the user of it by the "pre-call" message, as shown in the screenshot. Then the handler runs, and can give dwTerm a "post-call" message as a result so that it shows on the status bar erasing the previous message. Our example, the Load handler in model.dll, after drawing some 3D objects, does not report such a post-call message and the pre-call message remains as in the screenshot.

      There is a button on the right of the command window. Either press it, or press the Enter key in the command window, to input the command string after typing. Enter a command "z" for our example to show the distance of the 3D objects on the status bar or enter a command "z 5000" to see a closer look at the objects. The latter also shows the distance on the status bar as "d1: z = 5000...". What happened are as follows.

      dwTerm calls the "Command" handler after a command is entered. The pre-call message contains the prefix "dwTerm Input n: " for the n-th command. The handler in the example DLL(model.dll) so quickly draws the closer image and reports the new z value as the post-call message that you can hardly see the pre-call message.

      When unloading, dwTerm calls the "Unload" handler in the DLL, if found. dwTerm stops unloading if the handler issues a message.

      Note that the post-call messages of the 3 handlers contains the prefix "dn: ", with n = 0 for the Load handler and n = N+1 for the Unload handler if N commands input.

      Here is a summary on the status bar messages. There can be 3 handlers in the DLL. The pre-call message appears for a handler, and the post-call message may or may not. No message for a handler not found. Only the string after the prefix in the post-call message is given by the DLL while the other strings in all the pre-call and post-call messages are by dwTerm.

      The command window is an edit box where simple operations like Ctrl+C is allowed. It has an additional feature. If the DLL need a long command including a file or folder path which can tire you in typing, you can use the mouse to drag it from a folder window and drop it into the edit box. Then the path apears at the edit-cursor.

      Some DLLs can show an read-only multi-line edit box instead of the graphics output display window.

    2. Menus

      If the installation was successful, the file extension "dsc" is associated with dwTerm so that you can then run dwTerm and load a script file (*.dsc) just by double-clicking the file in a folder window. If not, press the right mouse button on any script file and follow the system boxes to associate them. Refer to your OS manual for details.

      If you run dwTerm not by the association but directly by dwTerm.exe (by shortcuts in the Start menu or desktop), it searches the dwTerm folder (where dwTerm is installed) for a default script named "intro.dsc" and tries to load it if found, as described early in this chapter to load model.dll. If you don't have any practical interest in this example, it just provides a beautiful(?) picture you see when you start dwTerm that way. If you even don't think so, you may modify or remove the script.

      The [File]->[Load...] menu lets you manually load a DLL or a script. A file with the extension "dll" (*.dll) is loaded as a DLL, and any other file is loaded as a script. Therefore a script file extension does not have to be "dsc".

      Use the [File]->[Edit...] menu to let your editor open the script file loaded. You may not use this menu after you loaded the DLL directly (Will you? Why?). The editor can be specified by the [Option]->[Editor...] menu, as shown below. Set the path of your text editor in the "Application" edit box, by browsing. The command line string for the editor can be specified. Use "%m" to represent the script file path, and use "%%" if you need "%".

      The [File]->[Reload] menu reloads the file. You may use this menu frequently when you edit the script to see the results, which can tire you. In that case just press Ctrl+Alt+R even on your editor. Then the menu runs. (If your are a programmer, you may prefer your IDE where you edit the script and run dwTerm as a tool). The hot key can be changed from this default, by [Option]->[Hot Key...] menu as shown below. Click the display window to set the focus on it, and press the hot key you want or press Spacebar to delete the hot key.

      The DLL is unloaded, just before it or another DLL is loaded by the 2 menus above, or when dwTerm ends (by the [File]->[eXit] menu or by other ways). The DLL is also unloaded by the [File]->[Unload] menu. In any case, a DLL (the Unload handler in it) can refuse to be unloaded for some reason (the DLL programmer may need you to wait or input something for example). The DLL generally shows the post-call message on the status bar or some texts in the display window to say the reason. Since dwTerm does not end before unloading, you sometimes cannot but kill dwTerm if you use a bad DLL or if you don't want to follow the DLL's message.

      The [Setup] menu helps you use DLLs or scripts in more convenient ways. Those ways can be called as the setup or installation of them. The [Setup]->[System Folder] menu opens the system folder, which is useful when you want to put a DLL into it. Refer to the next section about when you want a DLL to be in it. The [Setup]->[Start Folder] menu opens the Start menu folder, which is useful when you want to put a script file or a shortcut to it in the Start menu.

      The [Help]->[Manual...] menu opens this manual, and the [Help]->[About...] menu shows the version, the copyright and the license status.

    3. Scripts

      A dwTerm script is a text file, in which the DLL to load and a set of command strings to input automatically right after loading are specified. Loading a script means for dwTerm to read it, load the DLL specified in it, and let the DLL process the commands specified in it. The syntax is simple, as you may recognize in "intro.dsc" included in the package. Use [File]->[Edit] menu to see the script of our example, and add two commands as follows.
      *** Default dwTerm Script *** ("default", since dwTerm will search the dwTerm folder for this file "intro.dsc" if none specified at the start-up.) (Any lines like this is meaningless, because they begin with a blank.) model\model.dll dwTerm Script Commands -- The following two commands are added now by you. z 10000 z abcd 123
      Save and press the hot key (Ctrl+Alt+R). Then the focus moves from the editor to dwTerm and the script gets reloaded. Our example shows a more distant look of the objects by the first command and the status bar says that the second command is wrong. If you edit and use a script for a DLL which contains very many commands, you may feel tired in debugging. The "stop"(whatever name) command that may be defined in such a DLL can help debugging since it requests dwTerm to stop scripting before the next command. One of the examples in the package realized the command using the corresponding dwTerm API functions.

      The next paragraphs describes the syntax of dwTerm Script, although you might already understand it by taking a look at intro.dsc.

      Begin a line with a blank to make it meaningless to dwTerm and to write a note or comment. Therefore the title in the first line in "intro.dsc" is meaningless, for example.

      The first meaningful line tells the path and the file name of the DLL. The path can be absolute, or relative to the script's location. If the path is omitted, the DLL is supposed to be in the folder where the script exists, or in the system folder. Every example's script in the package omits the path since the DLL is in the same folder, except intro.dsc using a relative path. The system folder is the best location of DLL, since it makes the path omitted and lets the script be anywhere, which you may want when your DLL is neither an example nor a program under development but a program you will seriously use.

      The command string lines come next, preceded by the break line "dwTerm Script Commands". They are read, understood and processed by the DLL through the Command handler in it.

  4. Additional Examples

    This chapter describes how to run the examples, other than model.dll (intro.dsc) described in the previous chapter and hello.dll in the next chapter. Each section name is the file (DLL or script) name, and is also the name of the folder in the package which includes the files with source codes.

    All the examples are mainly for the DLL programmers with their source codes described in the next chapters, but some users can be interested in some of them. Users may enter commands or modify scripts to obtain good results or want to be a programmer to modify DLLs. More useful DLLs can be found in the Internet, especially at http://www.softbattery.net.

    You can run them by loading the DLLs, or by loading the scripts. The latter way lets you see the same outputs as the screenshots shown in the sections, while the former can show poor outputs, since some scripts contain commands.

    1. count

      This program reads numbers from the file named "data" and inform you of how many numbers are in a range specified.

      The commands are defined as follows. The results appear in the output display window.

      • b 3
        counts values below 3 for example.
      • ge 5
        counts values greater than or equal to 5 for example.
      • r 4 7
        counts values, greater than or equal to 4, and below 7, for example.

    2. diffeqn

      This program solves a differential equation y"=-sin(x) for x = 0 to 8 with initial conditions y(0)=0, y'(0)=0, using a predictor-corrector method.

      All the commands except "s" shows 4 parameters in the output display window, the meanings of which are:

      • m, h
        m is a positive integer that divides the x range to obtain the step size h.
      • r
        Iterations at each x will stop when the differences of y and y' from the previous calculation are less than r times 0.1.
      • N
        Iterations at any x more than N times are not allowed. When such an iteration is needed, the solution stop and will not go on to the next x.

      The commands are defined as follows.

      • m 30
        sets m = 30 for example, divides the x range to obtain h, and allocates the result data space for y, y' and n the number of iteration valued at the all m+1 x-points.
      • r 0.01
        sets r = 0.01 for example.
      • N 6
        sets N = 6 for example.
      • s
        solves the equation. The result will be written into the file named "data", and the message "File saved." will show in the display window.

      The screenshot above shows the reactions when you input these 4 command examples in that order. Although you can see the result of the s command in the text file "data", you may want to see graphs of the data. The following screenshot shows them drawn by running graph.dsc, after Canvas Commander is installed which is also a dwTerm DLL application downloadable at http://www.softbattery.net/canvascommander. You need a dwTerm license since graph.dsc contains more than 20 commands.

      The next examples are tutorials about graphics programing as described in the next chapters, for you to develop a DLL like Canvas Commander.

    3. graph

      This program draws sine functions sin(Angle-Phase) versus Angle with various Phase.

      The commands are defined as follows. All the commands except "e" shows Phase on the status bar.

      • e
        erases all and redraws the title and axis.
      • p 90
        sets Phase = 90 deg for example.
      • p
        just shows Phase on the status bar.
      • d
        draws the graph.

    4. draw

      This program is the same as the previous one except that the graph title and the axis are absent and that the sub-title "Sine" is added into the titile bar.

    5. plot2d

      This is a plotting program helpful for visual optimization of a 2-dimensional 2nd order function.

      f(x, y) = Axxx2 + Axyxy + Ayyy2 + Axx + Ayy + A1
      The dots in the x-y plane are painted by the colors which depend on the calculated function values as follows.
      • "+" color when f > z
      • "0" color when |f| ≤ z
      • "-" color when f < -z

      There are 4 brushes for "+", "0", "-" and "e"(erase, i.e. background) colors. The colors are specified and the brushes are created or deleted, by commands. The "e" brush is initially created and used to erase all before the first command. The parameters of the function are specified by commands. The graphics region is defined, created and deleted, also by commands.

      The commands are defined as follows.

      "brush commands": sets z and brushes, and erases over the graphics region. All the commands shows values about z and brushes, on the status bar, where the data for a brush are displayed as, for example for the "+" brush, "+: ffff00" if the brush exists or "+: N(ffff00)" if not. The 3 bytes in the hexadecimal mean the the blue, green and red intensities, from the left, so that the example value (ffff00) stands for a cyan color.

      • z 0.5
        sets z = 0.5 for example.
      • b + n
        destroys the "+" brush. The same goes for the other 3 brushes if "+" in the command is replaced.
      • b + c 0xffff00
        sets the "+" color = 0xffff00 for example, and creates the brush. The same goes for the other 3 colors if "+" in the command is replaced.
      • b +
        creates the "+" brush. The same goes for the other 3 brushes if "+" in the command is replaced.
      • b
      • z
        just shows the data on the status bar.
      • e
        Erases anything over the region, with the "e" brush.

      "plot commands": sets the function parameters and paints dots. All the commands shows parameters, on the status bar.

      • p xx 3.5
        sets Axx = 3.5 for example. The same goes for the other parameters if "xx" in the command is replaced.
      • p
        just shows the parameters on the status bar.
      • d
        paints dots over the region, using the brush according to the function value for each dot. If the brush does not exist, the dot will not be painted, so that the present dot color will be kept unchanged, which enables the accumulated drawings of ellipses done by the command strings in "intro.dsc" where only the "e" and "+" brushes are created.

      "region commands": sets the graphics region by setting the dot size and the mathematical coordinates. All the commands shows the dot size and the coordinates, on the status bar. The dot size t is the length of each edge of each square do. The region r is defined by the x, y coordinates of the bottom left corner and the top right corner. Note that the dot size is measured in pixels, and that the coordinates are in dots.

      • t 3
        sets t = 3 for example, and runs the "e" and "d" commands, if 3 is new.
      • r -10 25 100 90
        sets r = (-10 25 100 90) for example, and runs the "e" and "d" commands, if any coordinate value is new.
      • t
      • r
        just shows the size and coordinates on the status bar.

    6. anaglyph

      Do you have anaglyph glasses? If not, you can make it now with trivial things like some sheets of paper and color filters like cellophane. With the red filter for the left eye and the cyan for the right, you can feel real-3D in the following picture generated by the DLL.

      4 rows of texts and 2D objects are displayed. The 1st and the 4-th rows are on the screen, while the 2nd is above the screen to you and the 3rd below the screen from you, if your glasses are correct. The DLL can be modified to include a command to change the glass colors if you are a programmer.

      The commands are defined as follows.

      • move 2
        move the text and rectangle in the first row into the screen, and display the "z" value (2) on the status bar. Try -2 instead of 2 to move out of the screen. Larger absolute values may make you feel 2 overlapped images rather than real-3D, since the color filters of the glasses are not perfect: The number is not the z coordinate actually but just the left-to-right image separation.
      • move
        just displays the z value on the status bar..

    7. stereo

      Viewed with anaglyph glasses, the following picture of this example makes you see the wire cylinder getting out of the screen and the mosaic sphere deep into the screen. See the comments in the previous example about anaglyph and more features obtainable by modifying DLLs if you are a programmer.

      The commands are defined as follows.

      • z 8000
        defines the distance of the objects from you, to be 8000 for example. Since the default is 6500, this pushes the objects more far from you, enough for the cylinder to go deep into the screen and so that they looks smaller. This command also shows the parameters on the status bar.
      • s 5000
        defines the distance of the screen (monitor) from you, to be 5000 for example, showing the parameters on the status bar. Since the default is 2500, this is enough for the cylinder comming out of the screen, if you changed z to 8000 when learning the z command above. If you did not and z remains to be 6500, this new s makes you feel two overlapped image rather than real-3D, because the absolute value of the left-to-right image separation for anaglyph becomes too large for the glasses' color-filtering. Try 500 and 2500 as s to make you feel good in changing the depth of the objects with respect to the screen, if z is 6500.
      • z
      • s
        just displays the parameters.

    8. debug

      The source codes of this example show how programmers can provide users with a "stop" command useful in debugging scripts.

      The commands are defined as follows.

      • good
        does nothing.
      • bad
        shows a post-call message "Not ready!" (on the status bar).
      • stop
        enables the stop feature. The "stop" box will pop-up when the next command makes the DLL issue any post-call message like the command "bad" or a bad(wrong tokens) command. The DLL can be modified so that the box appears on a special or no message.

  5. Getting Started in Programming

    This and the next 3 chapters show how to make a DLL for dwTerm and what happen in and between the two modules. If you have never built any DLL, the first section of this chapter can be a tutorial. Buiding a DLL is as easy as buliding a *.exe.

    The 4 chapters have the same way of organization. The API reference is the last section, and the other sections are tutorials which briefs the API with comments on the source codes of the related examples. While the source codes of all the examples in the package are commented about in these chapters, the usages are described in the previous 2 chapters except hello.dll, so that the comments usually omits even what the programs (DLL) are for.

    1. hello.dll

      Here is hello.c of hello.dll, the simplest example in the package.
      #define EXPORT __declspec(dllexport) EXPORT char *dwTermH_Load (char *CmdLine, char **Title, void *dwtf) { return "Hello!"; }
      A function in a DLL is said to be "exported" if it can be called by other module (*.exe for example). In this example the function is exported by the definition of "EXPORT" and making it precede the function.

      All the examples are compiled and linked by MinGW, and you can see the options used in compile.bat and link.bat in each example folder. You can use these batch files with your MinGW, after modifying the path. If your tool is not MinGW and you have never built any DLL, you may have to modify the source code for exporting, and should set your compiler and linker, after reading their manauls. Be careful in reading those manuals, to build not "Load-Time DLL" but "Run-Time DLLs". Otherwise, dwTerm should be re-built for your DLLs!

      After hello.dll is built by your tool and loaded by dwTerm, the result is the following screenshot. The next section comments on what happened.

    2. Handlers

      Right after loading a DLL, dwTerm searches it for a routine named as in the example and calls it if found. We call it the "Load" handler, and there are the other two handlers "Command" and "Unload" that a DLL can have. The two handlers are called when the user enter a command string, and when the DLL is about to be unloaded, respectively, A handler can return a string to let dwTerm show it on the status bar as the post-call message, and to refuse unloading if it is the Unload handler. Note that a handler should have the correct name "dwTerm_xxx" although we call it simply the xxx handler.

      If your DLL does not use any dwTerm API functions but just wants dwTerm to call handlers, the Load handler's prototype in hello.c is sufficient and the last argument dwtf is meaningless. Include in your project the header file dwterm.h in the "include" folder to use the last argument. It points to a structure DWTRMF containing the API function pointers, as is used in the next examples. The header file is dependent on the Win32 API header windows.h that your compiler may have.

      Let's turn to count.c (The only source file this manual shows is hello.c as in the previous section. Please use your editor or viewer to see source files in examples' folders, while reading this manual). Note that this example has one more handler.

      The Load handler saves the last argument into a global variable dwt to use it later, since it is the pointer to the dwTerm API function pointers. You can call a function aftn(a, b) for example by
      dwt->aftn(a, b)
      and the API reference sections also describe each function using the prefix "dwt->" although dwt is just a variable name that you can change.

      This example has its program name "Count" which is added in the title bar, since the Load handler routine requests dwTerm using the argument "title". The Command handler is given the tokens of the command string. For example, the tokens of "ab cd" are "ab" and "cd".

    3. Inputs and Outputs

      The example count.c shows the result not in the status bar but in the output display window, by ShowDisplay() and Printf(). The Load handler uses ShowDisplay() to show the text window instead of the graphics window, i.e. to turn the output display into a read-only multi-line edit box, to "print" texts there. Printf() is similar to the famous C function printf except that there is an additional first argument to specify the number of empty lines to insert before the text. These two functions belong to the Display group in the API reference in the next chapter.

      Use ReadNumber() as in this example, to easily read a number from a text file. It takes any string separated from others by blanks or new lines as a number, and returns the double precision float number.

      There is one more example, diffeqn, which uses the text display window. It also introduces to you the other handler "Unload". The handler in this example frees the memory allocated by the command handler to contain the differential equation's solution. This example uses one more print function Print() to show a text without any format.

      While diffeqn shows the parameters in the display, the main output is the equation's solution in a file named "data". Writef() is used to write a formatted text into the file. It is similar to the c function printf() except that the output is directed to a file with the additional first argument being the file handle.

      To solve a second order differential equation, the example investigates into the equivalent pair of coupled first order equations. The result file can be graphed by graph.dsc and Canvas Commander. The next chapters show how to develop such a graphic program like Canvas Commander.

    4. Primary Reference
      DWTRMF is a special structure type, in which a group of dwTerm function potinters are listed. Therefore a function is called by prefixing the function name by "dwt->", if dwt is the pointer value given to Load handler. The functions' prototypes in these API references are also prefixed by it. //*********************************************************************** // Handlers //*********************************************************************** are procedures in a DLL to be called by dwTerm after loading it. Be sure to write and export the handler with the correct name and arguments. If a handler returns the pointer to a null-terminated string, the status bar shows it as the post-call message. If the handler returns NULL, the bar remains unchanged. Refer to the "How to Use" chapter about the format of the message. The string is used by dwTerm only once right after the handler returns, to write on the bar. Therefore you can use the string space (memory) for other purposes or free it, in any handler called later. char *dwTermH_Load (char *CmdLine, char **title, DWTRMF *dwtf); is called right after the DLL is loaded, if found, so that you can initialize your work (for example, allocate memory spaces and so on). In this handler you can also process the following arguments. CmdLine is reserved. Do not use this. title is used to display your own title on the dwTerm title bar. You should let *title point to a null-terminated string, "mytitle" for example, if you want dwTerm to write on the title bar "dwTerm - mytitle" instead of "dwTerm". A handler called later can use or free the string space. dwtf points to the structure DWTRMF which contains dwTerm API function pointers, so that a function ftn() can be called dwtf->ftn() for example. You may save it on a global variable unless you will use the functions only in this handler. char *dwTermH_Unload (void); is called when the DLL is about to be unloaded, if found. Return a null-terminated string (pointer) to refuse. Return NULL otherwise. In this handler, the DLL may free or delete a memory space or other system resources that was allocated or created in the Load handlers, for example. It may refuse to be unloaded, if it wants the user to wait until something is processed or to input something, for example. You may inform the user of the refusal and the reason, by returning a message. char *dwTermH_Command (int nToken, char **token); lets you process user's command entered by the input command window (the edit box in the dwTerm main window). dwTerm breaks the command string into a number of tokens, where a token is a string without any blank. nToken the number of tokens token points to an array of null-terminated string pointer, where the string consists of a token and a null byte. For example, if the user entered "mycommand op1 op2", you have nToken=3, token[0]="mycommand", token[1]="op1", and token[2]="op2". //*********************************************************************** // Inputs and Outputs //*********************************************************************** typedef int dwt->Write (void *hFile, char *str); writes a null-terminated string to hFile. The return value is that of the C function fwrite(). hFile the file handle (FILE*), obtained by the C function fopen() str points to the null-terminated string. typedef int dwt->Writef (void *hFile, char *format, ...); is the same as Write(), except the string is internally prepared using format and the additional arguments like the C function printf(). typedef double* dwt->ReadNumber (double *number, void *hFile); reads a file skipping any successive blanks or next-lines to a string, and fills the buffer by the value returned from the C function atof(string). The string does not have any blanks or next-line characters, and the file pointer moves to the next blanks or next- lines. The function returns the buffer pointer on success or 0 on failure. number the buffer pointer hFile the file handle (FILE*), obtained by the C function fopen()

  6. Graphics Programming

    1. Display

      The DLL does not draw graphics on the output display window. It draws on "canvases" and lets the window copy them. There can be one or two "registered" canvases that are to be copied, with the latter for anaglyph. The details are described in the next sections and the next chapter.

      The window also should be updated when it is exposed to the user. Therefore, without this system of the window and canvases provided by dwTerm, the programmer should not only draw on the window when the contents needs modification, but also draw the same contents again and again whenever the user restores the window from the minimized state or from being invisible under other windows.

      We end this section by commenting on the coordinates in Win32 GDI and on a subtle thing about Win32 RECT structure, before going to the next section and returning to draw.c again.

      The coordinates are measured in pixels and the coordinate convention is: The origin is the top left corner, with the horizontal coordinate increasing to the right and the vertical to the bottom.

      When you express a rectangle by 4 coordinates as in RECT, don't forget that the "rectangle", i.e. the geometrical object we intend to represent by the expression does NOT include the right and the bottom edges of the expression. Most of GDI functions including those introduced in this manual have this convention, when they work (e.g. paint, copy, ...) with rectangles given as arguments. If you forget this, the result can differ from what you intend, by one pixel both horizontally and vertically.

    2. Canvases

      The Load handler in draw.c creates an object "canvas". An object in dwTerm is just a data structure which is managed and manipulated by dwTerm and the DLL using related API functions. Some members are Win32 type and others are not. The objects are so designed for you to do something without knowing much about the structure and without knowing any Win32 data type but the simple BOOL, POINT, and RECT. But, if you are an advanced Win32 programmer, you can exploit more members in the structure.

      There are several types of objects including canvas, with the structure type DWTRMD_Xxx, e.g. DWTRMD_Canvas. We simply denote the structure by the object type xxx, e.g. canvas. Some types of objects are allocated directly as a whole variable or by using the C function calloc() for example, and the structure members are set or initialized by functions or assignments. But canvases are allocated by the function CreateCanvas(), which returns the pointer after initializing the members.

      For the output display window to use a canvas for copying, it should be registered by RegisterCanvas(). Note that the canvas is deleted in the Unload handler in draw.c, by DeleteCanvas(), since it is created by the DLL. Elsewhere than in the Unload handler, be sure to uregister the canvas by RegisterCanvas(NULL, FALSE) before deleting, for dwTerm not try to access a destroyed space.

      The canvas size specified in pixels in CreateCanvas() are saved into the POINT type member "size" in the structure, and can be read by the DLL to know the boundary in drawing. dwTerm copies the registered canvases to the top-left area of the same size in the display window, and paints the other area with a gray color. FitDisplay() lets dwTerm adjust the window size for the canvas to fit onto the window and keep the user from changing the size.

      The last argument of RegisterCanvas() is related to 3D-modeling, and there are more functions for the display window and canvases, related to anaglyph, modeling and canvases, as described later in this manual.

    3. Drawing

      Now, you are ready to draw in draw.c, if you know about the painting tools, i.e. Win32 brushes, pens and fonts. The "painting box" is a useful object for you to use the tools without any Win32 function for them but creation like CreateSolidBrush(). NewPaintingBox() lets dwTerm allocate a painting box, i.e. an array for the tools, and NewXxx() save a tool('s handle) with the index in the array as the identifier.

      Although you should know the Win32 function to create a tool and to put it (the handle returned by the function) into the last argument in NewXxx(), you don't have to delete (free) it. You don't have to delete the painting box either. dwTerm maintains the handles and pointer to them, and automatically frees them after unloading the DLL.

      While dwTerm helps you program without many Win32 API functions, you should refer to your Win32 API documents if these examples codes and comments in this manual are not sufficient for you to understand those functions. Note also that link.bat in the examples' folder have the additional option "-mwindows" for those functions.

      After the d command routine in the Command handler in draw.c draws the rectangular dots on the registered canvas using PaintDot(), Show() is called to let the display window copy it. NULL instead of a specific RECT pointer as the first argument lets Show() copy all over the canvas. A valid brush index as the second argument lets Show() paint the area before copying, so that the other calls of Show() in draw.c shows the green canvas without any drawing function called before Show().

      Let's turn to a graph.c, which is similar to draw.c and has some new important things as in the next paragraph. A trivial thing new is the use of Win32 RECT function SetRect() to initialize a RECT. OffsetRect(), InflateRect() are also such functions you should get familiar in Win32 drawing.

      The first is SelectXxx() which selects a tool on the registered canvas. It was not used in draw.c since PaintDot()(the only drawing function there) is using the tools (brushes) specified as the arguments, like the other 2 dwTerm drawing functions. Most of Win32 drawing functions including Ellipse() and DrawText() don't have such arguments and want tools to be selected in advance. You may use such functions to draw circles and other shapes as well as texts.

      The second is the use of the Win32 type member hDC of a canvas structure, as the "device context handle" argument in Win32 drawing functions. The member hDC is the heart of the canvas and two Win32 functions SetBkMode() and SetTextColor() set its properties affecting DrawText().

      The final thing to comment on is Show(). The Load handler and the e command codes in the Command handler is calling Show() not after but before drawing, to paint the backgrounds as well as to show, as commented in the e command routine. This is not strange, since Show just requests the system to update an area in the display window and the system lets the display window do it (by copying the canvas or by painting gray) AFTER the handler returns.

      plot2d.c has two more things to comment on. A call of Show(NULL, xxx) in the routine Init can happen even when there is no canvas. Don't worry, since it does nothing in that case. You may also think that deleting without unregistering the canvas (Register(NULL, FALSE) is dangerous in the routine since there can be any updating by user's action (during very short time though) before the new canvas gets registered. Not at all. The response to such a request is also delayed untill the handler returns, like the request from the program as described in the previous paragraph.

    4. Graphics Reference
      //*********************************************************************** // Display //*********************************************************************** typedef void dwt->ShowDisplay (BOOL fGraphics); shows one of the graphics window and the text window, and hide the other. fGraphics TRUE shows the graphics window and FALSE shows the text window. The default is TRUE, i.e. the text window is hidden without this function called. typedef BOOL dwt->Print (int nLine, char *text); adds empty lines and a text to the text window. nLine the number of empty lines text the text, a null-terminated string typedef BOOL dwt->Printf (int nLine, char *format, ...); adds empty lines and a formatted text to the text window. nLine the number of empty lines format a null-terminated string to generate the text using the other arguments. Refer to the C function printf()'s corresponding last arguments because they have the same meanings and roles. typedef void dwt->SetDisplaySize (int width, int height); adjusts the main window to set the output display window size, and disables changing by the user. width, height the display window width and height typedef void dwt->FitDisplay (void); calls SetDisplaySize with the arguments corresponding to the registered canvas size, and does nothing if none registered. typedef void dwt->CopyDisplay (void); copies the display window to the clipboard as a bitmap, for the user to use the image in other graphics applications. typedef HWND dwt->GetDisplay (void); returns the graphics window's handle, which is useful if you know much about Win32. typedef HWND dwt->GetTextDisplay (void); returns the text window's handle. typedef void dwt->AnaglyphColors (int clrLeft, int clrRight); sets the colors to gray the left and right images taken from the registered canvases for anaglyph. Refer to comments on AnaglyphCanvas on this reference for details of anaglyphing. clrLeft, clrRight the colors for the left and right canvases. The value is taken as the Win32 COLORREF type value, i.e. 0x00bbggrr with bb, gg and rr each being the two hex digits to represent the blue, green and red component intensity respectively. The defaults are red (0xff) and cyan (0xffff00) respectively. typedef int dwt->GetLeftColor (void); returns the left color. typedef int dwt->GetRightColor (void); returns the right color. //*********************************************************************** // Canvases //*********************************************************************** typedef struct { HDC hDC; Handle of a memory DC compatible to the display window's DC. HBITMAP hBm, hOldBm; Handle of a bitmap compatible to the display window's DC, selected on the memory DC. hOldBm is just for internal use. POINT size; Width(=size.x) and height(=size.y) of the bitmap, in pixels. } DWTRMD_Canvas; typedef void dwt->DeleteCanvas (DWTRMD_Canvas *cv); deletes the resources for a canvas and frees the canvas memory. cv points to the canvas. typedef DWTRMD_Canvas* dwt->CreateCanvas (int size_x, int size_y); allocates a canvas structure, initializes and creates the members, and returns the pointer to the structure. size_x, size_y the canvas width and height, in pixels typedef void dwt->RegisterCanvas (DWTRMD_Canvas *cv, BOOL fModel); registers a canvas so that dwTerm takes it as the canvas to copy into the display window. The canvas also becomes the left canvas for anaglyph. Note that "the registered canvas" in this manual means the left one unless the context is for the right one. cv points to the canvas. NULL means to unregister. If there are painting tools selected by SelectXxx on the previous canvas, they gets selected on the new canvas. fModel The function gets the display window and the canvas suitable for OpenGL, if this argument is TRUE. typedef RECT* dwt->CopyCanvasRect (RECT *rect, RECT *rc); sets a rectangle structure by copying other or by the registered canvas size. rect points to the target rc points to the source. If NULL, the target becomes a rectangle RECT={0, 0, cv->size.x, cv->size.} for the registered canvas pointed by cv. If rc=NULL and none registered, the function returns NULL. Otherwise it returns rect. typedef DWTRMD_Canvas* dwt->CloneCanvas (BOOL fCopy); creates the same canvas as the registered one, and returns the pointer to the new canvas. NULL will be returned if none registered. fCopy The new canvas copies all drawn on the registered canvas, if this argument is TRUE. typedef void dwt->AnaglyphCanvas (DWTRMD_Canvas *cv); registers a canvas as the right canvas for anaglyph, with the one registered by RegisterCanvas being the left canvas. To register the right canvas is to enable anaglyph. That is, dwTerm takes the bitwise OR of the grayed versions of the canvases' images which are grayed by the left and right "graying colors", to update the display window, instead of simply copying the (left) canvas. Note that the left canvas size defines the area of the final image, and that only the intersection of the two canvases' is anaglyphed as above, with the other part in the final image being just the white- grayed version of the left canvas. In other words, a right canvas larger than the left is a waste, and you can make a non-anaglyph area simply by using a smaller canvas. A non-anaglyph image should be white-gray, to be neutral to the users' eyes wearing anaglyph glasses. Use AnaglyphColors described in the Display subsection in this reference to change the graying colors to be the same as the user's anaglyph glasses' colors. cv points to the canvas. NULL means to unregister, i.e. disable anaglyph. A valid pointer enables anaglyph, and gets the canvas suitable for OpenGL if the left canvas is so registered. typedef DWTRMD_Canvas* dwt->GetLeftCanvas (void); returns the pointer to the left canvas, or returns NULL if none registered. typedef DWTRMD_Canvas* dwt->GetRightCanvas (void); returns the pointer to the right canvas, or returns NULL if none registered. //*********************************************************************** // Drawing //*********************************************************************** typedef BOOL dwt->NewPaintingBox (int num); allocates an array to contain painting tools(' handles), freeing the previous array after deleting the tools in it. We call the array the "painting box". num the painting box (array) size, i.e. the maximum number of tools, so that a "valid" tool index is 0 to num-1 for num>0 typedef int dwt->GetPaintingBoxSize (void); returns the painting box size. typedef BOOL dwt->IsPaintingTool (int iTool); returns TRUE if iTool is valid and the tool exists, and returns FALSE otherwise. typedef BOOL dwt->FreePaintingTool (int iTool); deletes a tool in the painting box. Generally you don't have to use this function since dwTerm does when the tool needs to be deleted. You may use this function if your codes have calls of any function which does nothing if the tool is deleted, like PaintDot. iTool the tool index. The functions does nothing but returns FALSE if iTool is invalid, and returns the result of deleting otherwise. typedef BOOL dwt->NewBrush (int iTool, HBRUSH hBr); typedef BOOL dwt->NewPen (int iTool, HPEN hPen); typedef BOOL dwt->NewFont (int iTool, HFONT hFont); save a painting tool's handle into the painting box, as the iTool-th tool, deleting the previous tool with the same index. iTool the tool index. The functions does nothing but returns FALSE if iTool is invalid, and returns TRUE otherwise. hBr, hPen, hFont the Win32 GDI object handle, which can be obtained by Win32 functions like CreateSolidBrush. Do NOT delete the handle by the Win32 function DeleteObject. typedef BOOL dwt->SelectBrush (int iTool); typedef BOOL dwt->SelectPen (int iTool); typedef BOOL dwt->SelectFont (int iTool); select the iTool-th painting tool on the registered canvas, replacing the same kind of tool selected previously. After selecting tools. you can use Win32 drawing functions, for example Ellipse to draw a circle, with cv->hDC as the "device context handle" if cv is the registered canvas pointer. You don't have to try to "unselect", since dwTerm does such a thing when needed (i.e. before a tool is about to be deleted). iTool the tool index. The functions does nothing but returns FALSE if iTool is invalid, and returns TRUE otherwise. typedef BOOL dwt->SolidRect (RECT *rc, int iBr); paints a rectangle and inside it with a brush. iBr the tool index of the brush. The functions does nothing but returns FALSE if iBr is invalid or the brush is deleted, and returns the result of painting otherwise. typedef BOOL dwt->WireRect (RECT *rc, int iBr); draws a rectangle with a brush. iBr the tool index of the brush. The functions does nothing but returns FALSE if iBr is invalid or the brush is deleted, and returns the result of drawing otherwise. typedef BOOL dwt->PaintDot (int x, int y, int dx, int dy, int iBr); paints a rectangle and inside it with a brush. The rectangle location and size are specified instead of the pointer to a RECT. x, y, dx, dy constitute the rectangle RECT = {x, y, x+dx, y+dy} iBr the tool index of the brush. The functions does nothing but returns FALSE if iBr is invalid or the brush is deleted, and returns the result of drawing otherwise. typedef void dwt->Show (RECT *rc, int iBr); requests the display window to update an area, so that after the handler (in which this function is called) returns the window does it by pasting a gray color and copying the registered canvases. The function runs SolidRect before requesting. Note that multiple calls of the function in a handler accumulate the areas into the union. rc points to the rectangular area. If NULL, the area corresponding to the whole registered canvas is to be updated or the function does nothing if none registered. iBr the tool index of the brush for SolidRect

  7. 3D Programming

    This chapter describes structures and functions which initalize the OpenGL components in the operating system for you to only have to build 3D objects without knowing about the implementation of OpenGL in the system or about the camera and the viewport. Therefore beginners in OpenGL can take dwTerm as an easy toolkit, and examples help them know some basic modeling functions in OpenGL. dwTerm also has functions for anaglyph of this 3D drawing.

    This chapter also describes how to anaglyph 2D or 3D objects. The reference section in the previous chapter describes how to register a canvas as the second canvas so that the 2 canvases contain the left and the right images for anaglyph, and how to change the graying colors. This chapter is a tutorial with examples and has a reference about structures and functions to draw such images.

    Although structures and functions are designed to enable anaglyph, 3D without anaglyph is an easy subset. If you are not interested in anaglyph but only in OpenGL, ignore anything related to the right canvas when you read sections and source codes.

    1. Areas

      As defined in the reference section in this chapter, Area (DWTRMD_Area) is a useful structure for anaglyph. It has one more member "sep" than Win32 RECT, to represent the separation of the right image from the left. The goal is to draw in the rectangle in the left canvas, and to copy it to the rectangular region of the same size shifted by sep in the right canvas. The user feels the image on the screen for zero sep, between the screen and the user for a negative sep, and deep into the screen for a positive sep.

      In this manual, we sometimes call an Area as well as a RECT an "area", and are not afraid of confusion since we can depend on the contexts.

      The Load handler in anaglyph.c is drawing some anaglyph objects using areas after enabling anaglyph by calling AnaglyphCanvas to register the right canvas. It has the smaller height than that of the left canvas, so that the lower part of the display window is not anaglyphed and white-grayed.

      CopyArea() is an Area version of CopyCanvasRect() and initializes the target area to have the left canvas size with zero-depth (sep=0) for the NULL source pointer. ShowArea() is an Area version of Show(), and copies all in the RECT region on the left canvas to the same region shifted by sep on the right canvas as well as requesting the window to update both the reqions.

      There is an internal object called the "area stack" in dwTerm useful when many areas are to be used forming a hierarchy without naming each area. NewAreaStack() lets dwTerm allocate a stack of the specified maximum number of areas after freeing the previous one. Use PushArea() and PopArea() to save and read areas respectively. You may understand easily what the two functions do if you are familiar with the machine stack in assembly and the transformation matrix stack in OpenGL.

      You can set or change an area by accessing members directly with or without Win32 RECT functions, or by MoveArea() or other Area functions. MoveArea() is an Area version of Win32 OffsetRect(), which can move the area "to" and "from" the user as well as moving left, right, up and down. Note that such functions use "offset" as the argument rather than sep, the twice of it.

    2. Modeling

      The Load handler in the example model.c shows how to initialize the OpenGL components. The first to do is using TRUE as the second argument in RegisterCanvas(), to make the display window and the canvas be compatible with OpenGL.

      DWTRMD_View is the structure to understand the other steps in the example. The area member defines the region onto which OpenGL "prints" the "photograph" from the "camera". We don't care area.sep since the example does not anaglyph, and the handler initializes the area.rc by CopyCanvasRect() to use the whole canvas.

      The other members in View is about where and how to view in the 3D imaginary space. They are set by SetViewProjection() with the arguments' order the same as the members' order in the structure. If the first one fOrtho is TRUE, the orthogonal projection view (usual in the final CAD drawing with dimensions) is selected. If FALSE, the perspective projection (where distant objects look small) is selected. The other 4 float numbers are the width and the height of the 3D region when viewed by the camera, and the distances of the boundary planes near and far from the camera, respectively. For the perspective projection, the width and the height are those of the near plane.

      Note that the 3D region is symmetrical with respect to both the horizontal and vertical lines of the camera, and the two planes are perpendicular to the camera axis. Note also that the height/width ratio does not have to be the same as that of the Area member. It does, in this example, since we want objects to look with the same ratios as we build. Actually, the example is using the same size as the Area size to simplify the work. Using a new set of the 4 values (and the variables for modeling too) multiplied by 0.01 for example will produce the same result, since the 3D space xyz coordinates' unit is arbitary.

      BeginModel() called in the routine model() initializes OpenGL components according to the View. Note that the function locates the camera at the origin and directs it to look at the -z direction, so that +x points to the right, +y is upward and +z points to the user at the center of Area. After BeginModel() you can use OpenGL functions glXXX() or gluXXX() until EndModel() is called to let OpenGL draw the scene according to them.

      Refer to your OpenGL references to understand such functions, while the comments in model() and the next paragraphs may help you outline what they do. Note that you only have to and are recommended to, read about lights, objects (vertexes/lines/planes), modeling transformations and so on needed to build what you want in the 3D space with the camera fixed at the origin, since BeginModel() and EndModel() internally run OpenGL functions about viewport, camera, viewing transformations, projections and display lists for you to work without knowing about them and they can spoil what BeginModel() and EndModel() do.

      The modeling transformation is easy to understand if you imagine you are moved (translated, rotated, ...) with the coordinate system to build lights or objects in the system, while a friend in the previous system see you moved. That friend is the camera director if the previous system is the very one at the origin, and you are the executive director moving by the transformation to build somethings at various places and orientations.

      stereo.c, which is almost a combination of anaglyph.c and model.c to demonstrate an OpenGL programming with anaglyphing, shows where some functions can spoil what BeginModel() and EndModel() do. With the second argument TRUE, BeginModel() moves the camera to the -x direction, and EndModel() takes the "left" photo with that camera position and the "right" photo with a new position at the same distance from the origin to the +x direction. BeginModel() internally runs a viewing transformation function to move the camera, so that you are recommended, neither to use such function, nor to use glLoadIdentity() which resets the transformation matrix to be the identity matrix. (The identity matrix sends the camera and you the director back to the origin. That is, viewing and modeling transformations are all matrices to be multiplied into the "present" matrix, and the formers are just for realizing the notion of moving camera.)

      The last argument, zScreen is the distance of the "monitor screen" from the "user('s eyes)" in the virtual space, so that objects closer than it looks coming out of the monitor. BeginModel() and EndModel() use it and Area.sep to calculate the camera's offset from the origin to move it left and right as described in the previous paragraph. Objects at zScreen have zero separations, while closer and far objects have negative and positive values respectively, in the left and the right canvases.

    3. 3D Reference
      //*********************************************************************** // Areas //*********************************************************************** typedef struct { int sep; the distance of the right image from the left one RECT rc; the rectangular region to define the left image } DWTRMD_Area; typedef void dwt->SetArea (DWTRMD_Area *area, int offset, int left, int top, int right, int bottom); initializes an area. area points to the area. offset a half of the sep member left, top, right, bottom The function sets the rc member using these, and subtracts offset from the rc.left and rc.right members, so that the center of the rectangle defined by the argument coincides the mid point of the left and right regions. typedef void dwt->MoveArea (DWTRMD_Area *area, int doffset, int dx, int dy); shifts an area, by adding some amounts to members. area points to the area. doffset subtracts from the rc.left and rc.right members, and the twice of this adds to the sep member, so that the center of the left and right images remains unchanged with the separation increased. dx adds to the rc.left and rc.right members. dy adds to the rc.top and rc.bottom members. typedef int dwt->LandArea (DWTRMD_Area *area); makes the area to have zero separation, with the center of the left and right regions unchanged, so that the area "lands" on the monitor screen. The return value is half the previous separation. area points to the area. typedef void dwt->ShowArea (DWTRMD_Area *area, int iBr); copies all in the rectangle on the left canvas to the same region shifted by the sep member on the right canvas, and requests the window to update both the regions. If iBr is a valid tool id of a brush, the regions are painted by it. typedef DWTRMD_Area* dwt->CopyArea (DWTRMD_Area *areaDest, DWTRMD_Area *areaSrc); copies the source area structure to the target. areaDest points to the target area. The function returns this if it succeeded and NULL if failed. areaSrc points to the source area. If NULL, the target will be filled with the area structure corresponding to the entire left canvas with zero sep. typedef BOOL dwt->NewAreaStack (int num); allocates a new area stack, freeing the previous one. num the maximum number of areas that can be puhsed(memorized). typedef BOOL dwt->PushArea (DWTRMD_Area *area); typedef BOOL dwt->PopArea (DWTRMD_Area *area); pushes or pops an area respectively, i.e. writes to the i-th area or reads (unpush) from the (i-1)-th area in the stack if there are i-1 areas pushed. area points to the area structure to be pushed into or popped from the stack. //*********************************************************************** // Modeling //*********************************************************************** typedef struct { DWTRMD_Area area; The OpenGL camera "prints" the "photo" onto this area. BOOL fOrtho; TRUE and FALSE means the orthogonal and the perspective projections respectively. double width, height, zNear, zFar; The 3D region in the virtual space, to be viewed by the camera. It is symmetrical about the x, y, z axes of camera. If the Area is to have the realistic scene the height/width ratio should be the same as that of Area. We may sometimes make them different if we want distortions. The distances of the boundary planes near and far from the camera along the camera z axis are zNear and zFar respectively. } DWTRMD_View; typedef void dwt->SetViewProjection (DWTRMD_View *view, BOOL fOrtho, double width, double height, double zNear, double zFar); just initializes the view members except the area. typedef BOOL dwt->BeginModel (DWTRMD_View *view, BOOL fStereo, double zScreen); gets the camera ready to take the scene, for you to start building objects and lights using OpenGL functions. view points to the View according to which the camera is to be set. fStereo If FALSE, the camera is at the origin. If TRUE, it is moved to the left (i.e. the -x direction) from the origin. Unless view->area.sep is zero, you may use TRUE in order to anaglyph the 3D space. Sometimes you may use FALSE even for non-zero sep, since you must want to anaglyph the photo in that case like anaglyph.c zScreen The camera distance from the origin with fStereo TRUE, is calculated using view->Area.sep and this. This is the distance of a plane from the origin along the -z axis, where you want every point to have zero separation. typedef void dwt->EndModel (void); prints the scene onto the area in the (left) canvas. If there is the right canvas and fStereo was FALSE in BeginModel, the function further calls ShowArea just to copy the scene to the right canvas with the shift by View.area.sep, to make a "2D" anaglyph. For the right canvas and fStereo TRUE, the function takes and prints one more scene, after moving the camera to the right (i.e. the +x direction) so that the new position and the previous one are symmetric with respect to the origin, in order to make a 3D anaglyph. typedef DWTRMD_View* dwt->IsModeling (void); returns the pointer to the View if EndModel is not called after BeginModel called. Otherwise, NULL is returned.

  8. More about Programming

    1. Stop

      The example debug.c demonstrates the Stop feature. It is enabled by EnableStop(), and then a message box pops up when the Command handler returns a message containing a string. When the first argument for the string pointer is NULL, the box will pop up anyway even when the handler returns NULL. In this example the box pops up as long as the handler returns a non-null string pointer. This feature is useful when the user is editing a long script and wants to find where is wrong. You can provide the user a command to enable Stop and the user can insert the "stop" command in the script around suspicious commands. The feature can be used also when the status bar is thought to be insufficient to inform the user of a message.

    2. Command Reference
      //*********************************************************************** // Stop //*********************************************************************** typedef void dwt->EnableStop (char *str, char *title, char *text); enables the Stop feature which pops up a "stop" box when the Command handler returns a special string pointer. The box has 3 buttons. All the buttons close the box, but the next state becomes different. The Yes button maintains the Stop enabled and the No button disables it. The Cancel button not only disables but also stop scripting if was running. str If this is NULL, the box pops up whenever the handler returns. If it points to a valid NULL-terminated string, the box pops up only when the handler returns a string which includes the string. For example, if str="ab", the box pop up when the handler returns "1234ab89". title, text The title and the content of the box respectively. If NULL, the default ones are used, as in the "debug" example. typedef void dwt->DisableStop (void); disables the Stop feature. typedef BOOL dwt->CanStop (void); returns TRUE if the Stop is enabled, and FALSE if disabled. typedef char* dwt->GetStopString (void); typedef char* dwt->GetStopTitle (void); typedef char* dwt->GetStopText (void); return the pointers specified by str, title and text arguments in EnableStop.

  9. Limits of Trial Version

    The following paragraphs list the trial version's limits. They will disappear if you install a full license key.

    Only the first 20 commands in a script file are run and the others are ignored. More commands lets dwTerm issue a modal box saying they are ignored, after scripting.

    Anaglyphing is bound to the top-left 400x300 region and the other parts in the display window to be anaglyphed are just painted black.

    The trial version also has a small additional area in the main window to display advertising pictures. If the computer is connected to the internet, new pictures may be displayed.

  10. License Agreement

    Please read Agree.txt.

  11. History

    • Version 2.3: Apr 27, 2012

      New API group "Inputs and Outputs" is added

      One more output display window, i.e. a multi-line text window is added, which can be used instead of the graphics window. New 4 functions related with it, i.e., ShowDisplay, Print, Printf, and GetTextDisplay are added to the API group "Display".

      The strip command is added to each example's link.bat. New examples are added: count, diffeqn.

      This manual and the API header dwterm.h are reorganized.

      Bugs related to the window size are removed.

    • Version 2.1: May 16, 2011

      The installer and the uninstaller are included.

      A new menu Setup is added, which have 2 submenus named System Folder and Start Folder, to help install DLLs and shortcuts.

      The check-control in the Option->Editor menu's box is removed. The option is not useful since scripts(*.dsc) are associated with dwTerm by the installer now.

      The fonts are changed.

      A bug in loading a file by association (for example when double clicking it), and other bugs in routines for sub-title and for Area-Stack, are removed.

      The product is modularized, the result of which, the new file softbatt.dll gets installed into the system folder.

      The Load handler's argument CmdLine gets reserved. That is, developers should not use it. The codes in dwTerm for it are removed. New usages can be suggested in the future.

    • Version 2.0: Oct 29, 2009

      The Start and End handlers, and all the API functions gets obsolete, although they still remains to run old DLLs. If the old v1.0 handlers are not found in a DLL, dwTerm search for new handlers, "Load" and "Unload". A new group of functions and related examples are provided and can be summarized into the following 6 sets.

      The display window size can be specified and can be fixed. The window is capable of anaglyph and the 2 colors can be specified.

      The canvas functions are easier than old ones. Furthermore, one more canvas can be registered, as the second or "right" canvas, with the first one being the "left" canvas, in order for the window to compose an anaglyph image.

      The concept of the painting box and related functions are provided to help programmers use the painting tools (brushs, pens, fonts) without knowing much about maintaining, deleting, or selecting those Win32 GDI objects in relation with the canvas.

      The Area structure and its stack are suggested and related functions are provided, to make it easy to draw the left and the right images for anaglyph.

      The View structure and related functions let the programmers to call OpenGL functions to build objects and lights, without knowing about initializing OpenGL components including the camera. The functions can also anaglyph the 3D scene by shifting the camera.

      The Stop functions gets the programmers capable of providing users with script-debugging commands.

      The v1.0 handler-scheme and functions still remaining, DLLs programmed for v1.0 works well with this version, except the status bar names the old hadlers by new ones.

    • Version 1.0: Jan 11, 2008