home *** CD-ROM | disk | FTP | other *** search
-
- ┌──────────────────────────────────────────────┐
- │ MOTOR CITY SOFTWARE │
- │ ┌──────────────────────────────────────┐ │
- │ │ JPDoor - Version 3.1 SE │ │
- │ │ Copyright 1990 - 1992 │ │
- │ │ ┌──────────┐ │ │
- │ │ │\ │ │ │
- │ │ │ \ │ │ │
- │ │ │ \ P │ │ │
- │ │ │ \ A │ │ │
- │ │ │ │ S │ │ │
- │ │ │ │ C │ │ │
- │ │ 5.5 │ │ A │ 6.0 │ │
- │ │ │ o│ L │ │ │
- │ │ │ │ │ │ │
- │ │ \ │──────┘ │ │
- │ │ \ │ │ │
- │ └──────────────\ │─────────────────────┘ │
- │ The Ultimate \│ Door Writing Unit. │
- └────────────────────┴─────────────────────────┘
-
-
-
- This file contains information on writing doors that work in a multi-node
- environment. While your door may not be multi-player, we would recommend
- that you read over the following information anyways.
-
-
- With the number of Multi-Node BBS's steadily increasing, we felt it was
- very important to make it easy on the programmer to make his doors multi-
- node aware. This release of JPDoor has many new features that make it easy
- to write programs which work in a multi-node environment, even if you are
- not running multi-node yourself. We have taken this one step further, in
- that you can easily write doors which allow players to compete head-to-head!
-
- While some of this may sound complex, it really is quite simple.
-
- JPDoor will only allow multi-player games on RemoteAccess V 1.xx and
- QuickBBS V 2.75. Future versions will also include full support for PCBoard.
- SHARE MUST BE LOADED!
-
- Some of the multi-node capabilities included are:
-
- - Listing Other Users Currently Online
- - Sending Online Messages to other users
- - Determining the node number that the current user is logged onto
- - Determining who is logged onto other nodes
- - File/Record locking routines so your door can run on more than one node
- at a time
- - A method to ensure that your door is only run on one node at a time if
- need be
- - The ability for two nodes to pass data back and forth
-
- This document is going to try to explain how to write a door which allows
- two players, and passes game data back and forth between them. These
- routines have been tested extensively, and while they appear to be working
- fine, there exists a possibility that there are systems which may have
- problems. Because of this, we will be working closely with anyone having
- problems. If problems are discovered, then beta versions will be made
- available to any registered user who requests it.
-
-
- To start with, some basic concepts...
-
- Multi-player doors will only work with QBBS 2.75 or RA 1.xx
- All data is passed in a file called JPDOOR.USE which will be
- created in the system directory pointed to by either the RA
- or QUICK environment variable.
-
- JPDoor has defined the structure for this file as follows:
-
- TYPE
- JPUseData = Array[1..2048] of Byte;
- JPUSErecord = record
- Name : String[35];
- Line : Byte;
- DoorName : String[20];
- Status : Byte;
- MaxPlayers : Byte;
- Filler : Array[1..13] of byte;
- MultiNode : Boolean;
- PID : Integer;
- Data : JPUseData;
- End;
-
- { Status Byte : 0 - New Record Added }
- { 1 - New Data Written }
- { 2 - Data Has Been Read }
-
- Var
- JPUse : JPUseRecord; { Variable to hold MY record}
- JPUseOther : JPUseRecord; { Variable to hold OTHER users record }
-
- Lets look at each field :
-
- Name - This is the name of the user currently online
-
- Line - This is the node number the user is on. This does
- not default to 1 like the dorinfo1.def does, and you
- can get the users node with the function GetNode.
- GetNode will simply search USERON.BBS for the users
- name as defined in dorinfo1.def, and return the actual
- node he is loggend onto.
-
- DoorName - This is the name of your door. Its best to keep this to
- 15 characters or less. When JPDoor's Whoson procedure is
- called, it will display this so other users can see that
- your door is in use.
-
- Status - This is used internally, and you need not worry about it.
- The following values are used :
- 0 - New Record Added
- 1 - New Data Written
- 2 - Data Has Been Read
-
- MaxPlayers - This contains the maximum number of users who can play
- at one time. Currently, JPDoor will only support 2
- players, but this will be increased in future versions.
-
- MultiNode - True if your door allows more than one user to run the
- door at the same time.
-
- PID - If your Door is a multi-player door, then you MUST apply
- for a Product ID code. You must be registered in order
- to receive one. In order to test your door, use a PID of
- 0. If you attempt to use any other value, it will abort!
-
- Data - This is where all the data is passed back and forth between
- two nodes. This is explained in detail below.
-
-
- A note about PIDs.
- The PID is used to ensure that you only try to read data
- written by YOUR door on another node. You dont want a
- battleship door reading a data file from an X's and O's
- door etc... The PID is validated internally by JPDoor.
- The Value of 0 is for test purposes only, as we do not
- want to force you to register BEFORE you can test it.
- If you release a multi-player door using a 0 for a PID,
- then you run the risk of it conflicting with other doors!
- You will need a PID for each and every different multi-
- player game you write.
-
- There is no fee for registering a PID, and there is no
- limit to the number of PIDs you may register, but you
- must be a registered user of JPDoor.
-
- PID 0 is ONLY for testing purposes, and you are expected
- to register JPDoor and request a PID BEFORE you release
- your door.
-
-
- How it all works.
-
-
- First, you need to decide what data you wish to pass back and forth.
- Define a structure that is exactly 2048 bytes in size. An example
- from my BattleShips door follows:
-
- TYPE
- Grid = Array[1..9,0..9] of Char; { Letter,Number }
-
- NodeData = Record
- Status : Byte;
- PlayerName : String[25];
- SeaGrid : Grid;
- ShotN,
- ShotL : Byte;
- ShipHits : Array[1..6] of byte;
- ChatLine : String[78];
- Local : Boolean;
- Filler : Array[1..1843] of Byte; {this is added to ensure that}
- { the record is exactly 2048 }
- { bytes in length}
- End;
-
-
- Once you have defined this structure, you need to be able to reference
- it two ways. You need to be able to modify each field, and also be
- able to reference it within the JPUseRecord. This is accomplished by
- using pointers.
-
- You must also remember that you need to reference YOUR nodes data, as
- well as the OTHER nodes data.
-
-
- Var
- JPD : JPUseData; { MY nodes Data as a field in JPUseRecord}
- OJPD : JPUseData; { OTHER nodes data as a field in JPUseRecord}
- NDPtr : ^NodeData; { My Nodes Data a I defined it}
- ONDPtr : ^NodeData; { Other nodes data as I defined it}
-
-
- Now JPD and OJPD are an Array[1..2048] of Byte;
- NDPtr and ONDPtr are pointers to the Type we defined above.
-
- All of these structures occupy the same amount of space, 2048 bytes.
- We can now tell our program that NDPtr points to the same location in
- memory where the variable JPD is stored, and ONDPtr points to the same
- location in memory where the variable OJPD is stored. If your not
- familiar with pointers, don't worry, I'm no pro either <grin>.
- Basically what we are doing, is saying that NDPtr points to the
- location where the variable JPD is located in memory. Because they
- are the same size, we can now reference the same data in two ways!
-
- NDPtr := @JPD; {OUR nodes data}
- ONDPtr := @OJPD; {OTHER nodes data}
-
- If we want to put the users name into the JPDoor.Use file, we simply
- refer to the name field defined in JPUseRecord as JPD.NAME
-
- To reference a field in OUR defined structure, we use the pointer.
- For example if I wish to pass a short note to the user on the other
- node, I can use the CHATLINE field I defined in MY structure.
-
- NDPtr^.ChatLine := 'Hi there...';
-
- Because this points to JPD which is 2048 bytes in size, and ChatLine
- starts at 126 bytes into MY structure, is is saved in the same memory
- location as JPD, but at offset 126.
- Now JPD contains this string starting at byte 126.
-
- Like I said, it may sound confusing, but don't worry about it. Its
- kinda like driving a car, you don't have to understand how it works
- in order to use it, Afterall, thats what JPDoor is all about, making
- it easy to do things you may not understand!
-
-
-
- Adding a user to JPDOOR.USE
- ---------------------------
-
- Function JPUseAdd : Boolean;
-
- In your door, you need to add the user information to the JPDOOR.USE
- file. This is done with the JPUseAdd function. If JPDOOR.USE does
- not exist, it will be created. This function will count the number of
- nodes by counting the number of records in your USERON.BBS and one
- record will be added to JPDOOR.USE for each one in USERON.BBS.
-
- Here is a sample from my MAIN code:
-
- BEGIN (* M A I N *)
- ASSIGN(output,'') ;
- REWRITE(output) ;
- InitVars ;
- GetDorInfo('1',DropPath) ;
- NDPtr := @JPD; {Set the pointer to point to JPD}
- ONDPtr := @OJPD;
- FillChar(NDPtr^,SizeOf(NDPtr^),#0); {Fill the memory location with Nulls}
- JPUse.Pid := 0; {Set Your PID - 0 if not registered}
- JPUse.Name := UserName;
- JPUse.MultiNode := True;
- JPUse.DoorName := 'BattleShip';
- JPUse.Line := GetNode;
- NDPtr^.Status := 1;
- JPUse.MaxPlayers := 2;
- JPUse.Data := JPD; { Now move JPD into the JPUse.Data field}
- If Not JPUseAdd then
- Begin
- CRLF ;
- Display(0,15,0,'Motor City Battle Ships allows for two players at once,') ;
- Display(0,15,0,'and there are currently two people playing.') ;
- CRLF ;
- HALT(0) ;
- End;
-
- You will notice that I set JPUse.MaxPlayers to 2 players. When JPUseAdd
- is called, it counts the number of users already in JPDoor.Use with the
- same PID, and if there are already MaxPlayers playing, JPUseAdd will
- NOT add you, and will return False.
-
-
-
- Removing a user from JPDOOR.USE
- -------------------------------
-
- Procedure JPUseExit;
-
- When the user exists the door, under ANY circumstances, you MUST make
- sure you remove him from the JPDOOR.USE file. This is done by adding
- the JPUseExit procedure to your Terminate procedure as follows:
-
-
-
- Procedure Terminate(n:byte) ;
- begin
- JPUseExit; {This ensures that the user is removed!}
- case n of
- 0 : begin
- CloseGame ;
- LastComments ;
- end ;
- 1 : begin
- CloseGame ;
- Writeln('■ Carrier lost') ;
- end ;
- 2 : begin
- CloseGame ;
- Writeln('■ Time limit exceeded') ;
- end ;
- 3 : begin
- CloseGame ;
- Writeln('■ User inactive') ;
- end ;
- 4,
- 5,
- 6 : begin
- end ;
- 7 : begin
- CloseGame ;
- Writeln('■ CTS timeout error') ;
- End ;
- else CloseGame ;
- end ;
- end ;
-
-
-
-
- Updating Data in JPDOOR.USE
- ---------------------------
-
- Procedure JPUseUpdate;
-
- Data is passed to the other node by updating your JPUse.Data field,
- so that the other node can read it. It is similar to the JPUseAdd
- function except this is a procedure, and does not return any values.
- You may find it easier to create a PlayerUpdate procedure as I did
- in BattleShips:
-
-
- Procedure UpDateMyData;
- Begin
- NDPtr^.Local := Local;
- If Not SendChat then NDPtr^.ChatLine := '';
- SendChat := False;
- JPUse.Data := JPD;
- JPUseUpDate;
- End;
-
-
- Your code would update any relevent fields, then call this procedure.
- When you Update your data, JPUse.Status will be set to 1 signifying
- that new data has been written to the file.
-
-
-
- Getting Other Users Data from JPDOOR.USE
- ----------------------------------------
-
-
- Function JPUseGet : Boolean;
-
- JPUseGet will scan the JPDOOR.USE file for another user (it checks
- the username) with the SAME PID as your door. If one is found, and
- new data is read (JPUse.Status = 1) then JPUseGet returns TRUE and
- the other users data is stored in the variable JPUseOther.
- JPUseOther is exactly the same as JPUse, but is a seperate variable
- to hold the other players data. Both are defined in JPDoor.
- If there is no other user, then JPUseGet returns false, and the
- variable is filled with nulls. If it finds a user, but no new data
- is found, it returns false, and contains the same data as before the
- call was made.
-
- If you are waiting for the other player to take his turn, you may
- simply keep calling this funtion until it returns TRUE.
-
- The other players data is read the same as you write your data.
-
-
- If JPUseGet then
- Begin
- OJPD := JPUseOther.Data; { Put OTHER users data into OJPD}
- End;
-
- To get his name : JPUseOther.Name
- To Get his Node# : JPUseOther.Line
- To Get his Chatline : ONDPtr^.ChatLine
-
- etc...
-
-
-
-
-
-
-
-
-
-
-