1 /*
2 * notevil.c
3 *
4 * --------------------------------------------------------------------
5 *
6 * This software is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This software is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this software; see the file COPYING.LIB. If
18 * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19 * Cambridge, MA 02139, USA.
20 *
21 * --------------------------------------------------------------------
22 * ReactOS Coders Console Parade
23 *
24 * 19990411 EA
25 * 19990515 EA
26 */
27
28 #include <windows.h>
29 #include <stdio.h>
30 #include "resource.h"
31
32 // #define DISPLAY_COORD
33
34 LPCWSTR app_name = L"notevil";
35
36 HANDLE myself;
37 HANDLE ScreenBuffer;
38 CONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo;
39 HANDLE WaitableTimer;
40
41 VOID
WriteStringAt(LPWSTR lpString,COORD xy,WORD wColor)42 WriteStringAt(LPWSTR lpString,
43 COORD xy,
44 WORD wColor)
45 {
46 DWORD cWritten = 0;
47 DWORD dwLen;
48
49 if (!lpString || *lpString == 0) return;
50
51 dwLen = (DWORD)wcslen(lpString);
52
53 /* Don't bother writing text when erasing */
54 if (wColor)
55 {
56 WriteConsoleOutputCharacterW(ScreenBuffer,
57 lpString,
58 dwLen,
59 xy,
60 &cWritten);
61 }
62
63 FillConsoleOutputAttribute(ScreenBuffer,
64 wColor,
65 dwLen,
66 xy,
67 &cWritten);
68 }
69
70
71 #ifdef DISPLAY_COORD
72 VOID
WriteCoord(COORD c)73 WriteCoord(COORD c)
74 {
75 COORD xy = {0,0};
76 WCHAR buf[40];
77
78 wsprintf(buf, L"x=%02d y=%02d", c.X, c.Y);
79
80 WriteStringAt(buf, xy,
81 BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
82 }
83 #endif /* def DISPLAY_COORD */
84
85
86 VOID
GetNextString(LPWSTR Buffer,INT BufferSize,PDWORD Index)87 GetNextString(LPWSTR Buffer,
88 INT BufferSize,
89 PDWORD Index)
90 {
91 if (RES_LAST_INDEX == *Index)
92 *Index = RES_FIRST_INDEX;
93 else
94 ++*Index;
95
96 LoadStringW(myself, *Index, Buffer, BufferSize);
97 }
98
99
100 VOID
DisplayTitle(VOID)101 DisplayTitle(VOID)
102 {
103 LPWSTR szTitle = L"ReactOS Coders Console Parade";
104 COORD xy;
105
106 xy.X = (ScreenBufferInfo.dwSize.X - (USHORT)wcslen(szTitle)) / 2;
107 xy.Y = ScreenBufferInfo.dwSize.Y / 2;
108
109 WriteStringAt(szTitle, xy,
110 FOREGROUND_GREEN | FOREGROUND_INTENSITY);
111 }
112
113
114 #define RES_DELAY_CHANGE 12
115 #define RES_BUFFER_SIZE 1024
116 VOID
MainLoop(VOID)117 MainLoop(VOID)
118 {
119 WCHAR NameString[RES_BUFFER_SIZE];
120 DWORD NameIndex = 0;
121 INT NameLength = 0;
122 COORD xy;
123 INT n = RES_DELAY_CHANGE;
124 INT dir_y = 1;
125 INT dir_x = 1;
126 WORD wColor = 1;
127
128 xy.X = ScreenBufferInfo.dwSize.X / 2;
129 xy.Y = ScreenBufferInfo.dwSize.Y / 2;
130
131 for ( ; 1; ++n )
132 {
133 if (n == RES_DELAY_CHANGE)
134 {
135 n = 0;
136
137 GetNextString(NameString,
138 RES_BUFFER_SIZE,
139 &NameIndex);
140 NameLength = wcslen(NameString);
141
142 wColor++;
143 if ((wColor & 0x000F) == 0)
144 wColor = 1;
145 }
146 if (xy.X == 0)
147 {
148 if (dir_x == -1)
149 dir_x = 1;
150 }
151 else if (xy.X >= ScreenBufferInfo.dwSize.X - NameLength - 1)
152 {
153 if (dir_x == 1)
154 dir_x = -1;
155 }
156 xy.X += dir_x;
157
158 if (xy.Y == 0)
159 {
160 if (dir_y == -1)
161 dir_y = 1;
162 }
163 else if (xy.Y >= ScreenBufferInfo.dwSize.Y - 1)
164 {
165 if (dir_y == 1)
166 dir_y = -1;
167 }
168 xy.Y += dir_y;
169
170 #ifdef DISPLAY_COORD
171 WriteCoord(xy);
172 #endif /* def DISPLAY_COORD */
173
174 DisplayTitle();
175 WriteStringAt(NameString, xy, wColor);
176 WaitForSingleObject(WaitableTimer, INFINITE);
177 WriteStringAt(NameString, xy, 0);
178 }
179 }
180
181
wmain(int argc,WCHAR * argv[])182 int wmain(int argc, WCHAR* argv[])
183 {
184 LARGE_INTEGER lint;
185 DWORD Written;
186 COORD Coord = { 0, 0 };
187
188 myself = GetModuleHandle(NULL);
189
190 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
191 &ScreenBufferInfo);
192 ScreenBufferInfo.dwSize.X = ScreenBufferInfo.srWindow.Right - ScreenBufferInfo.srWindow.Left + 1;
193 ScreenBufferInfo.dwSize.Y = ScreenBufferInfo.srWindow.Bottom - ScreenBufferInfo.srWindow.Top + 1;
194 ScreenBuffer = CreateConsoleScreenBuffer(GENERIC_WRITE,
195 0,
196 NULL,
197 CONSOLE_TEXTMODE_BUFFER,
198 NULL);
199 if (ScreenBuffer == INVALID_HANDLE_VALUE)
200 {
201 wprintf(L"%s: could not create a new screen buffer\n", app_name);
202 return EXIT_FAILURE;
203 }
204
205 /* Fill buffer with black background */
206 FillConsoleOutputAttribute(ScreenBuffer,
207 0,
208 ScreenBufferInfo.dwSize.X * ScreenBufferInfo.dwSize.Y,
209 Coord,
210 &Written);
211
212 WaitableTimer = CreateWaitableTimer(NULL, FALSE, NULL);
213 if (WaitableTimer == INVALID_HANDLE_VALUE)
214 {
215 wprintf(L"CreateWaitabletimer() failed\n");
216 return 1;
217 }
218 lint.QuadPart = -2000000;
219 if (!SetWaitableTimer(WaitableTimer, &lint, 200, NULL, NULL, FALSE))
220 {
221 wprintf(L"SetWaitableTimer() failed: 0x%lx\n", GetLastError());
222 return 2;
223 }
224 SetConsoleActiveScreenBuffer(ScreenBuffer);
225 MainLoop();
226 CloseHandle(ScreenBuffer);
227 return EXIT_SUCCESS;
228 }
229
230 /* EOF */
231