Function Index

Between the game code and the C library routines used by the game code, there are 152 functions defined and documented in this project. This is a centralized, alphabetical (A–Z, a–z) index of all of these functions, their definitions, a brief description of their purpose, and a link to the page section that describes each in greater detail.


AdLibService()

void AdLibService(void);

Streams chunks of music data to the AdLib hardware at the appropriate time.


AnimatePalette()

void AnimatePalette(void);

Cycles through any palette animations that have been requested by the map.


ClearScreen()

void ClearScreen(void);

Overwrites the EGA memory for the current draw page with solid black tiles.


CopyTilesToEGA()

void CopyTilesToEGA(byte *source, word dest_length, word dest_offset);

Reads solid tile image data from the memory pointed to by source, and installs it into a block of dest_length bytes of the EGA’s memory starting at dest_offset. Because the destination memory is planar, each byte of address space covered by dest_length consumes four bytes from source.


DRAW_SOLID_TILE_XY()

#define DRAW_SOLID_TILE_XY(src, x, y) { DrawSolidTile((src), (x) + ((y) * 320)); }

Wraps a call to DrawSolidTile(), converting x and y tile coordinates into the linear offset form expected by that function.


DetectAdLib()

bool DetectAdLib(void);

Interrogates the default AdLib I/O address to check if one is installed, and initializes the hardware if it is there. Returns true if an AdLib is installed, and false otherwise.


DrawCartoon()

void DrawCartoon(byte frame, word x_origin, word y_origin);

Draws a cartoon having the provided frame number, with the lower-left tile at coordinates (x_origin, y_origin).


DrawFullscreenImage()

void DrawFullscreenImage(word image_num);

Loads and displays the full-screen image identified by image_num, fading the screen contents between what has already been drawn and the new image. If the requested image_num is anything other than IMAGE_TITLE or IMAGE_CREDITS, any playing music is stopped.


DrawFullscreenText()

void DrawFullscreenText(char *entry_name);

Draws a page of B800 text to the screen and clears space for the DOS prompt.


DrawMainMenu()

void DrawMainMenu(void);

A small helper that draws the main menu frame and text, but does not do any input handling. It is only called from TitleLoop().


DrawMaskedTile()

void DrawMaskedTile(byte *src, word x, word y);

Copies an 8x8 pixel masked tile from the byte pointer src minus 16,000 to the video memory tile location identified by column x and row y.


DrawNumberFlushRight()

void DrawNumberFlushRight(word x_origin, word y_origin, dword value);

Draws a numeric value with the rightmost (least significant) digit anchored at screen coordinates (x_origin, y_origin). value is interpreted as an unsigned long integer.


DrawPlayer()

void DrawPlayer(byte frame, word x_origin, word y_origin, word mode);

Draws a player sprite having the provided frame number, with the lower-left tile at coordinates (x_origin, y_origin).


DrawScancodeCharacter()

void DrawScancodeCharacter(word x, word y, byte scancode);

Draws a single-character representation of scancode at screen tile position (x, y).


DrawSolidTile()

void DrawSolidTile(word src_offset, word dst_offset);

Copies an 8x8 pixel solid tile from the tile storage area byte offset src_offset to the video memory byte offset dst_offset. Both offsets refer to locations within the EGA’s memory space. The EGA hardware must be in “latched write” mode for this function to work correctly.


DrawSprite()

void DrawSprite(word sprite, word frame, word x_origin, word y_origin, word mode);

Draws a sprite of the provided sprite type and frame, with the lower-left tile at coordinates (x_origin, y_origin). The mode influences the origin calculations and visual appearance.


DrawSpriteTile()

void DrawSpriteTile(byte *src, word x, word y);

Copies an 8x8 pixel masked tile from the byte pointer src to the video memory tile location identified by column x and row y.


DrawSpriteTileFlipped()

void DrawSpriteTileFlipped(byte *src, word x, word y);

Copies a vertically-flipped 8x8 pixel masked tile from the byte pointer src to the video memory tile location identified by column x and row y.


DrawSpriteTileTranslucent()

void DrawSpriteTileTranslucent(byte *src, word x, word y);

Copies a translucent outline of an 8x8 pixel masked tile from the byte pointer src to the video memory tile location identified by column x and row y.


DrawSpriteTileWhite()

void DrawSpriteTileWhite(byte *src, word x, word y);

Copies a solid white outline of an 8x8 pixel masked tile from the byte pointer src to the video memory tile location identified by column x and row y.


DrawTextFrame()

word DrawTextFrame(word left, word top, int height, int width, char *top_text, char *bottom_text, bbool centered);

Draws an empty text frame to the current draw page with the upper-left corner at tile position (left, top) and a total size of width x height tiles. The top and bottom edges of the frame are prefilled with top_text and bottom_text respectively, aligned according to the centered flag. Returns the X tile coordinate of the inside-left edge of the frame.


DrawTextLine()

void DrawTextLine(word x_origin, word y_origin, char *text);

Draws a single line of text with the first character anchored at screen coordinates (x_origin, y_origin). A limited form of markup is supported to allow insertion of cartoon images, player/actor sprites, and text animation effects.


EGA_BIT_MASK_DEFAULT()

#define EGA_BIT_MASK_DEFAULT() { outport(0x03ce, (0xff << 8) | 0x08); }

Resets the EGA’s bit mask to its default state.


EGA_MODE_DEFAULT()

#define EGA_MODE_DEFAULT() { outport(0x03ce, (0x00 << 8) | 0x05); }

Resets the EGA’s read and write modes to their default state.


EGA_MODE_LATCHED_WRITE()

#define EGA_MODE_LATCHED_WRITE() { outport(0x03c4, (0x0f << 8) | 0x02); outport(0x03ce, (0x01 << 8) | 0x05); }

Resets the EGA’s map mask to its default state and enables latched writes from the CPU.


EraseWaitSpinner()

void EraseWaitSpinner(word x, word y);

Erases an area previously occupied by a wait spinner by drawing a tile of solid dark gray at screen tile position (x, y).


ExitClean()

void ExitClean(void);

Cleans up game state and exits back to DOS.


FadeIn()

void FadeIn(void);

Calls FadeInCustom() with a fixed delay of three game ticks per palette entry.


FadeInCustom()

void FadeInCustom(word delay);

“Fades” the screen image into view by rebuilding the EGA’s default palette, one entry at a time, pausing delay game ticks between each entry.


FadeOut()

void FadeOut(void);

Calls FadeOutCustom() with a fixed delay of three game ticks per palette entry.


FadeOutAdLibPlayback()

void FadeOutAdLibPlayback(void);

Nominally fades any playing music to silence over a period of time, but as implemented it simply cuts the music off immediately.


FadeOutCustom()

void FadeOutCustom(word delay);

“Fades” the screen image away by incrementally blanking the EGA’s palette to black, one entry at a time, pausing delay game ticks between each entry.


FadeToWhite()

void FadeToWhite(word delay);

“Fades” the screen image away by incrementally blanking the EGA’s palette to white, one entry at a time, pausing delay game ticks between each entry.


GetProcessorType()

word GetProcessorType(void);

Tests the system processor and returns a value indicating its model. Returns CPUTYPE_*.


GroupEntryFp()

FILE *GroupEntryFp(char *entry_name);

Returns a file stream pointer to the data that a group file’s entry_name refers to.


GroupEntryLength()

dword GroupEntryLength(char *entry_name);

Locates a group file entry_name and returns the size of its data in bytes.


InitializeInterruptRate()

void InitializeInterruptRate(void);

Sets up the system timer interrupt rate depending on whether or not the AdLib hardware is enabled.


InnerMain()

void InnerMain(int argc, char *argv[]);

Main game function, once CPU testing has passed.


IsAdLibAbsent()

bbool IsAdLibAbsent(void);

Returns TRUE if an AdLib or compatible card was NOT detected in the system.


IsAnyKeyDown()

bbool IsAnyKeyDown(void);

Returns true if any key is currently pressed, without regard to which key it is.


JoinPath()

char *JoinPath(char *dir, char *file);

Combines a string dir with a string file, creating and returning an absolute pathname.


KeyboardInterruptService()

void interrupt KeyboardInterruptService(void);

Maintains the state of the keyboard variables. Called in response to the keyboard interrupt event.


LightenScreenTile()

void LightenScreenTile(word x, word y);

Lightens the entire area at the video memory tile location identified by column x and row y.


LightenScreenTileEast()

void LightenScreenTileEast(word x, word y);

Lightens the lower-left half of an 8x8 tile at the video memory tile location identified by column x and row y.


LightenScreenTileWest()

void LightenScreenTileWest(word x, word y);

Lightens the lower-right half of an 8x8 tile at the video memory tile location identified by column x and row y.


LoadActorTileData()

void LoadActorTileData(char *entry_name);

Loads actor tile data into system memory.


LoadCartoonData()

void LoadCartoonData(char *entry_name);

Loads the cartoon masked tile image data from the group file entry_name.


LoadConfigurationData()

void LoadConfigurationData(char *filename);

Loads and parses the contents of the configuration file named filename into several global variables.


LoadDemoData()

void LoadDemoData(void);

Copies the data from the PREVDEMO.MNI group file entry into system memory.


LoadFontTileData()

void LoadFontTileData(char *entry_name, byte *dest, word length);

Loads font data into system memory.


LoadGroupEntryData()

void LoadGroupEntryData(char *entry_name, byte *dest, word length);

Reads data from an entry_name inside a group file and stores it in the memory block pointed to by dest. length controls how much data is copied.


LoadInfoData()

void LoadInfoData(char *entry_name, word *dest, word length);

Reads a group file entry_name containing “info” data into the memory block pointed to by dest.


LoadMaskedTileData()

void LoadMaskedTileData(char *entry_name);

Loads data from the group file entry named entry_name and stores it in the masked tile data block.


LoadMusicData()

Music *LoadMusicData(word music_num, Music *dest);

Opens music data from a group file entry (whose name is indexed by a numerical music_num), loads the data into the Music structure pointed to by dest, and prepares the AdLib service to receive new music data. Returns a pointer to dest.


LoadSoundData()

void LoadSoundData(char *entry_name, word *dest, int skip);

Reads data from the group file entry named by entry_name and stores it in the dest memory block along with index structures.


LoadTileAttributeData()

void LoadTileAttributeData(char *entry_name);

Loads data from the group file entry named entry_name and stores it in the tile attribute data block.


MK_FP()

#define MK_FP(seg, ofs) \
    ((void far *) (((unsigned long)(seg) << 16) | (unsigned)(ofs)))

Makes a far pointer from its component segment (seg) and offset (ofs) parts.


PCSpeakerService()

void PCSpeakerService(void);

Sends a new fragment of sound effect data to the PC speaker.


ProfileCPU()

void ProfileCPU(void);

Measures the execution speed of the CPU relative to the system’s Programmable Interval Timer, and records the number of busy loop iterations the CPU requires to generate various delay times.


ProfileCPUService()

void interrupt ProfileCPUService(void);

Benchmarks the timing characteristics of the CPU relative to the system’s Programmable Interval Timer.


PromptKeyBind()

bbool PromptKeyBind(byte *target_var, word x, char *message);

Displays message text at the provided x position (and a fixed Y position) on the screen and reads a single scancode into the memory pointed to by target_var. Returns true if the user pressed the Esc key and false for all other keys.


PromptLevelWarp()

bbool PromptLevelWarp(void);

Prompts the user to select a map number from 1 to 12 (or 13, depending on the episode) and jumps to the start of the chosen map. Returns true if the map changed, or false if the user entered a non-numeric or out-of-range value.


PromptQuitConfirm()

bbool PromptQuitConfirm(void);

Displays a window prompting the user to confirm their intention to quit, and blocks until a key is pressed. The return value is true if the Y key was pressed, or false in the case of any other key.


PromptRestoreGame()

byte PromptRestoreGame(void);

Displays a menu that prompts the user to pick a save game slot (1-9) to load from, and gameplay jumps to that state. The user may cancel this prompt without loading by pressing Esc, Space, or Enter. The return value is one of the RESTORE_GAME_* constants.


PromptSaveGame()

void PromptSaveGame(void);

Displays a menu that prompts the user to pick a save game slot (1-9) to save the state of their game into, then the save is carried out. The user may cancel this prompt without saving by pressing Esc, Space, or Enter.


ReadAndEchoText()

void ReadAndEchoText(word x_origin, word y_origin, char *dest, word max_length);

Presents a wait spinner near (x_origin, y_origin) that accepts at most max_length characters of keyboard input. The typed characters are echoed to the screen and stored in the memory pointed to by dest, which should be large enough to hold max_length + 1 bytes of data.


ReadDemoFrame()

bbool ReadDemoFrame(void);

Reads the next byte from the demo data and updates the global input command state. Returns true on end of data.


ReadJoystickState()

JoystickState ReadJoystickState(word stick);

Polls the joystick identified by stick for its current position and button state, and updates the player control variables accordingly.


ReadJoystickTimes()

void ReadJoystickTimes(word stick, int *x_time, int *y_time);

Triggers a timing interval on the joystick hardware and returns the raw interval lengths for the one joystick, identified by stick, in x_time and y_time.


SaveConfigurationData()

void SaveConfigurationData(char *filename);

Saves the state of the global game configuration variables to the configuration file named filename.


SaveDemoData()

void SaveDemoData(void);

Flushes all of the in-memory demo data to the PREVDEMO.MNI file on disk – it does not modify any group file contents.


SelectActivePage()

void SelectActivePage(word page_num);

Switches the actively-displayed video memory page to page_num, causing its contents to appear on the screen, using a BIOS interrupt call.


SelectDrawPage()

void SelectDrawPage(word page_num);

Changes the draw page to page_num and updates the memory address that subsequent drawing procedures should operate on.


SetAdLibRegister()

void SetAdLibRegister(byte addr, byte data);

Writes one data byte to the AdLib register at address addr, assuming the hardware is present at the standard I/O ports.


SetBorderColorRegister()

void SetBorderColorRegister(word color_value);

Configures the display adapter to use color_value to fill the overscan area at the edges of the screen, using a BIOS interrupt call.


SetInterruptRate()

void SetInterruptRate(word ints_second);

Configures channel 0 of the system’s Programmable Interval Timer with an interrupts-per-second value specified by ints_second.


SetMusic()

bool SetMusic(bool state);

Enables or disables AdLib output based on the value of state.


SetPIT0Value()

void SetPIT0Value(word value);

Configures channel 0 of the system’s Programmable Interval Timer with the provided counter value.


SetPaletteRegister()

void SetPaletteRegister(word palette_index, word color_value);

Configures the display adapter to use color_value as the screen display color at positions where the video memory contains palette_index, using a BIOS interrupt call.


SetVideoMode()

void SetVideoMode(word mode_num);

Changes the system’s video mode to the mode number specified by mode_num, using a BIOS interrupt call.


ShowGameRedefineMenu()

void ShowGameRedefineMenu(void);

Shows a menu labeled “Game Redefine” in response to the user selecting the G option in either the main menu or the in-game help menu. This function simply dispatches one of the submenu functions in response to the user’s input.


ShowHelpMenu()

byte ShowHelpMenu(void);

Shows a menu labeled “Help Menu” in response to the user pressing F1 during the game. It gives access to save/restore functions and a subset of options offered by the main menu. Returns one of the HELP_MENU_* variables.


ShowHighScoreTable()

void ShowHighScoreTable(void);

Shows the top ten scores that have been reached and the name of the player who earned each spot. The table can optionally be erased by pressing the F10 key and confirming with the Y key.


ShowJoystickConfiguration()

void ShowJoystickConfiguration(word stick);

Prompts the user to calibrate the joystick timings and button configuration for the joystick identified by stick.


ShowKeyboardConfiguration()

void ShowKeyboardConfiguration(void);

Shows and handles the keyboard configuration (sometimes called keyboard redefine) menu.


ShowSoundTest()

void ShowSoundTest(void);

Presents a menu that allows the user to seek through and preview each sound effect available in the game.


StartAdLib()

void StartAdLib(void);

Detects and initializes the AdLib hardware if it is present, installs the interrupt handler necessary to run the AdLib and PC speaker services, and measures values for CPU-based time delays.


StartAdLibPlayback()

void StartAdLibPlayback(void);

Sets the enableAdLib variable to true, permitting the AdLib service to play music.


StartGameMusic()

void StartGameMusic(word music_num);

Starts playing the music identified by the numeric music_num if the AdLib hardware is available. This function is only safe to use while gameplay is occurring.


StartMenuMusic()

void StartMenuMusic(word music_num);

Starts playing the music identified by the numeric music_num if the AdLib hardware is available. This function is only safe to use on the title screens, main menu, and its submenus.


StartSound()

void StartSound(word sound_num);

Queues the new sound effect identified by sound_num for playback and immediately returns.


Startup()

void Startup(void);

Initializes the game environment and shows pre-title/copyright screens.


StepPalette()

void StepPalette(byte *pal_table);

During each frame of gameplay, steps through each element of the passed palette table pal_table and sets the palette key color accordingly, repeating once the END_ANIMATION marker has been reached.


StepWaitSpinner()

byte StepWaitSpinner(word x, word y);

Draws one frame of the wait spinner, immediately returning the most recent scancode seen by the keyboard hardware (even if that scancode is stale).


StopAdLib()

void StopAdLib(void);

Stops all playback from the AdLib card and restores the original system timer interrupt handler.


StopAdLibPlayback()

void StopAdLibPlayback(void);

Clears all the AdLib parameter values that could produce note sounds.


StopMusic()

void StopMusic(void);

Silences any active music and prevents the AdLib service from processing any new chunks of music.


SwitchMusic()

void SwitchMusic(Music *music);

Stops any currently playing music and starts playing the music specified by music.


TimerInterruptService()

void interrupt TimerInterruptService(void);

Handles interrupts that occur on interrupt vector 8 (IRQ 0), which is wired to channel 0 of the system’s Programmable Interval Timer. Each time the timer ticks, this function updates the sounds being played by the PC speaker and/or the AdLib.


TitleLoop()

byte TitleLoop(void);

Runs at the start of the program and is responsible for showing the title screen, credits, demo, and main menu. Additionally, this function reads the keyboard input for the main menu selection and calls the appropriate function in response. Returns one of the DEMOSTATE_* variables.


UnfoldTextFrame()

word UnfoldTextFrame(int top, int height, int width, char *top_text, char *bottom_text);

Draws an animated, empty text frame to the current draw page with the top edge at tile position top and a total size of width x height tiles. The top and bottom edges of the frame are prefilled with top_text and bottom_text respectively. The frame and its top/bottom texts are always centered horizontally on the screen. The return value is the X tile coordinate of the left edge of the inner text area.


UpdateDrawPageSegment()

void UpdateDrawPageSegment(void);

Recalculates the segment address of the video memory where drawing should occur.


ValidateSystem()

void ValidateSystem(void);

Ensures the system has an EGA adapter, and verifies there is enough free memory. If either are not true, exits back to DOS.


WaitForAnyKey()

byte WaitForAnyKey(void);

Waits indefinitely for any key to be pressed and released, then returns the scancode of that key.


WaitHard()

void WaitHard(word delay);

Pauses execution for delay game ticks with no provision for the user to skip the wait.


WaitSoft()

void WaitSoft(word delay);

Pauses execution for delay game ticks, returning early if the user presses a key.


WaitSpinner()

byte WaitSpinner(word x, word y);

Draws a rotating green icon at tile position (x, y) on the screen, blocking until a key is pressed. Once that occurs, the scancode of the pressed key is returned.


WaitWallclock()

void WaitWallclock(word loops);

Creates an artificial delay using a CPU busy loop, controlled by the iteration count specified in loops.


WriteDemoFrame()

bbool WriteDemoFrame(void);

Captures a snapshot of the global input command state (from the keyboard or joystick) and encodes it into a stream of demo data bytes. Returns true on error.


atoi()

int atoi(const char *s);

Interprets an integer value in a byte string pointed to by s.


coreleft()

unsigned long coreleft(void);

Returns a measure of RAM memory not in use.


disable()

void disable(void);

Disables hardware interrupts.


enable()

void enable(void);

Enables hardware interrupts, allowing any device interrupts to occur.


exit()

void exit(int status);

Causes normal program termination to occur.


farmalloc()

void far *farmalloc(unsigned long nbytes);

Allocates a block of memory nbytes bytes long from the far heap.


fclose()

int fclose(FILE *stream);

Closes the given file stream. Returns 0 on success, EOF otherwise.


feof()

int feof(FILE *stream);

Checks if the end of the given file stream has been reached.


ferror()

int ferror(FILE *stream);

Checks the given stream for errors.


fgetc()

int fgetc(FILE *stream);

Reads the next character from the given input stream.


filelength()

long filelength(int handle);

Returns the length (in bytes) of the file associated with handle.


fileno()

#define fileno(f) ((f)->fd)

Returns the file handle for the given stream.


fopen()

FILE *fopen(const char *path, const char *mode);

Opens a file indicated by path and returns a pointer to the file stream associated with that file. mode is used to determine the file access mode.


fprintf()

int fprintf(FILE *stream, const char *format, ...);

Loads the data from the given locations, converts them to character string equivalents and writes the results to the output stream stream.


fputc()

int fputc(int c, FILE *stream);

Writes a character c to the given output stream stream.


fread()

size_t fread(void *ptr, size_t size, size_t n, FILE *stream);

Reads up to n objects into the array ptr from the given input stream stream as if by calling fgetc() size times for each object, and storing the results, in the order obtained, into the successive positions of ptr, which is reinterpreted as an array of unsigned char. Returns the number of objects read successfully.


fscanf()

int fscanf(FILE *stream, const char *format, ...);

Reads the data from file stream stream, interprets it according to format and stores the results into given locations.


fseek()

int fseek(FILE *stream, long offset, int whence);

Sets the file position indicator for the file stream stream to the value pointed to by offset.


fwrite()

size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream);

Writes n of objects from the given array ptr to the output stream stream. The objects are written as if by reinterpreting each object as an array of unsigned char and calling fputc() size times for each object to write those unsigned chars into stream, in order.


getch()

int getch(void);

Reads a single character directly from the console (keyboard), without echoing to the screen.


getvect()

void interrupt (*getvect(int interruptno))();

Reads the value of the interrupt vector given by interruptno and returns that value as a far pointer to an interrupt function.


getw()

int getw(FILE *stream);

Returns the next integer (machine word) in the named input stream. It assumes no special alignment in the file.


inportb()

unsigned char inportb(int portid);

Reads a byte from the hardware I/O port specified by portid.


int86()

int int86(int intno, union REGS *inregs, union REGS *outregs);

Executes an 8086 software interrupt specified by the argument intno.


main()

void main(int argc, char *argv[]);

Main entry point for the program.


malloc()

void *malloc(size_t size);

Allocates size bytes of uninitialized storage.


memmove()

void *memmove(void *dest, const void *src, size_t n);

Copies n characters from the object pointed to by src to the object pointed to by dest.


movmem()

void movmem(void *src, void *dest, unsigned length);

Copies a block of length bytes from src to dest.


outport()

void outport(int portid, int value);

Writes the word given by value to the hardware I/O port specified by portid.


outportb()

void outportb(int portid, unsigned char value);

Writes the byte given by value to the hardware I/O port specified by portid.


printf()

int printf(const char *format, ...);

Loads the data from the given locations, converts them to character string equivalents and writes the results to the output stream stdout. Returns the number of characters transmitted to the output stream or negative value if an error occurred.


putw()

int putw(int w, FILE *stream);

Outputs the integer w (machine word) to the given stream.


rand()

int rand(void);

Returns a pseudo-random integer value between 0 and RAND_MAX (0 and RAND_MAX included).


random()

#define random(num) (rand() % (num))

Returns a random number between 0 and (num - 1).


remove()

int remove(const char *path);

Deletes the file identified by character string pointed to by path.


setvect()

void setvect(int interruptno, void interrupt (*isr)());

Sets the value of the interrupt vector named by interruptno to a new value, isr, which is a far pointer containing the address of a new interrupt function.


sprintf()

int sprintf(char *buffer, const char *format, ...);

Loads the data from the given locations, converts them to character string equivalents and writes the results to a character string buffer.


strcpy()

char strcpy(char *dest, const char *src);

Copies the null-terminated byte string pointed to by src, including the null terminator, to the character array whose first element is pointed to by dest.


strlen()

size_t strlen(const char *s);

Returns the length of the given null-terminated byte string, that is, the number of characters in a character array whose first element is pointed to by s up to and not including the first null character.


strncmp()

int strncmp(const char *s1, const char *s2, size_t maxlen);

Compares at most maxlen characters of two possibly null-terminated arrays.


strupr()

char *strupr(char *s);

Converts lowercase letters (az) in string s to uppercase (AZ). No other characters are changed.


textmode()

void textmode(int newmode);

Selects a specific screen text mode.


ultoa()

char *ultoa(unsigned long value, char *string, int radix);

Converts value to a null-terminated string and stores the result in string.