// // ROIDSUPP - hyperoid support functions // // Version: 1.1 Copyright (C) 1991, Hutchins Software // This software is licenced under the GNU General Public Licence // Please read the associated legal documentation // Author: Edward Hutchins // Revisions: // 11/01/91 added GNU General Public License - Ed. // #include "hyperoid.h" // // defines // // you may ask, "why did he embed all these string constants instead of // using the resource file?". Good question. The answer is: I feel better // knowing this stuff is part of the executable, and not part of the resource // file (which can be changed by sneaky people). Or maybe I wuz lazy. // If you don't like it, then YOU can change it! #define NL "\x0d\x0a" #define HYPEROID_HELP \ "The following keys control your ship:" NL NL \ " Left, Right Arrow .... spin left or right" NL \ " Down, Up Arrow ..... forward or reverse thrust" NL \ " Space Bar .............. fire!" NL \ " Tab ......................... shields" NL \ " S ............................. smartbomb" NL \ " Esc ......................... pause/boss key" NL NL \ "Note: You have 3 lives, unlimited fuel and firepower, 3 shields and 3 " \ "smartbombs. Your ship gets darker when you lose a life, but you keep on " \ "playing (unless you hit an asteroid). You get an extra life every 100,000 " \ "points. When you lose the game, you start over immediately and can finish " \ "off the current level (which should now be 0) before starting over at " \ "level 1 (There is no waiting around between games)." #define HYPEROID_HELP2 \ "The HYPEROID.INI file can be created/modified to change default settings " \ "in Hyperoid. Here are some of the items you can set:" NL \ NL "[Hyperoid]" NL "Max=<0/1>" NL "{X,Y,W,H}=" NL "Mono=<0/1>" NL \ "DrawDelay= ;microseconds/frame" NL \ NL "[Palette]" NL \ "{Black,DkGrey,Grey,White," NL \ " DkRed,Red,DkGreen,Green,DkBlue,Blue," NL \ " DkYellow,Yellow,DkCyan,Cyan," NL \ " DkMagenta,Magenta}=,," NL \ NL "[Keys]" NL \ "{Shield,Clockwise,CtrClockwise," NL \ " Thrust,RevThrust,Fire,Bomb}=" NL NL \ "Note: Virtual keycodes usually match the key's ASCII value." #define HYPEROID_HELPSTYLE (MB_OK | MB_ICONASTERISK) // this is the part I especially want in the executable image #define HYPEROID_LICENSE \ "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 1, or (at your option) " \ "any later version. " \ NL NL \ "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. " \ NL NL \ "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. " // // imports // IMPORT CHAR szAppName[32] FROM( hyperoid.c ); IMPORT HANDLE hAppInst FROM( hyperoid.c ); IMPORT BOOL bBW FROM( hyperoid.c ); IMPORT INT nDrawDelay FROM( hyperoid.c ); IMPORT INT vkShld FROM( hyperoid.c ); IMPORT INT vkClkw FROM( hyperoid.c ); IMPORT INT vkCtrClkw FROM( hyperoid.c ); IMPORT INT vkThrst FROM( hyperoid.c ); IMPORT INT vkRvThrst FROM( hyperoid.c ); IMPORT INT vkFire FROM( hyperoid.c ); IMPORT INT vkBomb FROM( hyperoid.c ); IMPORT LONG lHighScore FROM( hyperoid.c ); // // globals // // these parts map to "abcdefghijklm" GLOBAL POINT LetterPart[] = { {83, 572}, {64, 512}, {45, 572}, {96, 362}, {32, 362}, {128, 256}, {0, 0}, {0, 256}, {160, 362}, {224, 362}, {173, 572}, {192, 512}, {211, 572} }; // here's the vector font GLOBAL NPSTR szNumberDesc[] = { "cakmck", // 0 "dbl", // 1 "abekm", // 2 "abegjlk", // 3 "mcfh", // 4 "cbfgjlk", // 5 "bdiljgi", // 6 "acgl", // 7 "bdjlieb", // 8 "ljebdge" // 9 }; GLOBAL NPSTR szLetterDesc[] = { "kdbemhf", // A "kabegjlk", // B "cbflm", // C "kabejlk", // D "cafgfkm", // E "cafgfk", // F "bdiljhg", // G "kafhcm", // H "bl", // I "cjli", // J "akcgm", // K "akm", // L "kagcm", // M "kamc", // N "bdiljeb", // O "kabegf", // P "mlidbejl", // Q "kabegfgm", // R "ebdjli", // S "lbac", // T "ailjc", // U "alc", // V "akgmc", // W "amgkc", // X "aglgc", // Y "ackm" // Z }; // // locals // LOCAL CHAR szIni[] = "HYPEROID.INI"; LOCAL CHAR szLicense[] = "LicenseRead"; LOCAL CHAR szDrawDelay[] = "DrawDelay"; LOCAL CHAR szMax[] = "Max"; LOCAL CHAR szX[] = "X"; LOCAL CHAR szY[] = "Y"; LOCAL CHAR szW[] = "W"; LOCAL CHAR szH[] = "H"; LOCAL CHAR szBW[] = "Mono"; LOCAL CHAR szPalette[] = "Palette"; LOCAL CHAR szKeys[] = "Keys"; LOCAL CHAR szShield[] = "Shield"; LOCAL CHAR szClockwise[] = "Clockwise"; LOCAL CHAR szCtrClockwise[] = "CtrClockwise"; LOCAL CHAR szThrust[] = "Thrust"; LOCAL CHAR szRevThrust[] = "RevThrust"; LOCAL CHAR szFire[] = "Fire"; LOCAL CHAR szBomb[] = "Bomb"; LOCAL CHAR szHi[] = "Hi"; LOCAL CHAR *szColorName[] = { "Black", "DkGrey", "Grey", "White", "DkRed", "Red", "DkGreen", "Green", "DkBlue", "Blue", "DkYellow", "Yellow", "DkCyan", "Cyan", "DkMagenta", "Magenta" }; LOCAL DWORD dwColors[] = { RGB(0,0,0), RGB(128,128,128), RGB(192,192,192), RGB(255,255,255), RGB(128,0,0), RGB(255,0,0), RGB(0,128,0), RGB(0,255,0), RGB(0,0,128), RGB(0,0,255), RGB(128,128,0), RGB(255,255,0), RGB(0,128,128), RGB(0,255,255), RGB(128,0,128), RGB(255,0,255), }; // // PrintLetters - create letter objects from a string // VOID FAR PASCAL PrintLetters( NPSTR npszText, POINT Pos, POINT Vel, BYTE byColor, INT nSize ) { INT nLen = strlen( npszText ); INT nCnt = nLen; INT nSpace = nSize + nSize / 2; INT nBase = (nLen - 1) * nSpace; INT nBaseStart = Pos.x + nBase / 2; while (nCnt--) { NPOBJ npLtr = CreateLetter( npszText[nCnt], nSize / 2 ); if (npLtr) { npLtr->Pos.x = nBaseStart; npLtr->Pos.y = Pos.y; npLtr->Vel = Vel; npLtr->byColor = byColor; } nBaseStart -= nSpace; } } // // SpinLetters - spin letter objects away from center for effect // VOID FAR PASCAL SpinLetters( NPSTR npszText, POINT Pos, POINT Vel, BYTE byColor, INT nSize ) { INT nLen = strlen( npszText ); INT nCnt = nLen; INT nSpace = nSize + nSize / 2; INT nBase = (nLen - 1) * nSpace; INT nBaseStart = Pos.x + nBase / 2; while (nCnt--) { NPOBJ npLtr = CreateLetter( npszText[nCnt], nSize / 2 ); if (npLtr) { INT nSpin = (nCnt - nLen / 2) * 2; npLtr->Pos.x = nBaseStart; npLtr->Pos.y = Pos.y; npLtr->Vel = Vel; npLtr->Vel.x += nSpin * 16; npLtr->nSpin = -nSpin; npLtr->byColor = byColor; } nBaseStart -= nSpace; } } // // CreateHyperoidPalette - create a logical palette // HPALETTE FAR PASCAL CreateHyperoidPalette( VOID ) { HPALETTE hPalette; HDC hIC = CreateIC( "DISPLAY", NULL, NULL, NULL ); INT t; PALETTEENTRY Pal[PALETTE_SIZE + 2]; NPLOGPALETTE npLogPalette = (NPLOGPALETTE)Pal; // are we forced into using b&w? bBW = FALSE; if (GetDeviceCaps( hIC, NUMCOLORS ) < 8) bBW = TRUE; DeleteDC( hIC ); if (GetPrivateProfileInt( szAppName, szBW, FALSE, szIni )) bBW = TRUE; npLogPalette->palVersion = 0x0300; npLogPalette->palNumEntries = PALETTE_SIZE; for (t = 0; t < PALETTE_SIZE; ++t) { DWORD dwColor = dwColors[t]; CHAR szBuff[32]; GetPrivateProfileString( szPalette, szColorName[t], "", szBuff, sizeof(szBuff), szIni ); if (szBuff[0]) { INT r, g, b; NPSTR npBuff = szBuff; r = g = b = 255; while (*npBuff == ' ') ++npBuff; r = atoi( npBuff ); while (*npBuff && *npBuff != ',') ++npBuff; if (*npBuff == ',') g = atoi( ++npBuff ); while (*npBuff && *npBuff != ',') ++npBuff; if (*npBuff == ',') b = atoi( ++npBuff ); dwColor = RGB( r, g, b ); } if (bBW) dwColor = ((dwColor == RGB(0,0,0)) ? RGB(0,0,0) : RGB(255,255,255)); npLogPalette->palPalEntry[t].peRed = GetRValue( dwColor ); npLogPalette->palPalEntry[t].peGreen = GetGValue( dwColor ); npLogPalette->palPalEntry[t].peBlue = GetBValue( dwColor ); npLogPalette->palPalEntry[t].peFlags = 0; } hPalette = CreatePalette( npLogPalette ); return( hPalette ); } // // CreateHyperoidClass - create the class of Hyperoid's window // BOOL FAR PASCAL CreateHyperoidClass( VOID ) { WNDCLASS Class; // load the name from the resource file LoadString( hAppInst, IDS_NAME, szAppName, sizeof(szAppName) ); Class.style = CS_HREDRAW | CS_VREDRAW; Class.lpfnWndProc = HyperoidWndProc; Class.cbClsExtra = 0; Class.cbWndExtra = 0; Class.hInstance = hAppInst; Class.hIcon = NULL; Class.hCursor = LoadCursor( NULL, IDC_CROSS ); Class.hbrBackground = HNULL; Class.lpszMenuName = szAppName; Class.lpszClassName = szAppName; return( RegisterClass( &Class ) ); } // // SetHyperoidMenu - add Hyperoid's menu items to the system menu // VOID NEAR PASCAL SetHyperoidMenu( HWND hWnd, INT nFirstID, INT nLastID ) { CHAR szMenuName[40]; HMENU hMenu; hMenu = GetSystemMenu( hWnd, TRUE ); if (hMenu == HNULL) hMenu = GetSystemMenu( hWnd, FALSE ); if (hMenu == HNULL) return; while (nFirstID <= nLastID) { LoadString( hAppInst, nFirstID, szMenuName, sizeof(szMenuName) ); ChangeMenu( hMenu, 0, szMenuName, nFirstID, MF_APPEND ); ++nFirstID; } } // // CreateHyperoidWindow - open the Hyperoid window // HWND FAR PASCAL CreateHyperoidWindow( LPSTR lpszCmd, INT nCmdShow ) { HWND hWnd; INT x, y, w, h; CHAR szBuff[32]; // get the highscore profile here for lack of a better place... GetPrivateProfileString( szAppName, szHi, "0", szBuff, sizeof(szBuff), szIni ); lHighScore = atol( szBuff ); x = GetPrivateProfileInt( szAppName, szX, CW_USEDEFAULT, szIni ); y = GetPrivateProfileInt( szAppName, szY, CW_USEDEFAULT, szIni ); w = GetPrivateProfileInt( szAppName, szW, CW_USEDEFAULT, szIni ); h = GetPrivateProfileInt( szAppName, szH, CW_USEDEFAULT, szIni ); if (GetPrivateProfileInt( szAppName, szMax, FALSE, szIni ) && nCmdShow == SW_NORMAL) nCmdShow = SW_SHOWMAXIMIZED; hWnd = CreateWindow( szAppName, szAppName, WS_OVERLAPPEDWINDOW, x, y, w, h, HNULL, HNULL, hAppInst, NULL ); if (hWnd == HNULL) return( HNULL ); ShowWindow( hWnd, nCmdShow ); UpdateWindow( hWnd ); SetHyperoidMenu( hWnd, IDM_NEW, IDM_ABOUT ); // show the license... if (!GetPrivateProfileInt( szAppName, szLicense, FALSE, szIni )) { MessageBeep( HYPEROID_HELPSTYLE ); MessageBox( hWnd, HYPEROID_LICENSE, "Hyperoid License", HYPEROID_HELPSTYLE ); // ...and never show it again (unless they want to see it) WritePrivateProfileString( szAppName, szLicense, "1", szIni ); } return( hWnd ); } // // SaveHyperoidWindowPos - write out the .ini information // VOID FAR PASCAL SaveHyperoidWindowPos( HWND hWnd ) { RECT rect; CHAR szBuff[32]; // save the highscore profile here for lack of a better place... if (lHighScore) { wsprintf( szBuff, "%lu", lHighScore ); WritePrivateProfileString( szAppName, szHi, szBuff, szIni ); } if (IsIconic( hWnd )) return; if (IsZoomed( hWnd )) { WritePrivateProfileString( szAppName, szMax, "1", szIni ); return; } else WritePrivateProfileString( szAppName, szMax, NULL, szIni ); GetWindowRect( hWnd, &rect ); wsprintf( szBuff, "%d", rect.left ); WritePrivateProfileString( szAppName, szX, szBuff, szIni ); wsprintf( szBuff, "%d", rect.top ); WritePrivateProfileString( szAppName, szY, szBuff, szIni ); wsprintf( szBuff, "%d", rect.right - rect.left ); WritePrivateProfileString( szAppName, szW, szBuff, szIni ); wsprintf( szBuff, "%d", rect.bottom - rect.top ); WritePrivateProfileString( szAppName, szH, szBuff, szIni ); } // // GetHyperoidIni - load the ini file information // VOID FAR PASCAL GetHyperoidIni( VOID ) { nDrawDelay = GetPrivateProfileInt( szAppName, szDrawDelay, DRAW_DELAY, szIni ); vkShld = GetPrivateProfileInt( szKeys, szShield, VK_TAB, szIni ); vkClkw = GetPrivateProfileInt( szKeys, szClockwise, VK_LEFT, szIni ); vkCtrClkw = GetPrivateProfileInt( szKeys, szCtrClockwise, VK_RIGHT, szIni ); vkThrst = GetPrivateProfileInt( szKeys, szThrust, VK_DOWN, szIni ); vkRvThrst = GetPrivateProfileInt( szKeys, szRevThrust, VK_UP, szIni ); vkFire = GetPrivateProfileInt( szKeys, szFire, VK_SPACE, szIni ); vkBomb = GetPrivateProfileInt( szKeys, szBomb, 'S', szIni ); } // // HyperoidHelp - show help // VOID FAR PASCAL HyperoidHelp( HWND hWnd ) { MessageBox( hWnd, HYPEROID_HELP, "Hyperoid help", HYPEROID_HELPSTYLE ); MessageBox( hWnd, HYPEROID_HELP2, "Hyperoid.ini help", HYPEROID_HELPSTYLE ); } // // HyperoidAboutDlg - the about box proc // BOOL FAR PASCAL EXPORT HyperoidAboutDlg( HWND hDlg, WORD mess, WORD wParam, LONG lParam ) { switch (mess) { case WM_INITDIALOG: if (lHighScore) { CHAR szBuff[40]; wsprintf( szBuff, "High Score: %7.7lu", lHighScore ); SetDlgItemText( hDlg, IDD_A_HISCORE, szBuff ); } break; case WM_COMMAND: switch (wParam) { case IDD_A_HELP: HyperoidHelp( hDlg ); // fall through... case IDOK: EndDialog( hDlg, 0 ); break; default: return( FALSE ); } break; case WM_CLOSE: EndDialog( hDlg, FALSE ); break; default: return( FALSE ); } return( TRUE ); } // // AboutHyperoid - show the about box // VOID FAR PASCAL AboutHyperoid( HWND hWnd ) { FARPROC lpprocAbout = MakeProcInstance( HyperoidAboutDlg, hAppInst ); DialogBox( hAppInst, INTRES( IDD_ABOUT ), hWnd, lpprocAbout ); FreeProcInstance( lpprocAbout ); }