Beispiel #1
0
ULONG
SlAddMenuItem(
    PSL_MENU Menu,
    PCHAR Text,
    PVOID Data,
    ULONG Attributes
    )

/*++

Routine Description:

    Adds an item to the menu

Arguments:

    Menu - Supplies a pointer to the menu the item will be added to

    Text - Supplies the text to be displayed in the menu

    Data - Supplies a pointer to the data to be returned when the item
           is selected.

    Attributes - Supplies any attributes for the item.

Return Value:

    The Selection index if successful

    -1 on failure

--*/
{
    PSL_MENUITEM NewItem;
    ULONG Length;

    NewItem = BlAllocateHeap(sizeof(SL_MENUITEM));
    if (NewItem==NULL) {
        SlError(0);
        return((ULONG)-1);
    }
    InsertTailList(&Menu->ItemListHead, &NewItem->ListEntry);
    Menu->ItemCount += 1;

    NewItem->Text = Text;
    NewItem->Data = Data;
    NewItem->Attributes = Attributes;
    Length = strlen(Text);
    if (Length > Menu->Width) {
        Menu->Width = Length;
    }
    return(Menu->ItemCount - 1);
}
Beispiel #2
0
PVOID
SlGetMenuItem(
    IN PSL_MENU Menu,
    IN ULONG Item
    )

/*++

Routine Description:

    Given an item index, returns the data associated with that item.

Arguments:

    Menu - Supplies the menu structure.

    Item - Supplies the item index.

Return Value:

    The data associated with the given item.

--*/

{
    ULONG i;
    PSL_MENUITEM MenuItem;

    //
    // Find item to return
    //
    MenuItem = CONTAINING_RECORD(Menu->ItemListHead.Flink,
                                 SL_MENUITEM,
                                 ListEntry);

    for (i=0;i<Item;i++) {
        MenuItem = CONTAINING_RECORD(MenuItem->ListEntry.Flink,
                                     SL_MENUITEM,
                                     ListEntry);

#if DBG
        if (&MenuItem->ListEntry == &Menu->ItemListHead) {
            SlError(Item);
            return(NULL);
        }
#endif
    }
    return(MenuItem->Data);

}
Beispiel #3
0
/**
 * Perform all steps to upgrade from the old waypoints to the new version
 * that uses station. This includes some old saveload mechanics.
 */
void MoveWaypointsToBaseStations()
{
	/* In version 17, ground type is moved from m2 to m4 for depots and
	 * waypoints to make way for storing the index in m2. The custom graphics
	 * id which was stored in m4 is now saved as a grf/id reference in the
	 * waypoint struct. */
	if (IsSavegameVersionBefore(17)) {
		for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
			if (wp->delete_ctr != 0) continue; // The waypoint was deleted

			/* Waypoint indices were not added to the map prior to this. */
			_m[wp->xy].m2 = (StationID)wp->index;

			if (HasBit(_m[wp->xy].m3, 4)) {
				wp->spec = StationClass::Get(STAT_CLASS_WAYP, _m[wp->xy].m4 + 1);
			}
		}
	} else {
		/* As of version 17, we recalculate the custom graphic ID of waypoints
		 * from the GRF ID / station index. */
		for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
			for (uint i = 0; i < StationClass::GetCount(STAT_CLASS_WAYP); i++) {
				const StationSpec *statspec =  StationClass::Get(STAT_CLASS_WAYP, i);
				if (statspec != NULL && statspec->grf_prop.grffile->grfid == wp->grfid && statspec->grf_prop.local_id == wp->localidx) {
					wp->spec = statspec;
					break;
				}
			}
		}
	}

	if (!Waypoint::CanAllocateItem(_old_waypoints.Length())) SlError(STR_ERROR_TOO_MANY_STATIONS_LOADING);

	/* All saveload conversions have been done. Create the new waypoints! */
	for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
		Waypoint *new_wp = new Waypoint(wp->xy);
		new_wp->town       = wp->town;
		new_wp->town_cn    = wp->town_cn;
		new_wp->name       = wp->name;
		new_wp->delete_ctr = 0; // Just reset delete counter for once.
		new_wp->build_date = wp->build_date;
		new_wp->owner      = wp->owner;

		new_wp->string_id = STR_SV_STNAME_WAYPOINT;

		TileIndex t = wp->xy;
		if (IsTileType(t, MP_RAILWAY) && GetRailTileType(t) == 2 /* RAIL_TILE_WAYPOINT */ && _m[t].m2 == wp->index) {
			/* The tile might've been reserved! */
			bool reserved = !IsSavegameVersionBefore(100) && HasBit(_m[t].m5, 4);

			/* The tile really has our waypoint, so reassign the map array */
			MakeRailWaypoint(t, GetTileOwner(t), new_wp->index, (Axis)GB(_m[t].m5, 0, 1), 0, GetRailType(t));
			new_wp->facilities |= FACIL_TRAIN;
			new_wp->owner = GetTileOwner(t);

			SetRailStationReservation(t, reserved);

			if (wp->spec != NULL) {
				SetCustomStationSpecIndex(t, AllocateSpecToStation(wp->spec, new_wp, true));
			}
			new_wp->rect.BeforeAddTile(t, StationRect::ADD_FORCE);
		}

		wp->new_index = new_wp->index;
	}

	/* Update the orders of vehicles */
	OrderList *ol;
	FOR_ALL_ORDER_LISTS(ol) {
		if (ol->GetFirstSharedVehicle()->type != VEH_TRAIN) continue;

		for (Order *o = ol->GetFirstOrder(); o != NULL; o = o->next) UpdateWaypointOrder(o);
	}

	Vehicle *v;
	FOR_ALL_VEHICLES(v) {
		if (v->type != VEH_TRAIN) continue;

		UpdateWaypointOrder(&v->current_order);
	}

	_old_waypoints.Reset();
}
Beispiel #4
0
VOID
SlpDrawMenuItem(
    IN ULONG X,
    IN ULONG Y,
    IN ULONG TopItem,
    IN ULONG Height,
    IN ULONG Item,
    IN PSL_MENU Menu
    )

/*++

Routine Description:

    Redraws the given item

Arguments:

    X - Supplies X coordinate of upper-left corner of menu

    Y - Supplies Y coordinate of upper-left corner of menu

    TopItem - Supplies index of item at the top of the menu

    Height - Supplies the height of the menu

    Item - Supplies the index of the item to be redrawn

    Menu - Supplies the menu to be displayed

Return Value:

    None.

--*/

{
    ULONG i;
    PSL_MENUITEM MenuItem;
    ULONG Count;
    CHAR Width[80];

    //
    // Find item to display
    //
    MenuItem = CONTAINING_RECORD(Menu->ItemListHead.Flink,
                                 SL_MENUITEM,
                                 ListEntry);

    for (i=0;i<Item;i++) {
        MenuItem = CONTAINING_RECORD(MenuItem->ListEntry.Flink,
                                     SL_MENUITEM,
                                     ListEntry);

#if DBG
        if (&MenuItem->ListEntry == &Menu->ItemListHead) {
            SlError(Item);
        }
#endif
    }

    RtlFillMemory(Width,Menu->Width,' ');
    RtlCopyMemory(Width,MenuItem->Text,strlen(MenuItem->Text));
    SlPositionCursor(X+2, Y+(Item-TopItem)+1);
    ArcWrite(ARC_CONSOLE_OUTPUT,Width,Menu->Width,&Count);
}
Beispiel #5
0
VOID
SlGenericMessageBox(
    IN     ULONG   MessageId, OPTIONAL
    IN     va_list *args,     OPTIONAL
    IN     PCHAR   Message,   OPTIONAL
    IN OUT PULONG  xLeft,     OPTIONAL
    IN OUT PULONG  yTop,      OPTIONAL
    OUT    PULONG  yBottom,   OPTIONAL
    IN     BOOLEAN bCenterMsg
    )

/*++

Routine Description:

    Formats and displays a message box.  The longest line in the string
    of characters will be centered on the screen if bCenterMsg is TRUE.

    The status text line will be erased.

Arguments:

    NOTE:  Either the MessageId/args pair or the Message string must be
           specified. Message string will be used if non-NULL.

    MessageId - Supplies the MessageId that will be looked up to provide
                a NULL-terminated string of characters.
                Each \r\n delimited string will be displayed on its own line.

    args - Supplies the argument list that will be passed to vsprintf.

    Message - Supplies the actual text of the message to be displayed

    xLeft - If bCenterMsg is FALSE, then xLeft is used for the starting x
            coordinate of the message (if specified, otherwise, x = 1).
            Also, if specified, it receives the x coordinate of the left edge
            of all lines that were displayed.

    yTop -  If bCenterMsg is FALSE, then yTop is used for the starting y
            coordinate of the message (if specified, otherwise, y = 3).
            Also, if specified, receives the y coordinate of the top line where
            the message box was displayed.

    yBottom - if specified, receives the y coordinate of the bottom line of
              the message box.

    bCenterMsg - if TRUE, center message on the screen.

Return Value:

    None.

--*/

{
    PCHAR p;
    ULONG NumLines;
    ULONG MaxLength;
    ULONG x;
    ULONG y;
    ULONG i;
    PCHAR Line[20];
    ULONG LineLength[20];
    ULONG Count;

    if(!Message) {    // then look up the message
        p=BlFindMessage(MessageId);
        if (p==NULL) {
            SlError(MessageId);
            x=3;
            y=ScreenHeight/2;
            NumLines=0;
        } else {
            _vsnprintf(MessageBuffer,sizeof(MessageBuffer),p,*args);
            Message = MessageBuffer;
        }
    } else {
        //
        // Just make p non-NULL, so we'll know it's OK to continue.
        //
        p = Message;
    }

    if(p) {

        SlWriteStatusText("");  // Clear status bar

        SlpSizeMessage(Message,
                       &NumLines,
                       &MaxLength,
                       LineLength,
                       Line);

        if (MaxLength > ScreenWidth) {
            MaxLength = ScreenWidth;
        }

        if(bCenterMsg) {
            x = (ScreenWidth-MaxLength)/2;
            y = (ScreenHeight-NumLines)/2;
        } else {
            if(xLeft) {
                x = *xLeft;
            } else {
                x = 1;
            }

            if(yTop) {
                y = *yTop;
            } else {
                y = 3;
            }
        }
    }

    for (i=0; i<NumLines; i++) {
        SlPositionCursor(x, y+i);
        ArcWrite(ARC_CONSOLE_OUTPUT,Line[i],LineLength[i],&Count);
    }

    if(xLeft) {
        *xLeft = x;
    }

    if(yTop) {
        *yTop = y;
    }

    if(yBottom) {
        *yBottom = NumLines ? y+NumLines-1 : 0;
    }
}
Beispiel #6
0
VOID
SlFatalError(
    IN ULONG MessageId,
    ...
    )

/*++

Routine Description:

    This is called when a fatal error occurs.  It clears the client
    area, puts up a message box, displays the fatal error message, and
    allows the user to press a key to reboot.

    The status text line will be erased.

Arguments:

    MessageId - Supplies ID of message box to be presented.

    any sprintf-compatible arguments to be inserted in the
    message box.

Return Value:

    Does not return.

--*/

{
    va_list args;
    ULONG x,y;
    PUCHAR Text;

    SlClearClientArea();

    Text = BlFindMessage(MessageId);
    if(Text) {

        va_start(args, MessageId);

        _vsnprintf(MessageBuffer, sizeof(MessageBuffer), Text, args);

        //
        // Add a blank line, then concatenate the 'Can't continue' text.
        //
        strcat(MessageBuffer, "\r\n");

        Text = BlFindMessage(SL_CANT_CONTINUE);
        if(Text) {
            strcat(MessageBuffer, Text);
        }

        Text = BlAllocateHeap((strlen(MessageBuffer)+1) * sizeof(CHAR));
        strcpy(Text, MessageBuffer);

        //
        // Note that MessageId and args won't be used, since we're
        // passing in our Text pointer.
        //
        SlGenericMessageBox(MessageId, &args, Text, &x, NULL, &y, TRUE);

        va_end(args);

    } else {
        SlError(MessageId);
    }

    SlFlushConsoleBuffer();
    SlGetChar();
    ArcRestart();
}
Beispiel #7
0
BOOLEAN
SlPromptForDisk(
    IN PCHAR   DiskName,
    IN BOOLEAN IsCancellable
    )

/*++

Routine Description:

    This routine prompts a user to insert a given diskette #, or to abort the
    Setup process.

    The status line will be erased.

Arguments:

    DiskName - Supplies the name of the disk to be inserted.

    IsCancellable - Supplies flag indicating whether prompt may be cancelled.

Return Value:

    TRUE - The user has pressed OK

    FALSE - The user has pressed CANCEL

--*/

{
    ULONG msg;
    ULONG y;
    ULONG Key;
    PCHAR StatusText;
    PCHAR PleaseWait;
    ULONG i;
    CHAR  DiskNameDisplayed[81];
    BOOLEAN Repaint=TRUE;

    SlWriteStatusText("");

    if(IsCancellable) {
        msg = SL_NEXT_DISK_PROMPT_CANCELLABLE;
    } else {
        msg = SL_NEXT_DISK_PROMPT;
    }
    StatusText = BlFindMessage(msg);
    if(StatusText == NULL) {
        SlError(msg);
        return(FALSE);
    }

    PleaseWait = BlFindMessage(SL_PLEASE_WAIT);
    if(PleaseWait == NULL) {
        SlError(SL_PLEASE_WAIT);
        return(FALSE);
    }

    //
    // Get first line of DiskName and save it in DiskNameDisplayed (limit to 80 chars)
    //
    for(i = 0;
        ((i < 80) && DiskName[i] && (DiskName[i] != '\r') && (DiskName[i] != '\n'));
        i++)
    {
        DiskNameDisplayed[i] = DiskName[i];
    }
    DiskNameDisplayed[i] = '\0';

    do {
        if (Repaint) {
            SlClearClientArea();
            y = SlDisplayMessageBox(SL_MSG_INSERT_DISK);
            SlPositionCursor((ScreenWidth-i)/2,y+2);
            SlWriteString(DiskNameDisplayed);
            SlWriteStatusText(StatusText);
        }
        Repaint = FALSE;
        SlFlushConsoleBuffer();
        Key = SlGetChar();

        if (Key == ASCI_CR) {
            SlClearClientArea();
            SlWriteStatusText(PleaseWait);
            return(TRUE);
        } else if (Key == SL_KEY_F3) {
            SlConfirmExit();
            Repaint=TRUE;
        } else if((Key == ASCI_ESC) && IsCancellable) {
            SlWriteStatusText("");
            SlClearClientArea();
            return FALSE;
        }
    } while ( TRUE );
}