/*****************************************************************************/

/*
 *      menus.c -- REALmagic Celeste Application
 *
 *      Copyright (C) 1999-2000 Sigma Designs
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*****************************************************************************/

#include "menus.h"

void initPoi(void **p) {
	OSCelFree(*p);
	*p = NULL;
}
/**********************************************************/
/**************** Navigation between menus ****************/
/**********************************************************/

char onScreenMenus(INFO *pInfo) {

	char buf[1];
//	ULONG scrH, scrW;
	int ind;

/*
	scrH = (pInfo->IHdtv_c) ? Hdtv_Params[pInfo->IHdtv_c - 1].VideoHeight : 480;
	scrW = (pInfo->IHdtv_c) ? Hdtv_Params[pInfo->IHdtv_c - 1].VideoWidth : 720;
	g_sw = (float)scrW / 720;
	g_sh = (float)scrH / 480;
*/
	g_sw = 1.0f;
	g_sh = 1.0f;

	ind = createMenu(MAIN, pInfo);
	g_Pass = FMPGetProfileWord(RMREG_PASSW_LOW_WORD) |
	         (FMPGetProfileWord(RMREG_PASSW_HIGH_WORD) << 16);
/*
	FMPGetProfileWord(RMREG_PASSW_LOW_WORD, (WORD *)(&g_Pass));
	FMPGetProfileWord(RMREG_PASSW_HIGH_WORD, (WORD *)(&g_Pass) + 1);
*/

	do {
		if(OSGetMessage(pInfo->osdMsgQ, buf, 1) == ERROR) {
			DPRINT(("osdManager: error during reading message queue \n"));
			return -1;
		}
		switch(buf[0]) {
			case UP:
				ind = up(ind, pInfo);
				break;
			case LEFT:
				ind = left(ind, pInfo);
				break;
			case RIGHT:
				ind = right(ind, pInfo);
				break;
			case DOWN:
				ind = down(ind, pInfo);
				break;
			case SEL:
				ind = bSelect(ind, pInfo);
				break;
			case SHOW_PREV:
				if(g_menusDesc[ind].prev != -1)
					ind = returnToPrevMenu(ind, pInfo);
				else
					buf[0] = SHOW_MENU;
				break;
			case SHOW_HIDDEN:
				if(ind == MAIN) {
					hiddenMenu(pInfo);
					if(g_menusDesc[MAIN].bmp) {
						OSD_WND *wnd = &(g_menusDesc[MAIN].menuItemsList[g_menusDesc[MAIN].hliItemIndex].wnd);
						DISPLAY_OSD(pInfo->pIOsd,g_menusDesc[MAIN].bmp,
						            ((720-MENU_WINDOW_WIDTH)>>1),((480-MENU_WINDOW_HEIGHT)>>1),
						            LEFT_TOP,g_sw,g_sh);
						SET_HIGHLIGHT(pInfo->pIOsd,wnd,g_sw,g_sh);
					}
				}
				break;
			default:
				break;
		}
	} while(buf[0] != SHOW_MENU);
	
	if(pInfo->pIOsd) {
		IOsd_Off(pInfo->pIOsd);
//		IOsd_Flush(pInfo->pIOsd);
	}

	while(g_menusDesc[ind].prev != -1) {
		initPoi((void **)(&(g_menusDesc[ind].bmp)));
		g_menusDesc[ind].hliItemIndex = 0;
		ind = g_menusDesc[ind].prev;
	}
	initPoi((void **)(&(g_menusDesc[ind].bmp)));
	g_menusDesc[ind].hliItemIndex = 0;
	pInfo->blk = 0;
	return 0;
}

void loadSettings(int menuInd, INFO *pInfo) {
	int i, j, f;
	WORD tmp;
	for(i = 0; i < (sizeof(g_regValues) / sizeof(Rgs)); i++) {
		tmp = (WORD)FMPGetProfileWord(g_regValues[i].kInd);
		if(tmp != 0xffff) {
			if(g_regValues[i].kInd == RMREG_PARENTALCONTROL) {
				g_settings[SUBMENU][VIDEO][4] = (tmp == g_regValues[i].arrVal[1]) ? 1 : 2;
			}
			if(g_regValues[i].kInd == RMREG_USER_ASPECT_RATIO) {
				WORD tmp1;
				tmp1 = (WORD)FMPGetProfileWord(RMREG_USER_VIDEO_OUTPUT_MODE);
				tmp = (tmp << 8) | tmp1;
			}
			j = 0; f = 1;
			while(j < 13 && f) {
				if(g_regValues[i].arrVal[j] == tmp) {
					f = g_regValues[i].i;
					g_settings[f >> 16][(f >> 8) & 0xff][f & 0xff] = j;
					f = 0;
				}
				j++;
			}
			if(g_regValues[i].kInd == RMREG_HDTV_RES && tmp == HDTV_480P_60FPS) {
				WORD tmp1;
				tmp1 = (WORD)FMPGetProfileWord(RMREG_OUTPUTMODE);
				if((tmp1 & FMPV_VIDEOOUT_MODE_MASK) == FMPV_VIDEOOUT_HDTV)
					g_settings[SUBMENU][VIDEO][1] = 4;
				else if((tmp1 & FMPV_VIDEOOUT_MODE_MASK) == FMPV_VIDEOOUT_TV) {
					if(tmp1 & FMPV_VIDEOOUT_TV_AS_SOURCE)
						g_settings[SUBMENU][VIDEO][1] = 3;
					else {
						switch(tmp1 & FMPV_VIDEOOUT_STANDARDTV_MASK) {
							case FMPV_VIDEOOUT_PAL:
								g_settings[SUBMENU][VIDEO][1] = 2;
								break;
							case FMPV_VIDEOOUT_NTSC:
							default:
								g_settings[SUBMENU][VIDEO][1] = 1;
								break;
						}
					}
				}
			}
/*
			if(f) {
				f = g_regValues[i].i;
				g_settings[f >> 16][(f >> 8) & 0xff][f & 0xff] = 0;
			}
*/
		}
	}
	for(i = 0; i < 13; i++) {
		if(g_settings[menuInd][g_menusDesc[menuInd].name][i])
			g_menusDesc[menuInd].menuItemsList[i].value =
				g_settings[menuInd][g_menusDesc[menuInd].name][i];
	}
}

void storeValue(int menuInd, int meniItInd, BYTE value, INFO *pInfo, BOOL bStoreInReg) {

	DWORD ind;
	int i;
	g_settings[menuInd][g_menusDesc[menuInd].name][meniItInd] = value;
	if(bStoreInReg)
		for(i = 0; i < (sizeof(g_regValues) / sizeof(Rgs)); i++) {
			ind = ((DWORD)(menuInd << 16) |
			       (DWORD)(g_menusDesc[menuInd].name << 8) |
			       (DWORD)meniItInd) & 0xffffff;
			if(g_regValues[i].i == ind) {
				if(g_regValues[i].kInd == RMREG_USER_ASPECT_RATIO) {
					FMPWriteProfileWord(g_regValues[i].kInd, (g_regValues[i].arrVal[value]) >> 8);
					FMPWriteProfileWord(RMREG_USER_VIDEO_OUTPUT_MODE, (g_regValues[i].arrVal[value]) & 0xff);
				}
				else
					FMPWriteProfileWord(g_regValues[i].kInd, g_regValues[i].arrVal[value]);
				break;
			}
		}
}

/* Returns the index of the menu or -1 if could not create bitmap*/

int createMenu(int menuIndex, INFO *pInfo) {
	
	int hliItInd;

	loadSettings(menuIndex, pInfo);
	if(g_menusDesc[menuIndex].bmp)
		initPoi((void **)(&(g_menusDesc[menuIndex].bmp)));
	if(g_menusDesc[menuIndex].createBmp(pInfo->pIRma, &(g_menusDesc[menuIndex].bmp)) == -1)
		return -1;
	if(g_menusDesc[menuIndex].bmp) {
		hliItInd = g_menusDesc[menuIndex].hliItemIndex;
		DISPLAY_OSD(pInfo->pIOsd,g_menusDesc[menuIndex].bmp,
		            ((720-MENU_WINDOW_WIDTH)>>1),((480-MENU_WINDOW_HEIGHT)>>1),LEFT_TOP,g_sw,g_sh);
		SET_HIGHLIGHT(pInfo->pIOsd, &(g_menusDesc[menuIndex].menuItemsList[hliItInd].wnd), g_sw, g_sh);

		return menuIndex;
	}
	else
		return -1;
}

/**********************************************************/
/******* Functions for the navigation between menus *******/
/**********************************************************/

int returnToPrevMenu(int menuInd, INFO *pInfo) {

	int ind = g_menusDesc[menuInd].prev, hliItInd;

	if(g_menusDesc[ind].bmp) {
		hliItInd = g_menusDesc[ind].hliItemIndex;
		DISPLAY_OSD(pInfo->pIOsd,g_menusDesc[ind].bmp,
		            ((720-MENU_WINDOW_WIDTH)>>1),((480-MENU_WINDOW_HEIGHT)>>1),LEFT_TOP,g_sw,g_sh);
		SET_HIGHLIGHT(pInfo->pIOsd, &(g_menusDesc[ind].menuItemsList[hliItInd].wnd), g_sw, g_sh);

		initPoi((void **)(&(g_menusDesc[menuInd].bmp)));
		g_menusDesc[menuInd].hliItemIndex = 0;
		g_menusDesc[menuInd].name = 0;
		return ind;
	}
	else {
		if(pInfo->pIOsd) {
			IOsd_Off(pInfo->pIOsd);
//			IOsd_Flush(pInfo->pIOsd);
		}
		initPoi((void **)(&(g_menusDesc[menuInd].bmp)));
		g_menusDesc[menuInd].hliItemIndex = 0;
		g_menusDesc[menuInd].name = 0;
		return -1;
	}
}


/* Returns index of the new menu */

int bSelect(int menuInd, INFO *pInfo) {

	int ind = menuInd;

	switch(ind) {
		case MAIN:
			switch(g_menusDesc[MAIN].hliItemIndex) {
				case 1:
					g_menusDesc[SUBMENU].name = LANG;
					ind = createMenu(SUBMENU, pInfo);
					break;
				case 2:
					g_menusDesc[SUBMENU].name = VIDEO;
					ind = createMenu(SUBMENU, pInfo);
					break;
				case 3:
					g_menusDesc[SUBMENU].name = AUDIO;
					ind = createMenu(SUBMENU, pInfo);
					break;
				default:
					break;
			}
			break;
		case SUBMENU:
			switch(g_menusDesc[SUBMENU].name) {
				case LANG:
					switch(g_menusDesc[SUBMENU].hliItemIndex) {
						case 1:
						case 2:
						case 3:
						case 4:
							g_menusDesc[SUBMENU_CHOICE].createBmp = createChoiceSubmenu;
							ind = createMenu(SUBMENU_CHOICE, pInfo);
							break;
						case 0:
							ind = returnToPrevMenu(ind, pInfo);
							break;
						default:
							break;
					}
					break;
				case VIDEO:
					switch(g_menusDesc[SUBMENU].hliItemIndex) {
						case 0:
							ind = returnToPrevMenu(ind, pInfo);
							break;
						case 1:
						case 3:
						case 4:
						case 5:
						case 6:
#ifdef PRINCETON
						case 7:
#endif
							g_menusDesc[SUBMENU_CHOICE].createBmp = createChoiceSubmenu;
							ind = createMenu(SUBMENU_CHOICE, pInfo);
							break;
						case 2:
							g_menusDesc[SUBMENU_CHOICE].createBmp = createARSubmenu;
							ind = createMenu(SUBMENU_CHOICE, pInfo);
							break;
						default:
							break;
					}
					break;
				case AUDIO:
					switch(g_menusDesc[SUBMENU].hliItemIndex) {
						case 0:
							ind = returnToPrevMenu(ind, pInfo);
							break;
						case 1:
						case 2:
						case 3:
						case 4:
							g_menusDesc[SUBMENU_CHOICE].createBmp = createChoiceSubmenu;
							ind = createMenu(SUBMENU_CHOICE, pInfo);
							break;
						default:
							break;
					}
					break;
			}
			break;
		case SUBMENU_CHOICE:
			if(g_menusDesc[SUBMENU].name == VIDEO &&
			   g_menusDesc[SUBMENU].hliItemIndex == 4 &&
			   g_menusDesc[SUBMENU_CHOICE].prev != PARENTAL_CONTROL_MENU) {
				if(g_menusDesc[SUBMENU_CHOICE].hliItemIndex != 0 &&
				   (g_menusDesc[SUBMENU].menuItemsList[5].value == 1 ||				   
				   checkPassword(pInfo))) {
					if(g_menusDesc[SUBMENU_CHOICE].hliItemIndex == 2) {
						g_menusDesc[SUBMENU].name = PARENTAL_CONTROL_MENU;
						g_menusDesc[PARENTAL_CONTROL_MENU].createBmp = createSubmenu;
						ind = createMenu(PARENTAL_CONTROL_MENU, pInfo);
						initPoi((void **)(&(g_menusDesc[SUBMENU_CHOICE].bmp)));
						g_menusDesc[SUBMENU_CHOICE].hliItemIndex = 0;
						g_menusDesc[SUBMENU_CHOICE].name = 0;
					}
					else if(g_menusDesc[SUBMENU_CHOICE].hliItemIndex == 1) {
						storeValue(SUBMENU, 4, 1, pInfo, 0);
						storeValue(PARENTAL_CONTROL_MENU, 1, 1, pInfo, 1);
						ind = createMenu(SUBMENU, pInfo);
						initPoi((void **)(&(g_menusDesc[SUBMENU_CHOICE].bmp)));
						g_menusDesc[SUBMENU_CHOICE].hliItemIndex = 0;
						g_menusDesc[SUBMENU_CHOICE].name = 0;
					}
				}
				else
					ind = returnToPrevMenu(ind, pInfo);
			}
			else if(g_menusDesc[SUBMENU].name == VIDEO &&
			        g_menusDesc[SUBMENU].hliItemIndex == 5 &&
			        g_menusDesc[SUBMENU_CHOICE].hliItemIndex != g_menusDesc[SUBMENU].menuItemsList[5].value &&
			        g_menusDesc[SUBMENU_CHOICE].hliItemIndex != 0) {
				if(g_menusDesc[SUBMENU_CHOICE].hliItemIndex == 1) {
					if(checkPassword(pInfo)) {
						storeValue(SUBMENU, 5, 1, pInfo, 1);
						ind = createMenu(SUBMENU, pInfo);
						initPoi((void **)(&(g_menusDesc[SUBMENU_CHOICE].bmp)));
						g_menusDesc[SUBMENU_CHOICE].hliItemIndex = 0;
						g_menusDesc[SUBMENU_CHOICE].name = 0;
					}
					else
						ind = returnToPrevMenu(ind, pInfo);
				}
				else if(g_menusDesc[SUBMENU_CHOICE].hliItemIndex == 2) {
					if(g_Pass != 0xffffffff || enterPassword(pInfo, 0)) {
						storeValue(SUBMENU, 5, 2, pInfo, 1);
						ind = createMenu(SUBMENU, pInfo);
						initPoi((void **)(&(g_menusDesc[SUBMENU_CHOICE].bmp)));
						g_menusDesc[SUBMENU_CHOICE].hliItemIndex = 0;
						g_menusDesc[SUBMENU_CHOICE].name = 0;
					}
					else
						ind = returnToPrevMenu(ind, pInfo);
				}
				else if(g_menusDesc[SUBMENU_CHOICE].hliItemIndex == 3) {
					enterPassword(pInfo, 1);
					ind = returnToPrevMenu(ind, pInfo);
				}
			}
#ifdef PRINCETON
			else if(g_menusDesc[SUBMENU].name == VIDEO &&
			   g_menusDesc[SUBMENU].hliItemIndex == 7) {
				changeFPSettings(pInfo, g_menusDesc[SUBMENU_CHOICE].hliItemIndex);
				goto do_nothing;
			}
#endif
			else {
				int Hind = g_menusDesc[SUBMENU_CHOICE].hliItemIndex;
				int prev = g_menusDesc[SUBMENU_CHOICE].prev;
				mI *mi = &(g_menusDesc[prev].menuItemsList[g_menusDesc[prev].hliItemIndex]);
				if(Hind && (Hind != mi->value)) {
					if(prev == SUBMENU &&
					   g_menusDesc[SUBMENU].name == VIDEO &&
					   g_menusDesc[SUBMENU].hliItemIndex == 1 &&
					   pInfo->pIHdtv) {
						if(!testRes(pInfo, Hind))
							goto do_nothing;
						else {
							FMPWriteProfileWord(RMREG_OUTPUTMODE, g_OutputMode);
						}
					}
					mi->value = Hind;
					storeValue(prev, g_menusDesc[prev].hliItemIndex, (BYTE) Hind, pInfo, 1);
					if(prev == PARENTAL_CONTROL_MENU) {
						if(g_menusDesc[PARENTAL_CONTROL_MENU].hliItemIndex == 1)
							storeValue(SUBMENU, 4, (BYTE) ((Hind > 1) ? 2 : 1), pInfo, 0);
						g_menusDesc[SUBMENU].name = PARENTAL_CONTROL_MENU;
						g_menusDesc[PARENTAL_CONTROL_MENU].createBmp = createSubmenu;
					}
					ind = createMenu(prev, pInfo);
					initPoi((void **)(&(g_menusDesc[SUBMENU_CHOICE].bmp)));
					g_menusDesc[SUBMENU_CHOICE].hliItemIndex = 0;
					g_menusDesc[SUBMENU_CHOICE].name = 0;
					if (g_menusDesc[SUBMENU].name == VIDEO) {
/*
						if(pInfo->pIHdtv && g_menusDesc[SUBMENU].hliItemIndex == 1) {
							if(g_menusDesc[SUBMENU].menuItemsList[1].value == 1) {
								pInfo->IHdtv_c = 0;
								IHdtv_Off(pInfo->pIHdtv);
								if(g_menusDesc[SUBMENU].bmp) {
									OSD_WND *wnd = &(g_menusDesc[SUBMENU].menuItemsList[1].wnd);
									DISPLAY_OSD(pInfo->pIOsd,g_menusDesc[SUBMENU].bmp,
									            ((720-MENU_WINDOW_WIDTH)>>1),((480-MENU_WINDOW_HEIGHT)>>1),
									            LEFT_TOP,g_sw,g_sh);
									SET_HIGHLIGHT(pInfo->pIOsd,wnd,g_sw,g_sh);
								}
							}
							else {
								if(!pInfo->IHdtv_c) {
									IHdtv_SetMode(pInfo->pIHdtv, &(Hdtv_Params_Init));
									if(g_menusDesc[SUBMENU].bmp) {
										OSD_WND *wnd = &(g_menusDesc[SUBMENU].menuItemsList[1].wnd);
										DISPLAY_OSD(pInfo->pIOsd,g_menusDesc[SUBMENU].bmp,
										            ((720-MENU_WINDOW_WIDTH)>>1),((480-MENU_WINDOW_HEIGHT)>>1),
										            LEFT_TOP,g_sw,g_sh);
										SET_HIGHLIGHT(pInfo->pIOsd,wnd,g_sw,g_sh);
									}
								}
								pInfo->IHdtv_c = g_menusDesc[SUBMENU].menuItemsList[1].value - 1;
							}
						}
*/
/*
						if(pInfo->pIHdtv && g_menusDesc[SUBMENU].hliItemIndex == 2) {
							if(g_menusDesc[SUBMENU].menuItemsList[2].value < 3) {
								IHdtv_SetAspectRatio(pInfo->pIHdtv,4,3,5);
							}
							else {
								IHdtv_SetAspectRatio(pInfo->pIHdtv,16,9,DISPLAY_MODE_NORMAL_OR_WIDE);
							}
						}
*/
						if(g_menusDesc[SUBMENU].hliItemIndex == 3) {
							if(g_menusDesc[SUBMENU].menuItemsList[3].value == 1) {
								aptID = OSInitPolling("autoplay_thread", (FUNCPTR)autoPlayThread, (DWORD)(pInfo));
							}
							else if(g_menusDesc[SUBMENU].menuItemsList[3].value == 2) {
								OSThreadDelete(aptID);
								aptID = ERROR;
							}
						}
					}
				}
				else {
do_nothing:
					ind = returnToPrevMenu(ind, pInfo);
				}
			}
			break;
		case PARENTAL_CONTROL_MENU:
			switch(g_menusDesc[PARENTAL_CONTROL_MENU].hliItemIndex) {
				case 0:
					ind = createMenu(SUBMENU, pInfo);
					break;
				case 1:
				case 2:
					g_menusDesc[SUBMENU].name = PARENTAL_CONTROL_MENU;
					g_menusDesc[SUBMENU_CHOICE].createBmp = createChoiceSubmenu;
					ind = createMenu(SUBMENU_CHOICE, pInfo);
					break;
				default:
					break;
			}
			break;
		default:
			break;
	}
	return ind;
}

/* Returns index of the new menu */

int right(int menuInd, INFO *pInfo) {

	int ind = menuInd;

	switch(ind) {
		case MAIN:
			hliMenuItem(MAIN, RIGHT, pInfo->pIOsd);
			break;
		case SUBMENU:
			hliMenuItem(SUBMENU, RIGHT, pInfo->pIOsd);
			break;
		case SUBMENU_CHOICE:
			hliMenuItem(SUBMENU_CHOICE, RIGHT, pInfo->pIOsd);
			break;
		case PARENTAL_CONTROL_MENU:
			hliMenuItem(PARENTAL_CONTROL_MENU, RIGHT, pInfo->pIOsd);
			break;
		default:
			break;
	}
	return ind;
}

/* Returns index of the new menu */

int left(int menuInd, INFO *pInfo) {

	int ind = menuInd;

	switch(ind) {
		case MAIN:
			hliMenuItem(MAIN, LEFT, pInfo->pIOsd);
			break;
		case SUBMENU:
			hliMenuItem(SUBMENU, LEFT, pInfo->pIOsd);
			break;
		case SUBMENU_CHOICE:
			hliMenuItem(SUBMENU_CHOICE, LEFT, pInfo->pIOsd);
			break;
		case PARENTAL_CONTROL_MENU:
			hliMenuItem(PARENTAL_CONTROL_MENU, LEFT, pInfo->pIOsd);
			break;
		default:
			break;
	}
	return ind;
}

/* Returns index of the new menu */

int down(int menuInd, INFO *pInfo) {

	int ind = menuInd;

	switch(ind) {
		case MAIN:
			hliMenuItem(MAIN, DOWN, pInfo->pIOsd);
			break;
		case SUBMENU:
			hliMenuItem(SUBMENU, DOWN, pInfo->pIOsd);
			break;
		case SUBMENU_CHOICE:
			hliMenuItem(SUBMENU_CHOICE, DOWN, pInfo->pIOsd);
			break;
		case PARENTAL_CONTROL_MENU:
			hliMenuItem(PARENTAL_CONTROL_MENU, DOWN, pInfo->pIOsd);
			break;
		default:
			break;
	}
	return ind;
}

/* Returns index of the new menu */

int up(int menuInd, INFO *pInfo) {

	int ind = menuInd;

	switch(ind) {
		case MAIN:
			hliMenuItem(MAIN, UP, pInfo->pIOsd);
			break;
		case SUBMENU:
			hliMenuItem(SUBMENU, UP, pInfo->pIOsd);
			break;
		case SUBMENU_CHOICE:
			hliMenuItem(SUBMENU_CHOICE, UP, pInfo->pIOsd);
			break;
		case PARENTAL_CONTROL_MENU:
			hliMenuItem(PARENTAL_CONTROL_MENU, UP, pInfo->pIOsd);
			break;
		default:
			break;
	}
	return ind;
}

/* Returns pointer to the highlighted menu item */

void hliMenuItem(int menuInd, int neighbour, IOsd *pIOsd) {

	Menu *tmp = &(g_menusDesc[menuInd]);
	mI *menuIt = &(tmp->menuItemsList[tmp->hliItemIndex]);


/*** temporarily hack to disable some menu items ***/

	if(menuInd == SUBMENU) {
		if(g_menusDesc[SUBMENU].name == AUDIO) {
			if(!tmp->hliItemIndex) {
				SET_HIGHLIGHT(pIOsd, &(tmp->menuItemsList[1].wnd), g_sw, g_sh);
				tmp->hliItemIndex = 1;
				return;
			}
			else if(tmp->hliItemIndex == 1) {
				SET_HIGHLIGHT(pIOsd, &(tmp->menuItemsList[0].wnd), g_sw, g_sh);
				tmp->hliItemIndex = 0;
				return;
			}
		}
		else if(g_menusDesc[SUBMENU].name == VIDEO) {
#ifdef PRINCETON
			if((tmp->hliItemIndex == 7) && (neighbour == UP || neighbour == LEFT)) {
				SET_HIGHLIGHT(pIOsd, &(tmp->menuItemsList[5].wnd), g_sw, g_sh);
				tmp->hliItemIndex = 5;
				return;
			}
			else if((tmp->hliItemIndex == 5) && (neighbour == DOWN || neighbour == RIGHT)) {
				SET_HIGHLIGHT(pIOsd, &(tmp->menuItemsList[7].wnd), g_sw, g_sh);
				tmp->hliItemIndex = 7;
				return;
			}
#else
			if(!(tmp->hliItemIndex) && (neighbour == UP || neighbour == LEFT)) {
				SET_HIGHLIGHT(pIOsd, &(tmp->menuItemsList[5].wnd), g_sw, g_sh);
				tmp->hliItemIndex = 5;
				return;
			}
			else if((tmp->hliItemIndex == 5) && (neighbour == DOWN || neighbour == RIGHT)) {
				SET_HIGHLIGHT(pIOsd, &(tmp->menuItemsList[0].wnd), g_sw, g_sh);
				tmp->hliItemIndex = 0;
				return;
			}
#endif
		}
		else if(g_menusDesc[SUBMENU].name == LANG) {
			if(!tmp->hliItemIndex && (neighbour == UP || neighbour == LEFT)) {
				SET_HIGHLIGHT(pIOsd, &(tmp->menuItemsList[3].wnd), g_sw, g_sh);
				tmp->hliItemIndex = 3;
				return;
			}
			else if((tmp->hliItemIndex == 3) && (neighbour == DOWN || neighbour == RIGHT)) {
				SET_HIGHLIGHT(pIOsd, &(tmp->menuItemsList[0].wnd), g_sw, g_sh);
				tmp->hliItemIndex = 0;
				return;
			}
		}
	}

/****************************************/

	switch(neighbour) {
		case UP:
			SET_HIGHLIGHT(pIOsd, &(tmp->menuItemsList[menuIt->uNeig].wnd), g_sw, g_sh);
			tmp->hliItemIndex = menuIt->uNeig;
			return;
		case DOWN:
			SET_HIGHLIGHT(pIOsd, &(tmp->menuItemsList[menuIt->dNeig].wnd), g_sw, g_sh);
			tmp->hliItemIndex = menuIt->dNeig;
			return;
		case LEFT:
			SET_HIGHLIGHT(pIOsd, &(tmp->menuItemsList[menuIt->lNeig].wnd), g_sw, g_sh);
			tmp->hliItemIndex = menuIt->lNeig;
			return;
		case RIGHT:
			SET_HIGHLIGHT(pIOsd, &(tmp->menuItemsList[menuIt->rNeig].wnd), g_sw, g_sh);
			tmp->hliItemIndex = menuIt->rNeig;
			return;
		default:
			SET_HIGHLIGHT(pIOsd, &(menuIt->wnd), g_sw, g_sh);
			return;
	}
}

/**********************************************************/
/****************** Creation of the menu ******************/
/**********************************************************/

/* Returns number of menu items */

int createMainMenu(IRma *pIRma, PBYTE *bmp) {

	RMASIZE textsize;
	RMAALIGNMENT al;
	ULONG size;
	DWORD width, height;
	RMAYUVENTRY *pPalette;
	RMAPOINT pos1;
	PBYTE p1 = NULL;
	BYTE i;
	RMARECT rect;
	PBYTE arr[3] = {/*onscreen_menu, */spoken_language,  tv, audio_setup};
	char str[30];
	char arrStr[3][15] = {"LANGUAGE SETUP", "VIDEO SETUP", "AUDIO SETUP"};

	IRma_CreateDC(pIRma, COMPRESSMODE_SEVEN_BPP, MENU_WINDOW_WIDTH, MENU_WINDOW_HEIGHT, 0x7f);
	IRma_GetPaletteFromBitmap(pIRma, (HRMABITMAP)audio_setup,
	                          (PBYTE *)(&pPalette), (LONG *)(&size));
	IRma_SetPalette(pIRma, (HRMABITMAP) NULL, pPalette, 0, 256);
	IRma_SetPen(pIRma, RMAPEN_SOLID, 0x7e, 1);

/* TEXT */

	IRma_SetTextStyle(pIRma, RMAOPAQUE);
	IRma_SetTextColor(pIRma, 0x2a);
	IRma_SetTextBackground(pIRma, 0x7f);
	al = ALIGNLEFT|ALIGNCENTER;

	IRma_SetFont(pIRma, &MAIN_MENU_HEADER_FONT);

	sprintf(str, "SETUP MENU");
	IRma_GetTextSize(pIRma,str, &textsize, &MAIN_MENU_HEADER_FONT, 0);
	rect.left = LEFT_HEADER_INDENT;
	rect.right = rect.left + textsize.width;
	rect.top = TOP_HEADER_INDENT;
	rect.bottom = rect.top + textsize.height;
	IRma_RMADrawText(pIRma, str, rect, al, 0);

	IRma_SetFont(pIRma, &MAIN_MENU_ITEMS_FONT);

	for(i = 1; i < 4; i++) {
		IRma_GetTextSize(pIRma, arrStr[i - 1], &textsize, &MAIN_MENU_ITEMS_FONT, 0);
		rect.left = MAIN_MENU_ITEMS_TEXT_INDENT;
		rect.right = rect.left + textsize.width;
		rect.top = g_menusDesc[MAIN].menuItemsList[i].wnd.y +
		           ((g_menusDesc[MAIN].menuItemsList[i].wnd.h - textsize.height) >> 1);
		rect.bottom = rect.top + textsize.height;
		IRma_RMADrawText(pIRma, arrStr[i - 1], rect, al, 0);
	}

/* Bitmaps */

	size = 0;

	for(i = 1; i < 4; i++) {
		ULONG size1;
		width = (((DWORD)(arr[i - 1][4])) << 8) | arr[i - 1][5];
		height = (((DWORD)(arr[i - 1][6])) << 8) | arr[i - 1][7];
		if((width * height + 1032) > size) {
			size = width * height + 1032;
			if(p1) initPoi((void **)(&p1));
			if(!(p1 = (PBYTE)OSCelMalloc(size))) {
				DPRINT(("Not enough memory\n"));
				IRma_DestroyDC(pIRma);
				return -1;
			}
		}
		memcpy(p1, arr[i - 1], size);

		pos1.x = MAIN_MENU_ITEMS_BMP_INDENT;
		pos1.y = g_menusDesc[MAIN].menuItemsList[i].wnd.y +
		         ((g_menusDesc[MAIN].menuItemsList[i].wnd.h - height) >> 1);
		IRma_LockRmaOSD(pIRma, (HRMABITMAP)p1, (PBYTE *)(&p1), &size1);
		rect.left = 0;
		rect.right = width;
		rect.top = 0;
		rect.bottom = height;
		IRma_BitBlt(pIRma, pIRma, (HRMABITMAP)p1, (HRMABITMAP) NULL, pos1, rect, RMASRCCOPY, 0);
		rect.left = g_menusDesc[MAIN].menuItemsList[i].wnd.x;
		rect.right = rect.left + g_menusDesc[MAIN].menuItemsList[i].wnd.w;
		rect.top = g_menusDesc[MAIN].menuItemsList[i].wnd.y;
		rect.bottom = rect.top + g_menusDesc[MAIN].menuItemsList[i].wnd.h;
		IRma_DrawRectangle(pIRma, rect, 0);
	}

/* select icon */

	initPoi((void **)(&p1));
	width = (((DWORD)(controller[4])) << 8) | controller[5];
	height = (((DWORD)(controller[6])) << 8) | controller[7];
	size = width * height + 1032;
	if(!(p1 = (PBYTE)OSCelMalloc(size))) {
		DPRINT(("Not enough memory\n"));
		IRma_DestroyDC(pIRma);
		return -1;
	}
	memcpy(p1, controller, size);
	pos1.x = MAIN_MENU_CNTR_BMP_POS_LEFT;
	pos1.y = MAIN_MENU_CNTR_BMP_POS_BOTTOM - height;
	IRma_LockRmaOSD(pIRma, (HRMABITMAP)p1, (PBYTE *)(&p1), &size);
	rect.left = 0;
	rect.right = width;
	rect.top = 0;
	rect.bottom = height;
	IRma_BitBlt(pIRma, pIRma, (HRMABITMAP)p1, (HRMABITMAP)NULL, pos1, rect, RMASRCCOPY, 0);

/* Text */

	IRma_SetFont(pIRma, &MAIN_MENU_SELECT_EXIT_FONT);

	sprintf(str, "To Select");
	IRma_GetTextSize(pIRma,str, &textsize, &MAIN_MENU_SELECT_EXIT_FONT, 0);
	rect.left = pos1.x + ((width - textsize.width) >> 1);
	rect.right = rect.left + textsize.width;
	rect.bottom = MAIN_MENU_EXIT_CNTR_TEXT_POS_BOTTOM;
	rect.top = rect.bottom - textsize.height;
	IRma_RMADrawText(pIRma, str, rect, al, 0);

/* exit icon */

	initPoi((void **)(&p1));
	width = (((DWORD)(menu_button[4])) << 8) | menu_button[5];
	height = (((DWORD)(menu_button[6])) << 8) | menu_button[7];
	size = width * height + 1032;
	if(!(p1 = (PBYTE)OSCelMalloc(size))) {
		DPRINT(("Not enough memory\n"));
		IRma_DestroyDC(pIRma);
		return -1;
	}
	memcpy(p1, menu_button, size);
	pos1.x = MAIN_MENU_EXIT_BMP_POS_LEFT;
	pos1.y = MAIN_MENU_EXIT_BMP_POS_BOTTOM - height;
	IRma_LockRmaOSD(pIRma, (HRMABITMAP)p1, (PBYTE *)(&p1), &size);
	rect.left = 0;
	rect.right = width;
	rect.top = 0;
	rect.bottom = height;
	IRma_BitBlt(pIRma, pIRma, (HRMABITMAP)p1, (HRMABITMAP)NULL, pos1, rect, RMASRCCOPY, 0);

/* Text */

	sprintf(str, "Exit");
	IRma_GetTextSize(pIRma,str, &textsize, &MAIN_MENU_SELECT_EXIT_FONT, 0);
	rect.left = pos1.x + ((width - textsize.width) >> 1);
	rect.right = rect.left + textsize.width;
	rect.bottom = MAIN_MENU_EXIT_CNTR_TEXT_POS_BOTTOM;
	rect.top = rect.bottom - textsize.height;
	IRma_RMADrawText(pIRma, str, rect, al, 0);

/* Clean up */

	initPoi((void **)(&p1));
	IRma_LockRmaOSD(pIRma, (HRMABITMAP)NULL, (PBYTE *)(&p1), &size);

	if(!(*bmp = (PBYTE)OSCelMalloc(size))) {
		DPRINT(("Not enough memory\n"));
		IRma_DestroyDC(pIRma);
		return -1;
	}
	memcpy((void *)(*bmp), (void *)p1, size);
	IRma_DestroyDC(pIRma);
	return 0;
}

int createARSubmenu(IRma *pIRma, PBYTE *bmp) {

	RMASIZE textsize;
	RMAALIGNMENT al;
	ULONG size;
	DWORD width, height;
	RMAYUVENTRY *pPalette;
	RMAPOINT pos1;
	PBYTE p1;
	BYTE i;
	RMARECT rect;
	char str[30];
	PBYTE arrBit[4] = {standard_fullscreen, standard_letterbox,
	                   widescreen_fullscreen, widescreen_letterbox};
	PBYTE arrStr[4] = {"PAN&SCAN", "LETTERBOX", "ZOOM ON", "ZOOM OFF"};

	g_menusDesc[SUBMENU_CHOICE].prev = SUBMENU;

	IRma_CreateDC(pIRma, COMPRESSMODE_SEVEN_BPP, MENU_WINDOW_WIDTH, MENU_WINDOW_HEIGHT, 0x7f);
	IRma_GetPaletteFromBitmap(pIRma, (HRMABITMAP)audio_setup,
	                          (PBYTE *)(&pPalette), (LONG *)(&size));
	IRma_SetPalette(pIRma, (HRMABITMAP) NULL, pPalette, 0, 256);
	IRma_SetPen(pIRma, RMAPEN_SOLID, 0x7e, 1);

	p1 = tv;
	width = (((DWORD)(p1[4])) << 8) | p1[5];
	height = (((DWORD)(p1[6])) << 8) | p1[7];
	IRma_LockRmaOSD(pIRma, (HRMABITMAP)p1, &p1, &size);
	pos1.x = LEFT_HEADER_INDENT;
	pos1.y = TOP_HEADER_INDENT;
	rect.left = 0;
	rect.right = width;
	rect.top = 0;
	rect.bottom = height;
	IRma_BitBlt(pIRma, pIRma, (HRMABITMAP)p1, (HRMABITMAP)NULL, pos1, rect, RMASRCCOPY, 0);
	IRma_UnLockRmaOSD(pIRma, (HRMABITMAP)p1, &p1, &size);

// TEXT

	IRma_SetTextStyle(pIRma, RMAOPAQUE);
	IRma_SetTextColor(pIRma, 0x2a);
	IRma_SetTextBackground(pIRma, 0x7f);
	al = ALIGNMIDDLE|ALIGNCENTER;

	IRma_SetFont(pIRma, &AR_MENU_HEADER_FONT);

	sprintf(str, "ASPECT RATIO");
	IRma_GetTextSize(pIRma,str, &textsize, &AR_MENU_HEADER_FONT, 0);
	rect.left = TEXT_HEADER_INDENT;
	rect.right = rect.left + textsize.width;
	rect.top = TOP_HEADER_INDENT + ((height - textsize.height) >> 1);
	rect.bottom = rect.top + textsize.height;
	IRma_RMADrawText(pIRma, str, rect, al, 0);

// Bitmaps

	IRma_SetFont(pIRma, &AR_MENU_CHOICES_FONT);
	al = ALIGNMIDDLE|ALIGNCENTER;
	width = (((DWORD)(p1[4])) << 8) | p1[5];
	height = (((DWORD)(p1[6])) << 8) | p1[7];

	for(i = 0; i < 4; i++) {
		p1 = arrBit[i];
		IRma_LockRmaOSD(pIRma, (HRMABITMAP)p1, &p1, &size);
		pos1.x = AR_MENU_ITEMS_X_ALIGNMENT_MIDDLE - (width >> 1) +
		         AR_MENU_ITEMS_WIDTH * (i & 1);
		pos1.y = AR_MENU_FIRST_ITEM_Y_ALIGNMENT_TOP * ((i >> 1) + 1);
		rect.left = 0;
		rect.right = width;
		rect.top = 0;
		rect.bottom = height;
		IRma_BitBlt(pIRma, pIRma, (HRMABITMAP)p1, (HRMABITMAP)NULL, pos1, rect, RMASRCCOPY, 0);
		IRma_UnLockRmaOSD(pIRma, (HRMABITMAP)p1, &p1, &size);
		IRma_GetTextSize(pIRma,arrStr[i], &textsize, &AR_MENU_CHOICES_FONT, 0);
		rect.left = AR_MENU_ITEMS_X_ALIGNMENT_MIDDLE - (textsize.width >> 1) +
		            AR_MENU_ITEMS_WIDTH * (i & 1);
		rect.right = rect.left + textsize.width;
		rect.top = pos1.y + width + AR_MENU_ITEMS_TEXT_Y_INDENT;
		rect.bottom = rect.top + textsize.height;
		IRma_RMADrawText(pIRma, arrStr[i], rect, al, 0);
		rect.left = AR_MENU_ITEMS_X_ALIGNMENT_MIDDLE - (AR_MENU_ITEMS_WIDTH >> 1) +
		            AR_MENU_ITEMS_WIDTH * (i & 1);
		rect.right = rect.left + AR_MENU_ITEMS_WIDTH;
		rect.top = AR_MENU_FIRST_ITEM_Y_ALIGNMENT_TOP * ((i >> 1) + 1) - AR_MENU_ITEMS_BMP_Y_INDENT;
		rect.bottom = rect.top + AR_MENU_ITEMS_HEIGHT;
		IRma_DrawRectangle(pIRma, rect, 0);
		SET_OSD_WINDOW(g_menusDesc[SUBMENU_CHOICE].menuItemsList[i + 1].wnd,
		               rect.left, rect.top, AR_MENU_ITEMS_WIDTH, AR_MENU_ITEMS_HEIGHT, LEFT_TOP);
		g_menusDesc[SUBMENU_CHOICE].menuItemsList[i + 1].rNeig = (i & 2) + 2;
		g_menusDesc[SUBMENU_CHOICE].menuItemsList[i + 1].lNeig = (i & 2) + 1;
	}

	g_menusDesc[SUBMENU_CHOICE].menuItemsList[0].rNeig = 0;
	g_menusDesc[SUBMENU_CHOICE].menuItemsList[0].lNeig = 0;
	g_menusDesc[SUBMENU_CHOICE].menuItemsList[0].dNeig = 1;
	g_menusDesc[SUBMENU_CHOICE].menuItemsList[0].uNeig = 3;
	g_menusDesc[SUBMENU_CHOICE].menuItemsList[1].dNeig = 3;
	g_menusDesc[SUBMENU_CHOICE].menuItemsList[1].uNeig = 0;
	g_menusDesc[SUBMENU_CHOICE].menuItemsList[2].dNeig = 4;
	g_menusDesc[SUBMENU_CHOICE].menuItemsList[2].uNeig = 0;
	g_menusDesc[SUBMENU_CHOICE].menuItemsList[3].dNeig = 0;
	g_menusDesc[SUBMENU_CHOICE].menuItemsList[3].uNeig = 1;
	g_menusDesc[SUBMENU_CHOICE].menuItemsList[4].dNeig = 0;
	g_menusDesc[SUBMENU_CHOICE].menuItemsList[4].uNeig = 2;
	g_menusDesc[SUBMENU_CHOICE].menuItemsNumber = 4;

	sprintf(str, "Back to the previous menu");
	IRma_GetTextSize(pIRma,str, &textsize, &MENUS_BACK_BUTTON_FONT, 0);
	rect.left = BACK_BUTTON_ALIGNMENT_X_MIDDLE - (textsize.width >> 1);
	rect.right = rect.left + textsize.width;
	rect.bottom = BACK_BUTTON_ALIGNMENT_Y_BOTTOM;
	rect.top = rect.bottom - textsize.height;
	IRma_RMADrawText(pIRma, str, rect, ALIGNMIDDLE|ALIGNCENTER, 0);
	IRma_DrawRectangle(pIRma, rect, 0);
	SET_OSD_WINDOW(g_menusDesc[SUBMENU_CHOICE].menuItemsList[0].wnd,
	               rect.left, rect.top, textsize.width, textsize.height, LEFT_TOP);

// menu items categories

	IRma_SetFont(pIRma, &AR_MENU_ITEMS_FONT);
	al = ALIGNRIGHT|ALIGNCENTER;

	sprintf(str, "4:3\nNORMAL TV");
	if(IRma_GetTextSize(pIRma,str, &textsize, &AR_MENU_ITEMS_FONT, 0) != Q_OK) {
		IRma_DestroyDC(pIRma);
		return -1;
	}
	rect.right = AR_MENU_HEADERS_INDENT_RIGHT;
	rect.left = rect.right - textsize.width;
	rect.top = g_menusDesc[SUBMENU_CHOICE].menuItemsList[1].wnd.y +
	           ((g_menusDesc[SUBMENU_CHOICE].menuItemsList[1].wnd.h - textsize.height) >> 1);
	rect.bottom = rect.top + textsize.height;
	if(IRma_RMADrawText(pIRma, str, rect, al, 0) != Q_OK) {
		IRma_DestroyDC(pIRma);
		return -1;
	}

	sprintf(str, "16:9\nWIDE TV");
	if(IRma_GetTextSize(pIRma,str, &textsize, &AR_MENU_ITEMS_FONT, 0) != Q_OK) {
		IRma_DestroyDC(pIRma);
		return -1;
	}
	rect.left = rect.right - textsize.width;
	rect.top = g_menusDesc[SUBMENU_CHOICE].menuItemsList[3].wnd.y +
	           ((g_menusDesc[SUBMENU_CHOICE].menuItemsList[3].wnd.h - textsize.height) >> 1);
	rect.bottom = rect.top + textsize.height;
	if(IRma_RMADrawText(pIRma, str, rect, al, 0) != Q_OK) {
		IRma_DestroyDC(pIRma);
		return -1;
	}

// Clean up

	IRma_LockRmaOSD(pIRma, (HRMABITMAP)NULL, (PBYTE *)(&p1), &size);

	if(!(*bmp = (PBYTE)OSCelMalloc(size))) {
		DPRINT(("Not enough memory\n"));
		IRma_DestroyDC(pIRma);
		return -1;
	}
	memcpy((void *)(*bmp), (void *)p1, size);
	IRma_DestroyDC(pIRma);
	return 0;
}

int createSubmenu(IRma *pIRma, PBYTE *bmp) {

	RMASIZE textsize;
	RMAALIGNMENT al;
	ULONG size;
	DWORD width, height;
	RMAYUVENTRY *pPalette;
	RMAPOINT pos1;
	PBYTE p1;
	BYTE t, i, strSize = 18, mInd = SUBMENU, ind = g_menusDesc[SUBMENU].name;
	RMARECT rect;
	char str[65];
	char *arrStr;
	char lArrStr[4][18] = {"AUDIO:", "SUBTITLE:", "DVD MENU:", "OSD:"};
	char vArrStr[7][18] = {"SCREEN MODE:", "ASPECT RATIO:", "AUTOPLAY:",
	                       "PARENTAL CONTROL:", "PASSWORD:", "SCREENSAVER:"
#ifdef PRINCETON
	                       , "FRONT PANEL:"
#endif
	                      };
	char aArrStr[4][18] = {"AUDIO TYPE:", "TRACK SELECTION:", "SURROUND:", "AUTO DRC:"};
	char pArrStr[2][18] = {"LEVEL:", "STANDARD:"};

	switch(ind) {
		case LANG:
			p1 = spoken_language;
			sprintf(str, "LANGUAGE SETUP");
			arrStr = (char *)lArrStr;
			t = 5;
			break;
		case VIDEO:
			p1 = tv;
			sprintf(str, "VIDEO SETUP");
			arrStr = (char *)vArrStr;
#ifdef PRINCETON
			t = 8;
#else
			t = 7;
#endif
			break;
		case AUDIO:
			p1 = audio_setup;
			sprintf(str, "AUDIO SETUP");
			arrStr = (char *)aArrStr;
			t = 5;
			break;
		case PARENTAL_CONTROL_MENU:
			mInd = PARENTAL_CONTROL_MENU;
			g_menusDesc[SUBMENU].name = VIDEO;
			p1 = rating;
			sprintf(str, "PARENTAL CONTROL");
			arrStr = (char *)pArrStr;
			t = 3;
			break;
	}

	IRma_CreateDC(pIRma, COMPRESSMODE_SEVEN_BPP, MENU_WINDOW_WIDTH, MENU_WINDOW_HEIGHT, 0x7f);
	IRma_GetPaletteFromBitmap(pIRma, (HRMABITMAP)audio_setup,
	                          (PBYTE *)(&pPalette), (LONG *)(&size));
	IRma_SetPalette(pIRma,(HRMABITMAP) NULL, pPalette, 0, 256);
	IRma_SetPen(pIRma, RMAPEN_SOLID, 0x7e, 1);

	width = (((DWORD)(p1[4])) << 8) | p1[5];
	height = (((DWORD)(p1[6])) << 8) | p1[7];
	IRma_LockRmaOSD(pIRma, (HRMABITMAP)p1, &p1, &size);
	pos1.x = LEFT_HEADER_INDENT;
	pos1.y = TOP_HEADER_INDENT;
	rect.left = 0;
	rect.right = width;
	rect.top = 0;
	rect.bottom = height;
	IRma_BitBlt(pIRma, pIRma, (HRMABITMAP)p1, (HRMABITMAP)NULL, pos1, rect, RMASRCCOPY, 0);
	IRma_UnLockRmaOSD(pIRma, (HRMABITMAP)p1, &p1, &size);

/* TEXT */

	IRma_SetTextStyle(pIRma, RMAOPAQUE);
	IRma_SetTextColor(pIRma, 0x2a);
	IRma_SetTextBackground(pIRma, 0x7f);
	al = ALIGNMIDDLE|ALIGNCENTER;

	IRma_SetFont(pIRma, &SUBMENU_HEADER_FONT);

	IRma_GetTextSize(pIRma,str, &textsize, &SUBMENU_HEADER_FONT, 0);
	rect.left = TEXT_HEADER_INDENT;
	rect.right = rect.left + textsize.width;
	rect.top = TOP_HEADER_INDENT + ((height - textsize.height) >> 1);
	rect.bottom = rect.top + textsize.height;
	IRma_RMADrawText(pIRma, str, rect, al, 0);

	IRma_SetFont(pIRma, &SUBMENU_ITEMS_FONT);

	al = ALIGNLEFT|ALIGNCENTER;

	for(i = 0; i < (t - 1); i++) {
		IRma_GetTextSize(pIRma,arrStr, &textsize, &SUBMENU_ITEMS_FONT, 0);
		rect.left = SUBMENU_ITEMS_TEXT_X_ALIGNMENT;
		rect.right = rect.left + textsize.width;
		rect.top = SUBMENU_FIRST_ITEM_Y_ALIGNMENT_TOP +
		           ((SUBMENU_ITEMS_HEIGHT - textsize.height) >> 1) +
		           i * SUBMENU_ITEMS_HEIGHT;
		rect.bottom = rect.top + textsize.height;
		IRma_RMADrawText(pIRma, arrStr, rect, al, 0);

		rect.left = SUBMENU_ITEMS_X_ALIGNMENT_LEFT;
		rect.right = rect.left + SUBMENU_ITEMS_WIDTH;
		rect.top = SUBMENU_FIRST_ITEM_Y_ALIGNMENT_TOP + i * SUBMENU_ITEMS_HEIGHT;
		rect.bottom = rect.top + SUBMENU_ITEMS_HEIGHT;
		IRma_DrawRectangle(pIRma, rect, 0);
		SET_OSD_WINDOW(g_menusDesc[mInd].menuItemsList[i + 1].wnd,
		               rect.left, rect.top,
		               rect.right - rect.left, rect.bottom - rect.top, LEFT_TOP);
		g_menusDesc[mInd].menuItemsList[i].uNeig = (!i) ? (t - 1) : (i - 1);
		g_menusDesc[mInd].menuItemsList[i].dNeig = i + 1;
		g_menusDesc[mInd].menuItemsList[i].lNeig = (!i) ? (t - 1) : (i - 1);
		g_menusDesc[mInd].menuItemsList[i].rNeig = i + 1;
		arrStr += strSize;
	}
	g_menusDesc[mInd].menuItemsList[t - 1].uNeig = t - 2;
	g_menusDesc[mInd].menuItemsList[t - 1].dNeig = 0;
	g_menusDesc[mInd].menuItemsList[t - 1].lNeig = t - 2;
	g_menusDesc[mInd].menuItemsList[t - 1].rNeig = 0;
	g_menusDesc[mInd].menuItemsNumber = t - 1;

	sprintf(str, "Back to the previous menu");
	IRma_SetFont(pIRma, &MENUS_BACK_BUTTON_FONT);
	IRma_GetTextSize(pIRma,str, &textsize, &MENUS_BACK_BUTTON_FONT, 0);
	rect.left = BACK_BUTTON_ALIGNMENT_X_MIDDLE - (textsize.width >> 1);
	rect.right = rect.left + textsize.width;
	rect.bottom = BACK_BUTTON_ALIGNMENT_Y_BOTTOM;
	rect.top = rect.bottom - textsize.height;
	IRma_RMADrawText(pIRma, str, rect, ALIGNMIDDLE|ALIGNCENTER, 0);
	IRma_DrawRectangle(pIRma, rect, 0);
	SET_OSD_WINDOW(g_menusDesc[mInd].menuItemsList[0].wnd,
	               rect.left, rect.top, textsize.width, textsize.height, LEFT_TOP);

// Clean up

	IRma_LockRmaOSD(pIRma, (HRMABITMAP)NULL, (PBYTE *)(&p1), &size);

	if(!(*bmp = (PBYTE)OSCelMalloc(size))) {
		DPRINT(("Not enough memory\n"));
		IRma_DestroyDC(pIRma);
		return -1;
	}
	memcpy((void *)(*bmp), (void *)p1, size);
	IRma_DestroyDC(pIRma);

#ifdef PRINCETON
	if(ind == VIDEO)
		t--;
#endif
	p1 = str;
	memset(str, 0, 65);

	for(i = 1; i < t; i++) {
		int k = 0;
		while(1) {
			switch(ind) {
				case VIDEO:
					*p1 = videoMenuArr[i - 1][(int)(g_menusDesc[mInd].menuItemsList[i].value) - 1][k];
					break;
				case LANG:
					*p1 = langMenuArr[i - 1][(int)(g_menusDesc[mInd].menuItemsList[i].value) - 1][k];
					break;
				case AUDIO:
					*p1 = audioMenuArr[i - 1][(int)(g_menusDesc[mInd].menuItemsList[i].value) - 1][k];
					break;
				case PARENTAL_CONTROL_MENU:
					*p1 = passwordMenuArr[i - 1][(int)(g_menusDesc[mInd].menuItemsList[i].value) - 1][k];
					break;
			}
			if(ind == PARENTAL_CONTROL_MENU && i == 1 && k == 2 &&
			   g_menusDesc[ind].menuItemsList[2].value == 2 &&
			   g_menusDesc[ind].menuItemsList[1].value != 1)
				*p1 = 0;
			p1++;
			if(!(p1[-1])) {
				if(((p1 - 1) == (PBYTE)str) || (p1[-2] == 10)) p1--;
				else p1[-1] = 10;
				break;
			}
			k++;
		};
	}
	p1[-1] = 0;
	textsize.width = SUBMENU_LIST_MAX_WIDTH;
	textsize.height = SUBMENU_LIST_MAX_HEIGHT;
	al = ALIGNRIGHT|ALIGNCENTER;
	p1 = createMenuList(pIRma, &textsize, &SUBMENU_CHOICES_FONT, 0x7f, al, str,
	                    SUBMENU_ITEMS_HEIGHT - SUBMENU_CHOICES_FONT.m_wHeight);
	rect.left = rect.top = 0;
	rect.right = textsize.width;
	rect.bottom = textsize.height;
	pos1.x = MENU_WINDOW_WIDTH - SUBMENU_ITEMS_TEXT_X_ALIGNMENT - textsize.width;
	pos1.y = SUBMENU_FIRST_ITEM_Y_ALIGNMENT_TOP +
	         ((SUBMENU_ITEMS_HEIGHT - SUBMENU_CHOICES_FONT.m_wHeight) >> 1);
	if(p1) {
		IRma_LockRmaOSD(pIRma, (HRMABITMAP)p1, &p1, &size);
		IRma_LockRmaOSD(pIRma, (HRMABITMAP)(*bmp), bmp, &size);
		IRma_BitBlt(pIRma, NULL, (HRMABITMAP)p1, (HRMABITMAP)(*bmp),
		          pos1, rect, RMASRCCOPY, 0);
		initPoi((void **)(&p1));
		IRma_UnLockRmaOSD(pIRma, (HRMABITMAP)(*bmp), bmp, &size);
		return 0;
	}
	else
		return -1;
}

int createChoiceSubmenu(IRma *pIRma, PBYTE *bmp) {

	BYTE string[80] = "ENGLISH\nFRENCH\nSPANISH\nITALIAN\nGERMAN\nDUTCH\nPORTUGUESE\nCHINESE\nJAPANESE\nOTHERS";
	BYTE str[170], ind = g_menusDesc[SUBMENU].name, menuInd = SUBMENU;
	RMASIZE size;
	RMAALIGNMENT al = ALIGNRIGHT|ALIGNCENTER;
	PBYTE p1 = NULL, p2;
	ULONG size1, width, height;
	RMAPOINT pos1;
	RMAYUVENTRY *pPalette;
	RMARECT rect;
	int n, i;

//form the string
	memset(str, 0, 170);
	switch(ind) {
		case LANG:
			switch(g_menusDesc[SUBMENU].hliItemIndex) {
				case 1:
					sprintf(str, "ORIGINAL\n");
					memcpy(str + 9, string, 78);
					n = 11;
					break;
				case 2:
					sprintf(str, "AUDIO FOLLOW\n");
					memcpy(str + 13, string, 78);
					n = 11;
					break;
				case 3:
					memcpy(str, string, 78);
					n = 10;
					break;
				case 4:
					memcpy(str, string, 22);
					n = 3;
					break;
			}
			break;
		case VIDEO:
			if(g_Pass == 0xffffffff)
				videoMenuArr[4][2] = NULL;
			else
				videoMenuArr[4][2] = vChange;
			p1 = str;
			for(i = 0; (i < 12) && (videoMenuArr[g_menusDesc[SUBMENU].hliItemIndex - 1][i]); i++) {
				int k = 0;
				while(1) {
					*p1 = videoMenuArr[g_menusDesc[SUBMENU].hliItemIndex - 1][i][k];
					p1++;
					if(!(p1[-1])) {
						if(((p1 - 1) == str) || (p1[-2] == 10)) p1--;
						else p1[-1] = 10;
						break;
					}
					k++;
				}
			}
			p1[-1] = 0;
			n = i;
			break;
		case AUDIO:
			p1 = str;
			n = 2;
			for(i = 0; i < 2; i++) {
				int k = 0;
				while(1) {
					*p1 = audioMenuArr[g_menusDesc[SUBMENU].hliItemIndex - 1][i][k];
					p1++;
					if(!(p1[-1])) {
						if(((p1 - 1) == str) || (p1[-2] == 10)) p1--;
						else p1[-1] = 10;
						break;
					}
					k++;
				}
			}
			p1[-1] = 0;
			break;
		case PARENTAL_CONTROL_MENU:
			g_menusDesc[SUBMENU].name = VIDEO;
			menuInd = PARENTAL_CONTROL_MENU;
			p1 = str;
			if(g_menusDesc[PARENTAL_CONTROL_MENU].menuItemsList[2].value == 1 ||
			   g_menusDesc[PARENTAL_CONTROL_MENU].hliItemIndex == 2) {
				for(i = 0; (i < 9) && (passwordMenuArr[g_menusDesc[PARENTAL_CONTROL_MENU].hliItemIndex - 1][i]); i++) {
					int k = 0;
					while(1) {
						*p1 = passwordMenuArr[g_menusDesc[PARENTAL_CONTROL_MENU].hliItemIndex - 1][i][k];
						p1++;
						if(!(p1[-1])) {
							if(((p1 - 1) == str) || (p1[-2] == 10)) p1--;
							else p1[-1] = 10;
							break;
						}
						k++;
					}
				}
			}
			else {
				p1[0] = passwordMenuArr[0][0][0];
				p1[1] = passwordMenuArr[0][0][1];
				p1[2] = passwordMenuArr[0][0][2];
				p1[3] = 10;
				p1 += 4;
				for(i = 1; i < 9; i++) {
					p1[0] = passwordMenuArr[0][i][0];
					p1[1] = passwordMenuArr[0][i][1];
					p1[2] = 10;
					p1 += 3;
				}
			}
			n = i;
			p1[-1] = 0;
			break;
	}

	p2 = g_menusDesc[menuInd].bmp;
	g_menusDesc[SUBMENU_CHOICE].prev = menuInd;

	size.width = SUBMENU_LIST_MAX_WIDTH;
	size.height = SUBMENU_LIST_MAX_HEIGHT -
	              SUBMENU_ITEMS_HEIGHT * (g_menusDesc[menuInd].hliItemIndex - 1);
	p1 = createMenuList(pIRma, &size, &CHOCE_SUBMENU_LIST_FONT, 0x7d, al, str, 0);

	if(p1) {
		OSD_WND *wnd;
		IRma_CreateDC(pIRma, COMPRESSMODE_SEVEN_BPP, MENU_WINDOW_WIDTH, MENU_WINDOW_HEIGHT, 0x7f);
		IRma_GetPaletteFromBitmap(pIRma, (HRMABITMAP)audio_setup,
		                          (PBYTE *)(&pPalette), (LONG *)(&size1));
		IRma_SetPalette(pIRma, (HRMABITMAP) NULL, pPalette, 0, 256);
		IRma_SetPen(pIRma, RMAPEN_SOLID, 0x7f, 1);

		pos1.x = 0;
		pos1.y = 0;
		IRma_LockRmaOSD(pIRma, (HRMABITMAP)p2, (PBYTE *)(&p2), (LONG *)(&size1));
		rect.left = 0;
		rect.right = MENU_WINDOW_WIDTH;
		rect.top = 0;
		rect.bottom = MENU_WINDOW_HEIGHT;
		IRma_BitBlt(pIRma, pIRma, (HRMABITMAP)p2, (HRMABITMAP)NULL, pos1, rect, RMASRCCOPY, 0);
		IRma_UnLockRmaOSD(pIRma, (HRMABITMAP)p2, (PBYTE *)(&p2), (LONG *)(&size1));

		wnd = &(g_menusDesc[menuInd].menuItemsList[g_menusDesc[menuInd].hliItemIndex].wnd);
		rect.left = MENU_WINDOW_WIDTH - SUBMENU_ITEMS_WIDTH - SUBMENU_ITEMS_X_ALIGNMENT_LEFT;
		rect.right = MENU_WINDOW_WIDTH;
		rect.top = wnd->y;
		rect.bottom = rect.top + wnd->h;
		IRma_DrawRectangle(pIRma, rect, 1);
		IRma_SetPen(pIRma, RMAPEN_SOLID, 0x7e, 1);

		width = (((DWORD)(p1[4])) << 8) | p1[5];
		height = (((DWORD)(p1[6])) << 8) | p1[7];
		pos1.x = MENU_WINDOW_WIDTH - SUBMENU_ITEMS_TEXT_X_ALIGNMENT - size.width;
		pos1.y = SUBMENU_FIRST_ITEM_Y_ALIGNMENT_TOP +
		         ((SUBMENU_ITEMS_HEIGHT - CHOCE_SUBMENU_LIST_FONT.m_wHeight) >> 1) +
		         SUBMENU_ITEMS_HEIGHT * (g_menusDesc[menuInd].hliItemIndex - 1);
		IRma_LockRmaOSD(pIRma, (HRMABITMAP)p1, (PBYTE *)(&p1), (LONG *)(&size1));
		rect.left = 0;
		rect.right = width;
		rect.top = 0;
		rect.bottom = height;
		IRma_BitBlt(pIRma, pIRma, (HRMABITMAP)p1, (HRMABITMAP)NULL, pos1, rect, RMASRCCOPY, 0);

		rect.left = pos1.x;
		rect.right = MENU_WINDOW_WIDTH - SUBMENU_ITEMS_TEXT_X_ALIGNMENT;
		IRma_SetPen(pIRma, RMAPEN_SOLID, 0x7c, 1);
		for(i = 0; i < n; i++) {
			rect.top = pos1.y + CHOCE_SUBMENU_LIST_FONT.m_wHeight * i;
			rect.bottom = rect.top + CHOCE_SUBMENU_LIST_FONT.m_wHeight;
			IRma_DrawRectangle(pIRma, rect, 0);
			SET_OSD_WINDOW(g_menusDesc[SUBMENU_CHOICE].menuItemsList[i + 1].wnd,
			               rect.left, rect.top, rect.right - rect.left, CHOCE_SUBMENU_LIST_FONT.m_wHeight, LEFT_TOP);
			g_menusDesc[SUBMENU_CHOICE].menuItemsList[i + 1].uNeig = (!i) ? 1 : i;
			g_menusDesc[SUBMENU_CHOICE].menuItemsList[i + 1].dNeig = ((i + 1) == n) ? n : (i + 2);
			g_menusDesc[SUBMENU_CHOICE].menuItemsList[i + 1].rNeig = i + 1;
			g_menusDesc[SUBMENU_CHOICE].menuItemsList[i + 1].lNeig = i + 1;
		}
		g_menusDesc[SUBMENU_CHOICE].menuItemsNumber = n;
		memset(&(g_menusDesc[SUBMENU_CHOICE].menuItemsList[0].rNeig), 1, 4);
		SET_OSD_WINDOW(g_menusDesc[SUBMENU_CHOICE].menuItemsList[0].wnd, 0, 0, 0, 0, LEFT_TOP);

/* Clean up */

		initPoi((void **)(&p1));
		IRma_LockRmaOSD(pIRma,(HRMABITMAP) NULL, (PBYTE *)(&p1), (LONG *)(&size1));
		if(!(*bmp = (PBYTE)OSCelMalloc(size1))) {
			DPRINT(("Not enough memory\n"));
			IRma_DestroyDC(pIRma);
			return -1;
		}
		memcpy((void *)(*bmp), (void *)p1, size1);
		IRma_DestroyDC(pIRma);
		return 0;
	}
	else {
		*bmp = NULL;
		return -1;
	}
}

/* Creation of the menu list */

PBYTE createMenuList(IRma *pIRma, RMASIZE *size, RMAFONT *pFont, RMACOLORINDEX color,
                     RMAALIGNMENT al, PBYTE list, int off) {

	RMASIZE textsize;
	ULONG size1;
	RMAYUVENTRY *pPalette;
	PBYTE p, p1;
	RMARECT rect;

	if(IRma_GetTextSize(pIRma,list, &textsize, pFont, (WORD) off) != Q_OK)
		return NULL;
	if((size->width < textsize.width) || (size->height < textsize.height))
		return NULL;
	else {
		size->width = textsize.width;
		size->height = textsize.height;
	}

	IRma_CreateDC(pIRma, COMPRESSMODE_SEVEN_BPP, (WORD) textsize.width, (WORD) textsize.height, color);
	IRma_GetPaletteFromBitmap(pIRma, (HRMABITMAP)audio_setup, (PBYTE *)(&pPalette), (LONG *)(&size1));
	IRma_SetPalette(pIRma,(HRMABITMAP) NULL, pPalette, 0, 256);

	IRma_SetTextStyle(pIRma, RMAOPAQUE);
	IRma_SetTextColor(pIRma, 0x2a);
	IRma_SetTextBackground(pIRma, color);

	IRma_SetFont(pIRma, pFont);

	rect.left = 0;
	rect.right = rect.left + textsize.width;
	rect.top = 0;
	rect.bottom = rect.top + textsize.height;
	if(IRma_RMADrawText(pIRma, list, rect, al, (WORD) off) != Q_OK)
		return NULL;

	IRma_LockRmaOSD(pIRma,(HRMABITMAP) NULL, (PBYTE *)(&p1), &size1);

	if(!(p = (PBYTE)OSCelMalloc(size1))) {
		DPRINT(("Not enough memory\n"));
		return NULL;
	}
	memcpy((void *)p, (void *)p1, size1);
	IRma_DestroyDC(pIRma);

	return p;
}


BOOL checkPassword(INFO *pInfo) {

	PBYTE bmp = createPasswordWindow(pInfo->pIRma, FALSE);
	BYTE buf[1];
	int c = 24;
	DWORD tmp = 0, bmpWidth, size1;
	RMARECT rect;
	RMAPOINT pos;
	BYTE str[2];
	RMASIZE size;
	PBYTE bmpX, bmpBl;
	OSD_WND wnd1;

	DISPLAY_OSD(pInfo->pIOsd, bmp, ((720 - PASSWORD_MENU_WINDOW_WIDTH) >> 1),
	            ((480 - PASSWORD_MENU_WINDOW_HEIGHT) >> 1), LEFT_TOP, g_sw, g_sh);
	bmpWidth = (DWORD)(bmp[4] << 8) | bmp[5];
	size.width = bmpWidth >> 2;
	size.height = ((DWORD)(bmp[6] << 8) | bmp[7]) - 40;
	sprintf(str, "X");
	bmpX = createMenuList(pInfo->pIRma, &size, &PASSWORD_MENU_INPUT_FONT, 0x7f, ALIGNMIDDLE|ALIGNCENTER, str, 0);
	IRma_LockRmaOSD(pInfo->pIRma, (HRMABITMAP)bmpX, (PBYTE *)(&bmpX), &size1);
	sprintf(str, "_");
	size.width++;
	size.height++;
	bmpBl = createMenuList(pInfo->pIRma, &size, &PASSWORD_MENU_INPUT_FONT, 0x7f, ALIGNMIDDLE|ALIGNCENTER, str, 0);
	IRma_LockRmaOSD(pInfo->pIRma, (HRMABITMAP)bmpBl, (PBYTE *)(&bmpBl), &size1);
	pos.y = PASSWORD_MENU_PASSWORD_FIELD_Y_INDENT;
	pos.x = (bmpWidth >> 1) - (size.width << 1);
	wnd1.x = pos.x; wnd1.y = pos.y; wnd1.w = size.width - 1; wnd1.h = size.height;
	SET_HIGHLIGHT(pInfo->pIOsd, &wnd1, g_sw, g_sh);
	rect.left = 0;
	rect.right = size.width;
	rect.top = 0;
	rect.bottom = size.height;
	
	do {
		if(OSGetMessage(pInfo->osdMsgQ, buf, 1) == ERROR) {
			DPRINT(("osdManager: error during reading message queue \n"));
			return FALSE;
		}
		if((buf[0] >= ZERO) && (buf[0] <= NINE) && (c > -8)) {
			tmp = tmp | ((DWORD)buf[0] << c);
			c -= 8;
			IRma_LockRmaOSD(pInfo->pIRma, (HRMABITMAP)bmp, (PBYTE *)(&bmp), &size1);
			IRma_BitBlt(pInfo->pIRma, NULL, (HRMABITMAP)bmpX, (HRMABITMAP)bmp, pos, rect, RMASRCCOPY, 0);
			IRma_UnLockRmaOSD(pInfo->pIRma, (HRMABITMAP)bmp, (PBYTE *)(&bmp), &size1);
			DISPLAY_OSD(pInfo->pIOsd, bmp, ((720 - PASSWORD_MENU_WINDOW_WIDTH) >> 1),
			            ((480 - PASSWORD_MENU_WINDOW_HEIGHT) >> 1), LEFT_TOP, g_sw, g_sh);
			pos.x += size.width;
			wnd1.x = pos.x;
			SET_HIGHLIGHT(pInfo->pIOsd, &wnd1, g_sw, g_sh)
		}
		if(buf[0] == LEFT && c != 24) {
			tmp = tmp & (0xffffffff << (c + 16));
			c += 8;
			pos.x -= size.width;
			IRma_LockRmaOSD(pInfo->pIRma, (HRMABITMAP)bmp, (PBYTE *)(&bmp), &size1);
			IRma_BitBlt(pInfo->pIRma, NULL, (HRMABITMAP)bmpBl, (HRMABITMAP)bmp, pos, rect, RMASRCCOPY, 0);
			IRma_UnLockRmaOSD(pInfo->pIRma, (HRMABITMAP)bmp, (PBYTE *)(&bmp), &size1);
			DISPLAY_OSD(pInfo->pIOsd, bmp, ((720 - PASSWORD_MENU_WINDOW_WIDTH) >> 1),
			            ((480 - PASSWORD_MENU_WINDOW_HEIGHT) >> 1), LEFT_TOP, g_sw, g_sh);
			wnd1.x = pos.x;
			SET_HIGHLIGHT(pInfo->pIOsd, &wnd1, g_sw, g_sh)
		}
	} while(buf[0] != SHOW_MENU && buf[0] != SEL);

	memset(&wnd1, 0, sizeof(OSD_WND));
	initPoi((void **)(&bmp));
	initPoi((void **)(&bmpX));
	initPoi((void **)(&bmpBl));
	if(buf[0] == SHOW_MENU) {
		if(pInfo->osdMsgQ) {
			char msg = SHOW_MENU;
			OSPostMessage(pInfo->osdMsgQ, &msg, 1);
		}
		return FALSE;
	}
	if(buf[0] == SEL)
		if(tmp == g_Pass)
			return TRUE;
		else {
			bmp = createPasswordWindow(pInfo->pIRma, TRUE);
			DISPLAY_OSD(pInfo->pIOsd, bmp, ((720 - PASSWORD_MENU_WINDOW_WIDTH) >> 1),
			            ((480 - PASSWORD_MENU_WINDOW_HEIGHT) >> 1), LEFT_TOP, g_sw, g_sh);
			SET_HIGHLIGHT(pInfo->pIOsd, &wnd1, g_sw, g_sh)
			initPoi((void **)(&bmp));
			if(OSGetMessage(pInfo->osdMsgQ, buf, 1) == ERROR)
				DPRINT(("osdManager: error during reading message queue \n"));
			return FALSE;
		}

	return FALSE;
}


PBYTE createPasswordWindow(IRma *pIRma, BOOL err) {

	RMASIZE textsize;
	ULONG size1;
	RMAYUVENTRY *pPalette, pHli;
	PBYTE p, p1;
	RMARECT rect;
	BYTE str[40];

	pHli.Alpha = 0xff;
	pHli.yuvY = 0xd2;
	pHli.yuvCb = 0x0f;
	pHli.yuvCr = 0x92;

	if(err)
		sprintf(str, "Incorrect password");
	else
		sprintf(str, "Enter password and press SELECT");

	IRma_CreateDC(pIRma, COMPRESSMODE_SEVEN_BPP, PASSWORD_MENU_WINDOW_WIDTH, PASSWORD_MENU_WINDOW_HEIGHT, 0x7f);
	IRma_GetPaletteFromBitmap(pIRma, (HRMABITMAP)audio_setup,
	                          (PBYTE *)(&pPalette), (LONG *)(&size1));
	IRma_SetPalette(pIRma,(HRMABITMAP) NULL, pPalette, 0, 256);
	IRma_SetPalette(pIRma,(HRMABITMAP) NULL, &pHli, 0xaa, 1);

	IRma_SetTextStyle(pIRma, RMAOPAQUE);
	IRma_SetTextColor(pIRma, 0x2a);
	IRma_SetTextBackground(pIRma, 0x7f);

	IRma_SetFont(pIRma, &PASSWORD_MENU_TEXT_FONT);

	IRma_GetTextSize(pIRma,str, &textsize, &PASSWORD_MENU_TEXT_FONT, 0);
	rect.left = (PASSWORD_MENU_WINDOW_WIDTH - textsize.width) >> 1;
	rect.right = rect.left + textsize.width;
	rect.top = PASSWORD_MENU_TEXT_Y_INDENT;
	rect.bottom = rect.top + textsize.height;
	if(IRma_RMADrawText(pIRma, str, rect, ALIGNMIDDLE | ALIGNCENTER, 0) != Q_OK)
		return NULL;

	if(!err) {
		IRma_SetFont(pIRma, &PASSWORD_MENU_INPUT_FONT);
		sprintf(str, "____");
		IRma_GetTextSize(pIRma,str, &textsize, &PASSWORD_MENU_INPUT_FONT, 0);
		rect.left = (PASSWORD_MENU_WINDOW_WIDTH - textsize.width) >> 1;
		rect.right = rect.left + textsize.width;
		rect.top = PASSWORD_MENU_PASSWORD_FIELD_Y_INDENT;
		rect.bottom = rect.top + textsize.height;
		if(IRma_RMADrawText(pIRma, str, rect, ALIGNMIDDLE | ALIGNCENTER, 0) != Q_OK)
			return NULL;
	}

	IRma_LockRmaOSD(pIRma,(HRMABITMAP) NULL, (PBYTE *)(&p1), &size1);

	if(!(p = (PBYTE)OSCelMalloc(size1))) {
		DPRINT(("Not enough memory\n"));
		return NULL;
	}
	memcpy((void *)p, (void *)p1, size1);
	IRma_DestroyDC(pIRma);

	return p;
}


BOOL enterPassword(INFO *pInfo, BOOL cW) {

	PBYTE bmp = createChangePasswordWindow(pInfo->pIRma, cW);
	BYTE buf[1];
	int c = 24, f = 0, nOfEntries = (cW) ? 3 : 2;
	DWORD tmp[3], bmpWidth, size1, x, y;
	RMARECT rect;
	RMAPOINT pos;
	BYTE str[2];
	RMASIZE size;
	PBYTE bmpX, bmpBl;
	OSD_WND wnd1;
	int off = (cW) ? CHANGE_PASSWORD_MENU_Y_OFFSET : NEW_PASSWORD_MENU_Y_OFFSET;

	memset(tmp, 0, 3 * sizeof(DWORD));
	bmpWidth = (DWORD)(bmp[4] << 8) | bmp[5];
	x = (720 - bmpWidth) >> 1;
	y = (480 - ((DWORD)(bmp[6] << 8) | bmp[7])) >> 1;
	DISPLAY_OSD(pInfo->pIOsd, bmp, x, y, LEFT_TOP, g_sw, g_sh);
	size.width = PASSWORD_MENU_INPUT_FONT.m_wWidth + 1;
	size.height = PASSWORD_MENU_INPUT_FONT.m_wHeight + 1;
	sprintf(str, "X");
	bmpX = createMenuList(pInfo->pIRma, &size, &PASSWORD_MENU_INPUT_FONT, 0x7f, ALIGNMIDDLE|ALIGNCENTER, str, 0);
	IRma_LockRmaOSD(pInfo->pIRma, (HRMABITMAP)bmpX, (PBYTE *)(&bmpX), &size1);
	sprintf(str, "_");
	size.width++;
	size.height++;
	bmpBl = createMenuList(pInfo->pIRma, &size, &PASSWORD_MENU_INPUT_FONT, 0x7f, ALIGNMIDDLE|ALIGNCENTER, str, 0);
	IRma_LockRmaOSD(pInfo->pIRma, (HRMABITMAP)bmpBl, (PBYTE *)(&bmpBl), &size1);
	pos.y = ENTER_PASSWORD_MENU_PASSWORD_FIELD_Y_INDENT;
	pos.x = bmpWidth - NEW_CHANGE_PASSWORD_MENU_X_INDENT - size.width * 4;
	wnd1.x = pos.x; wnd1.y = pos.y; wnd1.w = size.width - 1; wnd1.h = size.height;
	SET_HIGHLIGHT(pInfo->pIOsd, &wnd1, g_sw, g_sh);
	rect.left = 0;
	rect.right = size.width;
	rect.top = 0;
	rect.bottom = size.height;
	
	do {
		if(OSGetMessage(pInfo->osdMsgQ, buf, 1) == ERROR) {
			DPRINT(("osdManager: error during reading message queue \n"));
			return FALSE;
		}
		if((buf[0] >= ZERO) && (buf[0] <= NINE) && (c > -8)) {
			tmp[f] = tmp[f] | ((DWORD)buf[0] << c);
			c -= 8;
			IRma_LockRmaOSD(pInfo->pIRma, (HRMABITMAP)bmp, (PBYTE *)(&bmp), &size1);
			IRma_BitBlt(pInfo->pIRma, NULL, (HRMABITMAP)bmpX, (HRMABITMAP)bmp, pos, rect, RMASRCCOPY, 0);
			IRma_UnLockRmaOSD(pInfo->pIRma, (HRMABITMAP)bmp, (PBYTE *)(&bmp), &size1);
			DISPLAY_OSD(pInfo->pIOsd, bmp, x, y, LEFT_TOP, g_sw, g_sh);
			pos.x += size.width;
			wnd1.x = pos.x;
			SET_HIGHLIGHT(pInfo->pIOsd, &wnd1, g_sw, g_sh)
		}
		if(buf[0] == LEFT && c != 24) {
			tmp[f] = tmp[f] & (0xffffffff << (c + 16));
			c += 8;
			pos.x -= size.width;
			IRma_LockRmaOSD(pInfo->pIRma, (HRMABITMAP)bmp, (PBYTE *)(&bmp), &size1);
			IRma_BitBlt(pInfo->pIRma, NULL, (HRMABITMAP)bmpBl, (HRMABITMAP)bmp, pos, rect, RMASRCCOPY, 0);
			IRma_UnLockRmaOSD(pInfo->pIRma, (HRMABITMAP)bmp, (PBYTE *)(&bmp), &size1);
			DISPLAY_OSD(pInfo->pIOsd, bmp, x, y, LEFT_TOP, g_sw, g_sh);
			wnd1.x = pos.x;
			SET_HIGHLIGHT(pInfo->pIOsd, &wnd1, g_sw, g_sh)
		}
		if((buf[0] == SEL) && (c == -8)) {
			f++;
			c = 24;
			pos.y += (size.height + off);
			pos.x = bmpWidth - NEW_CHANGE_PASSWORD_MENU_X_INDENT - size.width * 4;
			wnd1.x = pos.x; wnd1.y = pos.y;
			SET_HIGHLIGHT(pInfo->pIOsd, &wnd1, g_sw, g_sh)
		}
	} while(buf[0] != SHOW_MENU && f < nOfEntries);

	memset(&wnd1, 0, sizeof(OSD_WND));
	initPoi((void **)(&bmp));
	initPoi((void **)(&bmpX));
	initPoi((void **)(&bmpBl));
	if(buf[0] == SHOW_MENU) {
		if(pInfo->osdMsgQ) {
			char msg = SHOW_MENU;
			OSPostMessage(pInfo->osdMsgQ, &msg, 1);
		}
		return FALSE;
	}
	if(tmp[f - 1] != tmp[f - 2]) {
		bmp = createPasswordWindow(pInfo->pIRma, TRUE);
		DISPLAY_OSD(pInfo->pIOsd, bmp, ((720 - PASSWORD_MENU_WINDOW_WIDTH) >> 1),
		            ((480 - PASSWORD_MENU_WINDOW_HEIGHT) >> 1), LEFT_TOP, g_sw, g_sh);
		SET_HIGHLIGHT(pInfo->pIOsd, &wnd1, g_sw, g_sh);
		initPoi((void **)(&bmp));
		if(OSGetMessage(pInfo->osdMsgQ, buf, 1) == ERROR)
			DPRINT(("osdManager: error during reading message queue \n"));
		return FALSE;
	}
	else {
		if(cW) {
			if(tmp[0] != g_Pass) {
				bmp = createPasswordWindow(pInfo->pIRma, TRUE);
				DISPLAY_OSD(pInfo->pIOsd, bmp, ((720 - PASSWORD_MENU_WINDOW_WIDTH) >> 1),
				            ((480 - PASSWORD_MENU_WINDOW_HEIGHT) >> 1), LEFT_TOP, g_sw, g_sh);
				SET_HIGHLIGHT(pInfo->pIOsd, &wnd1, g_sw, g_sh);
				initPoi((void **)(&bmp));
				if(OSGetMessage(pInfo->osdMsgQ, buf, 1) == ERROR)
					DPRINT(("osdManager: error during reading message queue \n"));
				return FALSE;
			}
			else {
				g_Pass = tmp[1];
				FMPWriteProfileWord(RMREG_PASSW_LOW_WORD, ((WORD *)(&g_Pass))[0]);
				FMPWriteProfileWord(RMREG_PASSW_HIGH_WORD, ((WORD *)(&g_Pass))[1]);
				return TRUE;
			}
		}
		else {
			g_Pass = tmp[0];
			FMPWriteProfileWord(RMREG_PASSW_LOW_WORD, ((WORD *)(&g_Pass))[0]);
			FMPWriteProfileWord(RMREG_PASSW_HIGH_WORD, ((WORD *)(&g_Pass))[1]);
			return TRUE;
		}
	}
}


PBYTE createChangePasswordWindow(IRma *pIRma, BOOL cW) {

	RMASIZE textsize;
	ULONG size1;
	RMAYUVENTRY *pPalette, pHli;
	PBYTE p, p1;
	RMARECT rect;
	BYTE str[65], str1[15];
	WORD off, width, height;

	pHli.Alpha = 0xff;
	pHli.yuvY = 0xd2;
	pHli.yuvCb = 0x0f;
	pHli.yuvCr = 0x92;

	if(cW) {
		sprintf(str, "Please enter password:\nEnter new password:\nConfirm new password:");
		sprintf(str1, "____\n____\n____");
		width = NEW_PASSWORD_MENU_WINDOW_WIDTH;
		height = NEW_PASSWORD_MENU_WINDOW_HEIGHT;
		off = CHANGE_PASSWORD_MENU_Y_OFFSET;
	}
	else {
		sprintf(str, "Please enter a four digit password:\nConfirm password:");
		sprintf(str1, "____\n____");
		width = CHANGE_PASSWORD_MENU_WINDOW_WIDTH;
		height = CHANGE_PASSWORD_MENU_WINDOW_HEIGHT;
		off = NEW_PASSWORD_MENU_Y_OFFSET;
	}

	IRma_CreateDC(pIRma, COMPRESSMODE_SEVEN_BPP, width, height, 0x7f);
	IRma_GetPaletteFromBitmap(pIRma, (HRMABITMAP)audio_setup,
	                          (PBYTE *)(&pPalette), (LONG *)(&size1));
	IRma_SetPalette(pIRma,(HRMABITMAP) NULL, pPalette, 0, 256);
	IRma_SetPalette(pIRma,(HRMABITMAP) NULL, &pHli, 0xaa, 1);

	IRma_SetTextStyle(pIRma, RMAOPAQUE);
	IRma_SetTextColor(pIRma, 0x2a);
	IRma_SetTextBackground(pIRma, 0x7f);

	IRma_SetFont(pIRma, &PASSWORD_MENU_TEXT_FONT);
	IRma_GetTextSize(pIRma,str, &textsize, &PASSWORD_MENU_TEXT_FONT, (WORD) (off + 1));
	rect.left = NEW_CHANGE_PASSWORD_MENU_X_INDENT;
	rect.right = rect.left + textsize.width;
	rect.top = NEW_CHANGE_PASSWORD_MENU_Y_INDENT;
	rect.bottom = rect.top + textsize.height;
	if(IRma_RMADrawText(pIRma, str, rect, ALIGNLEFT | ALIGNCENTER, (BYTE) (off + 1)) != Q_OK) {
		IRma_DestroyDC(pIRma);
		return NULL;
	}

	IRma_SetFont(pIRma, &PASSWORD_MENU_INPUT_FONT);
	IRma_GetTextSize(pIRma,str1, &textsize, &PASSWORD_MENU_INPUT_FONT, off);
	rect.right = width - NEW_CHANGE_PASSWORD_MENU_X_INDENT;
	rect.left = rect.right - textsize.width;
	rect.top = ENTER_PASSWORD_MENU_PASSWORD_FIELD_Y_INDENT;
	rect.bottom = rect.top + textsize.height;
	if(IRma_RMADrawText(pIRma, str1, rect, ALIGNMIDDLE | ALIGNCENTER, off) != Q_OK) {
		IRma_DestroyDC(pIRma);
		return NULL;
	}

	IRma_LockRmaOSD(pIRma, (HRMABITMAP)NULL, (PBYTE *)(&p1), &size1);

	if(!(p = (PBYTE)OSCelMalloc(size1))) {
		DPRINT(("Not enough memory\n"));
		IRma_DestroyDC(pIRma);
		return NULL;
	}
	memcpy((void *)p, (void *)p1, size1);
	IRma_DestroyDC(pIRma);

	return p;
}

PBYTE createHiddenMenu(IRma *pIRma, PBYTE *bmp, WORD menu) {

	RMASIZE textsize;
	ULONG size1;
	RMAYUVENTRY *pPalette;
	PBYTE p;
	BYTE str[25], i, n;
	RMARECT rect;
	RMAPOINT pos;
	WORD reg;

	memset(str, 0, 25);

	IRma_CreateDC(pIRma, COMPRESSMODE_SEVEN_BPP, HIDDEN_MENU_WINDOW_WIDTH, HIDDEN_MENU_WINDOW_HEIGHT, 0x7f);
	IRma_GetPaletteFromBitmap(pIRma, (HRMABITMAP)audio_setup,
	                          (PBYTE *)(&pPalette), (LONG *)(&size1));
	IRma_SetPalette(pIRma,(HRMABITMAP) NULL, pPalette, 0, 256);

	IRma_SetTextStyle(pIRma, RMAOPAQUE);
	IRma_SetTextColor(pIRma, 0x2a);

	if(!menu) {
		IRma_SetTextBackground(pIRma, 0x7f);
		IRma_SetFont(pIRma, &HIDDEN_ITEMS_FONT);
		IRma_SetPen(pIRma, RMAPEN_SOLID, 0x7e, 1);

		sprintf(str, "Region code\nMacrovision");
		IRma_GetTextSize(pIRma,str, &textsize, &HIDDEN_ITEMS_FONT, HIDDEN_MENU_TEXT_OFFSET);
		rect.left = HIDDEN_MENU_TEXT_INDENT_X;
		rect.right = rect.left + textsize.width;
		rect.top = HIDDEN_MENU_TEXT_INDENT_TOP;
		rect.bottom = rect.top + textsize.height;
		IRma_RMADrawText(pIRma, str, rect, ALIGNLEFT | ALIGNCENTER, HIDDEN_MENU_TEXT_OFFSET);

		memset(str, 0, 25);
		reg = (WORD)FMPGetProfileWord(RMREG_REGION_CODE);
		if(reg > 0x0006 || !reg) {
			FMPWriteProfileWord(RMREG_REGION_CODE, 1);
			reg = 1;
		}
		sprintf(str, "%d\n", reg);
		reg = (WORD)FMPGetProfileWord(RMREG_MACROVISION);
		if(reg > 0x0001) {
			FMPWriteProfileWord(RMREG_MACROVISION, 1);
			reg = 1;
		}
		if(reg)
			sprintf(str + 2, "Enable");
		else
			sprintf(str + 2, "Disable");
		IRma_GetTextSize(pIRma,str, &textsize, &HIDDEN_ITEMS_FONT, HIDDEN_MENU_TEXT_OFFSET);
		rect.right = HIDDEN_MENU_WINDOW_WIDTH - HIDDEN_MENU_TEXT_INDENT_X;
		rect.left = rect.right - textsize.width;
		rect.top = HIDDEN_MENU_TEXT_INDENT_TOP;
		rect.bottom = rect.top + textsize.height;
		IRma_RMADrawText(pIRma, str, rect, ALIGNRIGHT | ALIGNCENTER, HIDDEN_MENU_TEXT_OFFSET);

		rect.left = HIDDEN_MENU_ITEMS_INDENT_X;
		rect.right = rect.left + HIDDEN_MENU_ITEMS_WIDTH;
		rect.top = HIDDEN_MENU_ITEMS_INDENT_TOP;
		rect.bottom = rect.top + HIDDEN_MENU_ITEMS_HEIGHT;
		IRma_DrawRectangle(pIRma, rect, 0);

		rect.left = HIDDEN_MENU_ITEMS_INDENT_X;
		rect.right = rect.left + HIDDEN_MENU_ITEMS_WIDTH;
		rect.top = HIDDEN_MENU_ITEMS_INDENT_TOP + HIDDEN_MENU_ITEMS_HEIGHT + HIDDEN_MENU_ITEMS_OFFSET;
		rect.bottom = rect.top + HIDDEN_MENU_ITEMS_HEIGHT;
		IRma_DrawRectangle(pIRma, rect, 0);
	}
	else {
		IRma_SetPen(pIRma, RMAPEN_SOLID, 0x7f, 1);

		pos.x = 0;
		pos.y = 0;
		rect.left = rect.top = 0;
		rect.right = HIDDEN_MENU_WINDOW_WIDTH; rect.bottom = HIDDEN_MENU_WINDOW_HEIGHT;
		IRma_LockRmaOSD(pIRma, (HRMABITMAP)(*bmp), bmp, &size1);
		IRma_BitBlt(pIRma, pIRma, (HRMABITMAP)(*bmp),  (BYTE) NULL, pos, rect, RMASRCCOPY, 0);
		rect.left = HIDDEN_MENU_ITEMS_WIDTH + HIDDEN_MENU_ITEMS_INDENT_X + 1;
		rect.right = HIDDEN_MENU_WINDOW_WIDTH;
		if(menu == 2) {
			rect.top = HIDDEN_MENU_TEXT_INDENT_TOP + HIDDEN_MENU_ITEMS_HEIGHT + HIDDEN_MENU_ITEMS_OFFSET;
			sprintf(str, "Disable\nEnable");
			n = 2;
		}
		else {
			rect.top = HIDDEN_MENU_TEXT_INDENT_TOP;
			sprintf(str, "1\n2\n3\n4\n5\n6");
			n = 6;
		}
		rect.bottom = rect.top + HIDDEN_MENU_ITEMS_HEIGHT;
		IRma_DrawRectangle(pIRma, rect, 1);

		IRma_SetTextBackground(pIRma, 0x7d);
		IRma_SetFont(pIRma, &HIDDEN_CHOCE_SUBMENU_LIST_FONT);
		IRma_GetTextSize(pIRma, str, &textsize, &HIDDEN_CHOCE_SUBMENU_LIST_FONT, 0);
		rect.right = HIDDEN_MENU_WINDOW_WIDTH - HIDDEN_MENU_ITEMS_INDENT_X;
		rect.left = rect.right - textsize.width;
		rect.bottom = rect.top + textsize.height;
		IRma_RMADrawText(pIRma, str, rect, ALIGNRIGHT | ALIGNCENTER, 0);

		rect.right++; rect.left--;
		/*rect.top--*/; rect.bottom = rect.top + HIDDEN_CHOCE_SUBMENU_LIST_FONT.m_wHeight;
		IRma_SetPen(pIRma, RMAPEN_SOLID, 0x7c, 1);
		for(i = 0; i < n; i++) {
			IRma_DrawRectangle(pIRma, rect, 0);
			rect.top += HIDDEN_CHOCE_SUBMENU_LIST_FONT.m_wHeight;
			rect.bottom += HIDDEN_CHOCE_SUBMENU_LIST_FONT.m_wHeight;
		}
	}

	IRma_LockRmaOSD(pIRma, (BYTE) NULL, (PBYTE *)(&p), &size1);

	if(!(*bmp))
		if(!(*bmp = (PBYTE)OSCelMalloc(size1))) {
			DPRINT(("Not enough memory\n"));
			*bmp = NULL;
			IRma_DestroyDC(pIRma);
			return (PBYTE) bmp;
		}
	memcpy((void *)(*bmp), (void *)p, size1);
	IRma_DestroyDC(pIRma);
	return (PBYTE) bmp;
}

void hiddenMenu(INFO *pInfo) {

	WORD hliItem = 0, phliItem = 0, mInd = 0;
	PBYTE bmp = NULL;
	OSD_WND arr[3] = {{10, 12, 112, 30}, {180, 15, 11, 20}, {140, 55, 51, 20}}, wnd;
	BYTE buf = 0;
	BYTE n[3] = {2, 6, 2};
	

	createHiddenMenu(pInfo->pIRma, &bmp, 0);
	if(!bmp)
		return;

	DISPLAY_OSD(pInfo->pIOsd,bmp,((720-HIDDEN_MENU_WINDOW_WIDTH)>>1),
	            ((480-HIDDEN_MENU_WINDOW_HEIGHT)>>1),LEFT_TOP,g_sw,g_sh);
	memcpy(&wnd, &(arr[0]), sizeof(OSD_WND));
	SET_HIGHLIGHT(pInfo->pIOsd,&wnd,g_sw,g_sh);

	do {
		if(OSGetMessage(pInfo->osdMsgQ, &buf, 1) == ERROR) {
			DPRINT(("osdManager: error during reading message queue \n"));
			return;
		}
		switch(buf) {
			case UP:
			case LEFT:
				hliItem = (hliItem) ? (hliItem - 1) : (n[mInd] - 1);
				memcpy(&wnd, &(arr[mInd]), sizeof(OSD_WND));
				wnd.y  += (((mInd) ? 20 : 40) * hliItem);
				SET_HIGHLIGHT(pInfo->pIOsd,&wnd,g_sw,g_sh);
				break;
			case RIGHT:
			case DOWN:
				hliItem = (hliItem + 1) % n[mInd];
				memcpy(&wnd, &(arr[mInd]), sizeof(OSD_WND));
				wnd.y  += (((mInd) ? 20 : 40) * hliItem);
				SET_HIGHLIGHT(pInfo->pIOsd,&wnd,g_sw,g_sh);
				break;
			case SEL:
				if(mInd) {
					initPoi((void **)(&bmp));
					if(phliItem)
						FMPWriteProfileWord(RMREG_MACROVISION, hliItem);
					else
						FMPWriteProfileWord(RMREG_REGION_CODE, hliItem + 1);
					createHiddenMenu(pInfo->pIRma, &bmp, 0);
					if(!bmp)
						return;
					DISPLAY_OSD(pInfo->pIOsd,bmp,((720-HIDDEN_MENU_WINDOW_WIDTH)>>1),
					            ((480-HIDDEN_MENU_WINDOW_HEIGHT)>>1),LEFT_TOP,g_sw,g_sh);
					memcpy(&wnd, &(arr[0]), sizeof(OSD_WND));
					wnd.y  += (40 * phliItem);
					SET_HIGHLIGHT(pInfo->pIOsd,&wnd,g_sw,g_sh);
					mInd = 0;
					hliItem = phliItem;
				}
				else {
					phliItem = hliItem;
					hliItem = 0;
					mInd = phliItem + 1;
					createHiddenMenu(pInfo->pIRma, &bmp, mInd);
					if(bmp) {
						DISPLAY_OSD(pInfo->pIOsd,bmp,((720-HIDDEN_MENU_WINDOW_WIDTH)>>1),
						            ((480-HIDDEN_MENU_WINDOW_HEIGHT)>>1),LEFT_TOP,g_sw,g_sh);
						memcpy(&wnd, &(arr[mInd]), sizeof(OSD_WND));
						SET_HIGHLIGHT(pInfo->pIOsd,&wnd,g_sw,g_sh);
					}
					else
						return;
				}
				break;
			case SHOW_PREV:
				initPoi((void **)(&bmp));
				if(mInd) {
					createHiddenMenu(pInfo->pIRma, &bmp, 0);
					if(!bmp)
						return;
					DISPLAY_OSD(pInfo->pIOsd,bmp,((720-HIDDEN_MENU_WINDOW_WIDTH)>>1),
					            ((480-HIDDEN_MENU_WINDOW_HEIGHT)>>1),LEFT_TOP,g_sw,g_sh);
					memcpy(&wnd, &(arr[0]), sizeof(OSD_WND));
					wnd.y  += (40 * phliItem);
					SET_HIGHLIGHT(pInfo->pIOsd,&wnd,g_sw,g_sh);
					mInd = 0;
					hliItem = phliItem;
				}
				else
					return;
				break;
			default:
				break;
		}
	} while(buf != SHOW_MENU);

	if(bmp)
		initPoi((void **)(&bmp));
	return;
}

PBYTE createTRMenu(IRma *pIRma) {

	RMASIZE textsize;
	ULONG size1;
	RMAYUVENTRY *pPalette;
	PBYTE p, p1;
	BYTE str[25];
	RMARECT rect;

	memset(str, 0, 20);

	IRma_CreateDC(pIRma, COMPRESSMODE_SEVEN_BPP, TR_MENU_WINDOW_WIDTH, TR_MENU_WINDOW_HEIGHT, 0x7f);
	IRma_GetPaletteFromBitmap(pIRma, (HRMABITMAP)audio_setup,
	                          (PBYTE *)(&pPalette), (LONG *)(&size1));
	IRma_SetPalette(pIRma,(HRMABITMAP) NULL, pPalette, 0, 256);

	IRma_SetTextStyle(pIRma, RMAOPAQUE);
	IRma_SetTextColor(pIRma, 0x2a);

	IRma_SetTextBackground(pIRma, 0x7f);
	IRma_SetFont(pIRma, &TR_MENU_TEXT_FONT);
	IRma_SetPen(pIRma, RMAPEN_SOLID, 0x7e, 1);

	sprintf(str, "Accept resolution?");
	IRma_GetTextSize(pIRma,str, &textsize, &TR_MENU_TEXT_FONT, TR_MENU_TEXT_OFFSET);
	rect.left = (TR_MENU_WINDOW_WIDTH - textsize.width) >> 1;
	rect.right = rect.left + textsize.width;
	rect.top = TR_MENU_TEXT_INDENT_VERT;
	rect.bottom = rect.top + textsize.height;
	IRma_RMADrawText(pIRma, str, rect, ALIGNLEFT | ALIGNCENTER, TR_MENU_TEXT_OFFSET);

	sprintf(str, "YES");
	IRma_GetTextSize(pIRma,str, &textsize, &TR_MENU_TEXT_FONT, TR_MENU_TEXT_OFFSET);
	rect.left = ((TR_MENU_WINDOW_WIDTH >> 1) - textsize.width) >> 1;
	rect.right = rect.left + textsize.width;
	rect.top = rect.bottom + TR_MENU_TEXT_INDENT_VERT;
	rect.bottom = rect.top + textsize.height;
	IRma_RMADrawText(pIRma, str, rect, ALIGNLEFT | ALIGNCENTER, TR_MENU_TEXT_OFFSET);
	rect.left -= 2;
	rect.right += 2;
	rect.top -= 2;
	rect.bottom += 2;
	IRma_DrawRectangle(pIRma, rect, 0);

	sprintf(str, "NO");
	IRma_GetTextSize(pIRma,str, &textsize, &TR_MENU_TEXT_FONT, TR_MENU_TEXT_OFFSET);
	rect.left = ((TR_MENU_WINDOW_WIDTH >> 1) - textsize.width + TR_MENU_WINDOW_WIDTH) >> 1;
	rect.right = rect.left + textsize.width;
	rect.top += 2;
	rect.bottom -= 2;
	IRma_RMADrawText(pIRma, str, rect, ALIGNLEFT | ALIGNCENTER, TR_MENU_TEXT_OFFSET);
	rect.left -= 2;
	rect.right += 2;
	rect.top -= 2;
	rect.bottom += 2;
	IRma_DrawRectangle(pIRma, rect, 0);

	IRma_LockRmaOSD(pIRma, (HRMABITMAP)NULL, (PBYTE *)(&p1), &size1);

	if(!(p = (PBYTE)OSCelMalloc(size1))) {
		DPRINT(("Not enough memory\n"));
		IRma_DestroyDC(pIRma);
		return NULL;
	}

	memcpy((void *)p, (void *)p1, size1);
	IRma_DestroyDC(pIRma);

	return p;
}

BOOL testRes(INFO *pInfo, BYTE newValue) {

	DWORD Hdtv_c = (DWORD)(newValue - 1), outputMode;
	BOOL value = TRUE;
	float sw, sh;
	BYTE buf[1];

	PBYTE bmp = createTRMenu(pInfo->pIRma);

	outputMode = g_OutputMode & ~(FMPV_VIDEOOUT_MODE_MASK | FMPV_VIDEOOUT_STANDARDTV_MASK | FMPV_VIDEOOUT_TV_AS_SOURCE);

	if(bmp) {
		OSD_WND wnd;
		value = FALSE;
		wnd.x = TR_MENU_WINDOW_WIDTH >> 1;
		wnd.y = 0;
		wnd.w = (TR_MENU_WINDOW_WIDTH) >> 1;
		wnd.h = TR_MENU_WINDOW_HEIGHT;
		if(Hdtv_c < 3) {
			outputMode |= FMPV_VIDEOOUT_TV;
			switch(Hdtv_c) {
				case 0:
					outputMode |= FMPV_VIDEOOUT_NTSC; break;
				case 1:
					outputMode |= FMPV_VIDEOOUT_PAL; break;
				case 2:
					outputMode |= (FMPV_VIDEOOUT_TV_AS_SOURCE | FMPV_VIDEOOUT_NTSC);
					break;
			}
			IHdtv_Off(pInfo->pIHdtv, outputMode);
			sw = sh = 1.0f;
		}
		else {
			outputMode |= FMPV_VIDEOOUT_HDTV;
			IHdtv_SetMode(pInfo->pIHdtv, &(Hdtv_Params[Hdtv_c - 3]), outputMode);
			sw = (float)(Hdtv_Params[Hdtv_c - 3].VideoWidth) / 720;
			sh = (float)(Hdtv_Params[Hdtv_c - 3].VideoHeight) / 480;
		}
		DISPLAY_OSD(pInfo->pIOsd,bmp,
		            ((720-TR_MENU_WINDOW_WIDTH)>>1),((480-TR_MENU_WINDOW_HEIGHT)>>1),
		            LEFT_TOP,sw,sh);
		SET_HIGHLIGHT(pInfo->pIOsd,&wnd,sw,sh);
		pInfo->maddie = 3;
		OSThreadDelete(osdtID);
		osdtID = OSInitPolling("osd_delay", (FUNCPTR)osdDelay, (DWORD)(pInfo));
		do {
			if(OSGetMessage(pInfo->osdMsgQ, buf, 1) == ERROR) {
				DPRINT(("osdManager: error during reading message queue \n"));
				value = FALSE;
				break;
			}
			switch(buf[0]) {
				case LEFT:
					if(!value) {
						value = TRUE;
						wnd.x = 0;
						SET_HIGHLIGHT(pInfo->pIOsd,&wnd,sw,sh);
					}
					break;
				case RIGHT:
					if(value) {
						value = FALSE;
						wnd.x = TR_MENU_WINDOW_WIDTH >> 1;
						SET_HIGHLIGHT(pInfo->pIOsd,&wnd,sw,sh);
					}
					break;
				case SCR_OFF:
					value = FALSE;
					buf[0] = SEL;
				case SEL:
					OSThreadDelete(osdtID);
					osdtID = 0;
				default:
					break;
			}
		} while(buf[0] != SEL);

		if(value) {
			pInfo->IHdtv_c = (Hdtv_c < 2) ? 0 : (Hdtv_c - 2);
			g_OutputMode = outputMode;
		}

		if(pInfo->IHdtv_c) {
			IHdtv_SetMode(pInfo->pIHdtv, &(Hdtv_Params_Init), g_OutputMode);
		}
		else {
			IHdtv_Off(pInfo->pIHdtv, g_OutputMode);
		}

		IOsd_Off(pInfo->pIOsd);

		initPoi((void **)(&bmp));
		return value;
	}

	if(Hdtv_c < 3) {
		pInfo->IHdtv_c = 0;
		g_OutputMode = outputMode | FMPV_VIDEOOUT_TV;
		switch(Hdtv_c) {
			case 0:
				g_OutputMode |= FMPV_VIDEOOUT_NTSC; break;
			case 1:
				g_OutputMode |= FMPV_VIDEOOUT_PAL; break;
			case 2:
				g_OutputMode |= (FMPV_VIDEOOUT_TV_AS_SOURCE | FMPV_VIDEOOUT_NTSC);
				break;
		}
		IHdtv_Off(pInfo->pIHdtv, g_OutputMode);
	}
	else {
		g_OutputMode = outputMode | FMPV_VIDEOOUT_HDTV;
		pInfo->IHdtv_c = Hdtv_c - 2;
		if(!pInfo->IHdtv_c) {
			IHdtv_SetMode(pInfo->pIHdtv, &(Hdtv_Params_Init), g_OutputMode);
		}
	}
	IOsd_Off(pInfo->pIOsd);

	return TRUE;
}


#ifdef PRINCETON	
PBYTE createFPSettingsMenu(IRma *pIRma, int index) {

	RMASIZE textsize;
	ULONG size1;
	RMAYUVENTRY *pPalette;
	PBYTE p, p1;
	RMARECT rect;
	RMAPOINT st, en;
	BYTE i;

	IRma_CreateDC(pIRma, COMPRESSMODE_SEVEN_BPP, FP_MENU_WINDOW_WIDTH, FP_MENU_WINDOW_HEIGHT, 0x7f);
	IRma_GetPaletteFromBitmap(pIRma, (HRMABITMAP)audio_setup,
	                          (PBYTE *)(&pPalette), (LONG *)(&size1));
	IRma_SetPalette(pIRma, (HRMABITMAP) NULL, pPalette, 0, 256);
	
	IRma_SetTextStyle(pIRma, RMAOPAQUE);
	IRma_SetTextColor(pIRma, 0x2a);

	IRma_SetTextBackground(pIRma, 0x7f);
	IRma_SetFont(pIRma, &FP_MENU_TEXT_FONT);

	IRma_GetTextSize(pIRma,videoMenuArr[6][index - 1], &textsize, &FP_MENU_TEXT_FONT, FP_MENU_TEXT_OFFSET);
	rect.left = (FP_MENU_WINDOW_WIDTH - textsize.width) >> 1;
	rect.right = rect.left + textsize.width;
	rect.top = FP_MENU_TEXT_INDENT_VERT;
	rect.bottom = rect.top + textsize.height;
	IRma_RMADrawText(pIRma, videoMenuArr[6][index - 1], rect, ALIGNLEFT | ALIGNCENTER, FP_MENU_TEXT_OFFSET);

	IRma_SetPen(pIRma, RMAPEN_SOLID, 0x7e, 1);
	rect.left = FP_MENU_SCALE_OFFSET_X;
	rect.right = rect.left + (FP_MENU_SCALE_GRADE << 6);
	rect.top = FP_MENU_SCALE_OFFSET_Y;
	rect.bottom = rect.top + FP_MENU_SCALE_HEIGHT;
	IRma_DrawRectangle(pIRma, rect, 1);

	IRma_SetPen(pIRma, RMAPEN_SOLID, 0x2a, 1);
	en.x = st.x = FP_MENU_SCALE_OFFSET_X + 1;
	st.y = FP_MENU_SCALE_OFFSET_Y + 1;
	en.y = FP_MENU_SCALE_OFFSET_Y + FP_MENU_SCALE_HEIGHT - 1;

	for(i = 0; i < 64; i++) {
		IRma_DrawLine(pIRma, st, en);
		en.x += 2;
		st.x += 2;
	}

	IRma_LockRmaOSD(pIRma, (HRMABITMAP)NULL, (PBYTE *)(&p1), &size1);

	if(!(p = (PBYTE)OSCelMalloc(size1))) {
		DPRINT(("Not enough memory\n"));
		IRma_DestroyDC(pIRma);
		return NULL;
	}

	memcpy((void *)p, (void *)p1, size1);
	IRma_DestroyDC(pIRma);

	return p;
}

void changeFPSettings(INFO *pInfo, int index) {

	PBYTE bmp;
	IUserI2C *pIUserI2C;
	BYTE buf[1], value;

	if(!index)
		return;

	bmp = createFPSettingsMenu(pInfo->pIRma, index);

	if(bmp) {
		OSD_WND wnd;

		if(FMPQueryInterface(IID_ILCD, (void **)(&(pIUserI2C)))) {
			DPRINT(("Cannot set LCD interface\n"));
			initPoi((void **)&bmp);
			return;
		}
		else {
			IUserI2C_SetI2CAddress(pIUserI2C,0x58,0x59,1);
			DPRINT(("Address set\n"));
		}

		IUserI2C_Read(pIUserI2C,(0xb0 | (index - 1)),&value,1);

		wnd.x = FP_MENU_SCALE_OFFSET_X + value * FP_MENU_SCALE_GRADE;
		wnd.y = 0;
		wnd.w = FP_MENU_SCALE_GRADE + 1;
		wnd.h = FP_MENU_WINDOW_HEIGHT;
		DISPLAY_OSD(pInfo->pIOsd,bmp,
		            ((720-FP_MENU_WINDOW_WIDTH)>>1),((480-FP_MENU_WINDOW_HEIGHT)>>1),
		            LEFT_TOP,g_sw,g_sh);
		SET_HIGHLIGHT(pInfo->pIOsd,&wnd,g_sw,g_sh);
		do {
			if(OSGetMessage(pInfo->osdMsgQ, buf, 1) == ERROR) {
				DPRINT(("osdManager: error during reading message queue \n"));
				initPoi((void **)(&bmp));
				return;
			}
			switch(buf[0]) {
				case LEFT:
					if(wnd.x == FP_MENU_SCALE_OFFSET_X)
						break;
					wnd.x -= FP_MENU_SCALE_GRADE;
					SET_HIGHLIGHT(pInfo->pIOsd,&wnd,g_sw,g_sh);
					II2C_DecLCD(pIUserI2C,(0x20 | (index - 1)));
					break;
				case RIGHT:
					if(wnd.x == FP_MENU_SCALE_OFFSET_X + FP_MENU_SCALE_GRADE * 63)
						break;
					wnd.x += FP_MENU_SCALE_GRADE;
					SET_HIGHLIGHT(pInfo->pIOsd,&wnd,g_sw,g_sh);
					II2C_IncLCD(pIUserI2C,(0x20 | (index - 1)));
					break;
				case SHOW_MENU:
				case SHOW_PREV:
				case SEL:
				default:
					break;
			}
		} while(buf[0] != SEL && buf[0] != SHOW_MENU && buf[0] != SHOW_PREV);

		value = index - 1;

		if(buf[0] != SEL) {
			if(buf[0] == SHOW_MENU) {
				if(pInfo->osdMsgQ) {
					char msg = SHOW_MENU;
					OSPostMessage(pInfo->osdMsgQ, &msg, 1);
				}
			}
			value |= 0xd0;
		}
		else
			value |= 0xe0;

		II2C_XFRLCD(pIUserI2C,value);

		initPoi((void **)(&bmp));
	}

	return;
}
#endif

/**********************************************************/
/******************** Helpful functions *******************/
/**********************************************************/

PBYTE bScale(PBYTE bmp, float sw, float sh) {

	PBYTE bitmap, pd, ps;
	DWORD width, height, size, w, h, i, j;

	w = (((DWORD)(bmp[4])) << 8) | bmp[5];
	h = (((DWORD)(bmp[6])) << 8) | bmp[7];
	width = ROUND(w * sw);
	height = ROUND(h * sh);
	size = width * height + 1032;

	if(!(bitmap = (PBYTE)OSCelMalloc(size))) {
		DPRINT(("Not enough memory\n"));
		return NULL;
	}
	memcpy(bitmap, bmp, 1032);
	if(w == width && h == height) {
		memcpy(bitmap + 1032, bmp + 1032, w * h);
		return bitmap;
	}
	bitmap[4] = (BYTE)(width >> 8);
	bitmap[5] = (BYTE)width;
	bitmap[6] = (BYTE)(height >> 8);
	bitmap[7] = (BYTE)height;
	bitmap[1] = (BYTE)(size >> 16);
	bitmap[2] = (BYTE)(size >> 8);
	bitmap[3] = (BYTE)size;
	pd = bitmap + 1032;

	if(w == width) {
		for(i = 0; i < height; i++) {
			ps = bmp + ROUND(i / sh) * w + 1032;
			memcpy(pd, ps, width);
			pd += width;
		}
	}
	else if(sw == 3.0f) {
		for(i = 0; i < height; i++) {
			ps = bmp + ROUND(i / sh) * w + 1032;
#ifndef _MONTSERRAT_
			for(j = 0; j < w; j++) {
				memset(pd, ps[j], 3);
				pd += 3;
			}
#else
			{
				__asm("loop_start3:\n\t"
				      "movb (%%edx), %%al\n\t"
				      "movb %%al, %%ah\n\t"
				      "movw %%ax, (%%ebx)\n\t"
				      "inc %%ebx\n\t"
				      "inc %%ebx\n\t"
				      "movb %%al, (%%ebx)\n\t"
				      "inc %%ebx\n\t"
				      "inc %%edx\n\t"
				      "loop loop_start3"
				      :
				      : "c"(w),"d"(ps),"b"(pd)
				      : "%ecx","%edx","%ebx");
				pd += width;
			}
#endif
		}
	}
	else if(sw == 2.0f) {
		for(i = 0; i < height; i++) {
			ps = bmp + ROUND(i / sh) * w + 1032;
#ifndef _MONTSERRAT_
			for(j = 0; j < w; j++) {
				memset(pd, ps[j], 2);
				pd += 2;
			}
#else
			{
				__asm("loop_start2:\n\t"
				      "movb (%%edx), %%al\n\t"
				      "movb %%al, %%ah\n\t"
				      "movw %%ax, (%%ebx)\n\t"
				      "inc %%ebx\n\t"
				      "inc %%ebx\n\t"
				      "inc %%edx\n\t"
				      "loop loop_start2"
				      :
				      : "c"(w),"d"(ps),"b"(pd)
				      : "%ecx","%edx","%ebx");
				pd += width;
			}
#endif
		}
	}
	else if(sw == 1.5f) {
		for(i = 0; i < height; i++) {
			ps = bmp + ROUND(i / sh) * w + 1032;
#ifndef _MONTSERRAT_
			for(j = 0; j < width; j += 3) {
				*pd++ = *ps++;
				memset(pd, *ps, 2);
				pd += 2;
				ps++;
			}
#else
			{
				__asm("loop_start1:\n\t"
				      "movb (%%edx), %%al\n\t"
				      "movb %%al, (%%ebx)\n\t"
				      "inc %%edx\n\t"
				      "inc %%ebx\n\t"
				      "movb (%%edx), %%al\n\t"
				      "movb %%al, %%ah\n\t"
				      "movw %%ax, (%%ebx)\n\t"
				      "inc %%ebx\n\t"
				      "inc %%ebx\n\t"
				      "inc %%edx\n\t"
				      "dec %%ecx\n\t"
				      "dec %%ecx\n\t"
				      "loop loop_start1"
				      :
				      : "c"(width),"d"(ps),"b"(pd)
				      : "%ecx","%edx","%ebx");
				pd += width;
				ps += w;
			}
#endif
			if(w & 1) {
				memcpy(pd, ps, 2);
				pd += 2;
			}
//			pd += width;
		}
	}
	else {
		for(i = 0; i < height; i++) {
			ps = bmp + ROUND(i / sh) * w + 1032;
			for(j = 0; j < width; j++) {
				*pd++ = ps[ROUND(j / sw)];
			}
//			pd += width;
		}
	}
	return bitmap;
}
