⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 1、手持设备的机器人--服务器端; 2、通过蓝牙通讯;
💻 CPP
字号:
/*
 * Copyright (c) 2004-2005 Mobile Robotics
 * http://mobilerobotics.sf.net
 *
 * File: main.cpp
 * Author: Johan Johanson
 * Date: November 26, 2004
 * Updated: April 15, 2005
 *
 * Description: Main entry point for application
 *
*/

#define ERROR_CHECK_LEVEL ERROR_CHECK_PARTIAL // enable error alerts

#include <PalmOS.h>

#include "MobileRobotics.h"
#include "BtCustomEvent.h"
#include "resource.h"

FormPtr mainForm;
FieldPtr debugField;
ScrollBarPtr debugFieldScrollBar;

RectangleType pdaBatteryRect;	// palm battery level rect
RectangleType rcxBatteryRect;	// rcx battery level rect
UInt8 pdaPercent;
UInt8 rcxPercent;

MobileRobotics server;	// our bluetooth/ir server manager

DateTimeType counterStart;	// used for counting minutes

// prints out text to the field in the main form field
void debugPrint(Char *str)
{
	if (str != NULL && debugField != NULL)
	{
		// apply time stamp to message
		DateTimeType dateTime;
		Char date[timeStringLength + 3 + StrLen(str) + 1];

		TimSecondsToDateTime(TimGetSeconds(), &dateTime);
		TimeToAscii(dateTime.hour, dateTime.minute, tfColon24h, date);

		StrCat(date, " - ");
		StrNCat(date, str, timeStringLength + StrLen(str) + 1);

		FldSetInsPtPosition(debugField, FldGetTextLength(debugField));
		FldInsert(debugField, date, StrLen(date));
		FldInsert(debugField, "\n", 1);
	}
}

// draws a rounded rectangle frame around the debug field
void drawFieldFrame()
{
	if (debugField == NULL)
		return;

	UInt16 indexField = FrmGetObjectIndex(mainForm, MobileRoboticsDebugField);
	RectangleType fieldRect = { { 0, 0 }, { 0, 0 } };
	FrmGetObjectBounds(mainForm, indexField, &fieldRect);

	fieldRect.topLeft.x -= 1;
	fieldRect.topLeft.y -= 1;
	fieldRect.extent.x += 2;
	fieldRect.extent.y += 2;

	RGBColorType newColor = { 0, 255, 127, 63 };

	WinPushDrawState();
		WinSetForeColorRGB(&newColor, NULL);
		WinDrawRectangleFrame(boldRoundFrame, &fieldRect);
	WinPopDrawState();
}

// draws battery status
void drawBatteryStatus()
{
	Int16 timeout = 0;

	// retrieve battery info
	UInt16 volts = SysBatteryInfo(false, NULL, NULL, &timeout, NULL, NULL, &pdaPercent);
	volts = volts;

	// calculate new coords for pda battery status rect
	UInt16 startX = pdaBatteryRect.topLeft.x + 1;
	UInt16 startY = pdaBatteryRect.topLeft.y;

	UInt16 endX = startX + pdaBatteryRect.extent.x - 2;
	UInt16 endY = startY + pdaBatteryRect.extent.y;

	UInt16 diffY = endY - startY;

	// calculate for pda battery level
	UInt16 newStartY = startY + (UInt16)(((1.0f - ((float)pdaPercent / (float)100.0)) * (float)diffY));

	UInt16 extentX = endX - startX;
	UInt16 extentY = endY - newStartY;

	// pda battery level bar
	RectangleType pdaBar = { { startX, newStartY }, { extentX, extentY } };
	RGBColorType newColor = { 0, 0, 0, 0 };

	// draw pda battery frame
	WinPushDrawState();
		WinSetForeColorRGB(&newColor, NULL);
		WinDrawRectangleFrame(simpleFrame, &pdaBatteryRect);
	WinPopDrawState();

	// calculate new coords for rcx battery status rect
	startX = rcxBatteryRect.topLeft.x + 1;
	startY = rcxBatteryRect.topLeft.y;

	endX = startX + rcxBatteryRect.extent.x - 2;
	endY = startY + rcxBatteryRect.extent.y;

	diffY = endY - startY;

	// if one minute since last call has elapsed,
	// calculate rcx battery level
	DateTimeType curTime;
	TimSecondsToDateTime(TimGetSeconds(), &curTime);

	if ((curTime.minute - counterStart.minute) >= 1)
	{
		UInt16 mV = server.getRCXBatteryLevel();
		const UInt16 maxMV = 9000;
		
		if (mV > 0)
			rcxPercent = (UInt8)((float)mV / (float)maxMV * 100);
		else
			rcxPercent = 0;
			
		// save last time
		TimSecondsToDateTime(TimGetSeconds(), &counterStart);
	}
	
	newStartY = startY + (UInt16)(((1.0f - ((float)rcxPercent / (float)100.0)) * (float)diffY));

	extentX = endX - startX;
	extentY = endY - newStartY;
	
	// rcx battery bar
	RectangleType rcxBar = { { startX, newStartY }, { extentX, extentY } };

	// draw rcx battery frame
	WinPushDrawState();
		WinSetForeColorRGB(&newColor, NULL);
		WinDrawRectangleFrame(simpleFrame, &rcxBatteryRect);
	WinPopDrawState();

	newColor.r = 101;
	newColor.g = 186;
	newColor.b = 206;

	// draw battery levels
	WinPushDrawState();
		WinSetForeColorRGB(&newColor, NULL);
		WinDrawRectangle(&pdaBar, 0);
		WinDrawRectangle(&rcxBar, 0);
	WinPopDrawState();
}

// updates graphics etc each frame
void updateFrame()
{
	drawBatteryStatus();
	server.update();
}

// initializes app
Boolean startApp()
{
	mainForm = NULL;
	debugField = NULL;
	debugFieldScrollBar = NULL;

	pdaBatteryRect.topLeft.x = 21;
	pdaBatteryRect.topLeft.y = 123;
	pdaBatteryRect.extent.x = 7;
	pdaBatteryRect.extent.y = 34;

	rcxBatteryRect.topLeft.x = 34;
	rcxBatteryRect.topLeft.y = 123;
	rcxBatteryRect.extent.x = 7;
	rcxBatteryRect.extent.y = 34;

	FrmGotoForm(MobileRoboticsForm);

	// prevent palm to automatically power off when idle
	SysSetAutoOffTime(0);

	// get start time
	TimSecondsToDateTime(TimGetSeconds(), &counterStart);

	pdaPercent = rcxPercent = 0;

	return true;
}

// initializes Bluetooth server and RCX interface
Boolean startServer()
{
	// Bluetooth radio should be initialized
	debugPrint("Server initializing..");
	if (!server.init("MRRfComm", 1, true))
	{
		debugPrint("Server init error");
		return false;
	}

	debugPrint("Server init OK");

	// set server in listening state, accepting only one client
	if (!server.listen())
		debugPrint("Server listen error");
	else
		debugPrint("Server in listening state");

	return true;
}

// shuts down app
void stopApp()
{
	// shut down server and Bluetooth library
	debugPrint("System shutting down..");
	server.shutdown();
	BtBase::shutdownSystem();
	debugPrint("Shutdown complete");

	WinEraseChars("ok", 2, 47 + 13, 126 + 13 / 2 - 5);
	WinEraseChars("ok", 2, 47 + 13, 141 + 13 / 2 - 5);
	WinDrawChars("--", 2, 47 + 13, 126 + 13 / 2 - 5);
	WinDrawChars("--", 2, 47 + 13, 141 + 13 / 2 - 5);

	FrmCloseAllForms();
}

// application event handler
Boolean frmEventHandler(EventPtr event)
{
	switch (event->eType)
	{
		// form is opening
		case frmOpenEvent:
		{
			mainForm = FrmGetActiveForm();

			UInt16 indexField = FrmGetObjectIndex(mainForm, MobileRoboticsDebugField);
			debugField = (FieldPtr)FrmGetObjectPtr(mainForm, indexField);
			FldSetMaxChars(debugField, maxFieldTextLen);
			FldSetFont(debugField, stdFont);

			UInt16 indexScrollBar = FrmGetObjectIndex(mainForm, MobileRoboticsDebugFieldScrollBar);
			debugFieldScrollBar = (ScrollBarPtr)FrmGetObjectPtr(mainForm, indexScrollBar);

			FrmDrawForm(mainForm);
			drawFieldFrame();

			// connection status
			WinEraseChars("ok", 2, 47 + 13, 126 + 13 / 2 - 5);
			WinEraseChars("ok", 2, 47 + 13, 141 + 13 / 2 - 5);
			WinDrawChars("--", 2, 47 + 13, 126 + 13 / 2 - 5);
			WinDrawChars("--", 2, 47 + 13, 141 + 13 / 2 - 5);

			// try to initialize the Bluetooth radio
			// BtBase will post an event with the radio initialization
			// status once it's complete
			debugPrint("Bluetooth initializing..");
			BtBase::setCallbackRef(&server);
			if (!BtBase::initSystem())
			{
				debugPrint("Bluetooth init error");
				/*// failed, post quit event
				EventType e;
				MemSet((void **)&e, sizeof(EventType), 0);
				e.eType = appStopEvent;
				EvtAddEventToQueue(&e);*/
			}

			break;
		}

		// form is closing
		case frmCloseEvent:
		{
			FrmEraseForm(mainForm);
			FrmDeleteForm(mainForm);

			debugFieldScrollBar = NULL;
			debugField = NULL;
			mainForm = NULL;
			break;
		}

		// our debug field has changed
		case fldChangedEvent:
		{
			if (debugField == NULL || debugFieldScrollBar == NULL)
				return true;

			// do scroll bar boohagi
			UInt16 scrollPos = 0;
			UInt16 textHeight = 0;
			UInt16 fieldHeight = 0;
			UInt16 maxValue = 0;

			FldGetScrollValues(debugField, &scrollPos,  &textHeight, &fieldHeight);

			if (textHeight > fieldHeight)
				maxValue = textHeight - fieldHeight;
			else if (scrollPos)
			  	maxValue = scrollPos;
			else
			  	maxValue = 0;

			SclSetScrollBar(debugFieldScrollBar, scrollPos, 0, maxValue,  fieldHeight - 1);
			return false;
		}

		// scrollbar is updating
		case sclRepeatEvent:
		{
			if (debugFieldScrollBar == NULL)
				return true;

			// do scroll bar boohagi
		    UInt16 newValue = event->data.sclRepeat.newValue;
			static UInt16 curValue = 0;

			if (newValue > curValue)
				FldScrollField(debugField, newValue - curValue, winDown);
			else
				FldScrollField(debugField, curValue - newValue, winUp);

			curValue = newValue;
			return false;
		}

		default:
			return false;
	}

	return true;
}

// application event handler
Boolean appEventHandler(EventPtr event)
{
	switch (event->eType)
	{
		// form is being loaded, show it
		case frmLoadEvent:
		{
			FormPtr form = FrmInitForm(event->data.frmLoad.formID);
			FrmSetActiveForm(form);
			FrmSetEventHandler(form, frmEventHandler);
			break;
		}

		// custom user event
		case firstUserEvent:
		{
			BtCustomEvent *e = (BtCustomEvent *)event;

			// our radio state event
			if (e->data.eventData.type == btCustomRadioStateEvent)
			{
				// radio initialized
				if (e->data.eventData.status == btLibErrRadioInitialized ||
					e->data.eventData.status == btLibErrRadioSleepWake)
				{
					debugPrint("Bluetooth init OK");
					WinDrawChars("ok", 2, 47 + 13, 126 + 13 / 2 - 5);

					// fire up server
					if (!startServer())
					{
						/*EventType evt;
						MemSet((void **)&evt, sizeof(EventType), 0);
						evt.eType = appStopEvent;
						EvtAddEventToQueue(&evt);*/
					}
				}
				else
				{
					// radio error
					debugPrint("Bluetooth radio error");
					WinEraseChars("ok", 2, 47 + 13, 126 + 13 / 2 - 5);
					WinDrawChars("--", 2, 47 + 13, 126 + 13 / 2 - 5);
					/*EventType evt;
					MemSet((void **)&evt, sizeof(EventType), 0);
					evt.eType = appStopEvent;
					EvtAddEventToQueue(&evt);*/
				}
			}

			break;
		}

		default:
			return false;
	}

	return true;
}

// application event loop
void eventLoop()
{
	EventType event;

	// while our event isn't a quit event
	while (event.eType != appStopEvent)
	{
		// get a new event
		EvtGetEvent(&event, evtNoWait);

		// if there's an important event, handle it
		if (event.eType != nilEvent)
		{
			if (!SysHandleEvent(&event))
				if (!MenuHandleEvent(NULL, &event, NULL))
					if (!appEventHandler(&event))
						FrmDispatchEvent(&event);
		}
		else
			updateFrame();	// else update stuff
	}
}

// main application entry point
UInt32 PilotMain(UInt16 cmd, void *cmdPBP, UInt16 launchFlags)
{
	if (cmd != sysAppLaunchCmdNormalLaunch)
		return 1;

	if (!startApp())
		return 1;

	eventLoop();
	stopApp();

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -