Difference between revisions of "1K Intro"

From SizeCoding
Jump to: navigation, search
Line 3: Line 3:
  
 
Windows 1K Intros can be setup in C or Aseembler, or a combination of both, with only the few windows calls that are used being linked in.
 
Windows 1K Intros can be setup in C or Aseembler, or a combination of both, with only the few windows calls that are used being linked in.
In general writing everything in assembler should give you a little more freedom in pushing/popping your function arguments but in th past quality intros have been written in both languages.
+
In general writing everything in assembler should give you a little more freedom in pushing/popping your function arguments but in the past quality intros have been written in both languages.
 +
 
 +
Graphics are usualy done using OpenGL / GLSL, but there are 1K intros out there that have used D3D/DX11 instead.
 +
 
  
Graphics are usualy done using OpenGL / GLSL, but there are 1K intros out there that have used D3D instead.
 
  
 
=== Setup (Windows) ===
 
=== Setup (Windows) ===
* ChangeDisplaySettings(&screenSettings, CDS_FULLSCREEN) - Initialise fullscreen view
+
* <code>ChangeDisplaySettings(&screenSettings, CDS_FULLSCREEN)</code> - Initialise fullscreen view
* hwnd = CreateWindow((LPCSTR)0xC018, 0, WS_POPUP | WS_VISIBLE | WS_MAXIMIZE, 0, 0, 0, 0, 0, 0, 0, 0) - Setting up a Maximised Window
+
* <code>hwnd = CreateWindow((LPCSTR)0xC018, 0, WS_POPUP | WS_VISIBLE | WS_MAXIMIZE, 0, 0, 0, 0, 0, 0, 0, 0)</code> - Setting up a Maximised Window
* GetDC(hwnd) - Get DeviceContext handle
+
* <code>hdc = GetDC(hwnd)</code> - Get DeviceContext handle
* ChoosePixelFormat(hDC, &pfd) - Set pixelformat describer by pfd to DeviceContext handle
+
* <code>ChoosePixelFormat(hdc, &pfd)</code> - Set pixelformat describer by pfd to DeviceContext handle
* ShowCursor(NULL) - Hide mousecursor (usually required by compo rules)
+
* <code>ShowCursor(NULL)</code> - Hide mousecursor (usually required by compo rules)
  
 
=== Setup (OpenGL) ===
 
=== Setup (OpenGL) ===
* glContent = wglCreateContext(hDC) - Create OpenGL context
+
* <code>glContext = wglCreateContext(hdc) - Create OpenGL context
* wglMakeCurrent(hDC, glContext) - Set OpenGL Context
+
* <code>wglMakeCurrent(hdc, glContext) - Set OpenGL Context
* shaderProgam = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &shader) - Create and compile GLSL Shader
+
* <code>shaderProgam = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &shader) - Create and compile GLSL Shader
* glUseProgram(shaderProgram) - Set active shader
+
* <code>glUseProgram(shaderProgram) - Set active shader
  
 
=== Update Loop ===
 
=== Update Loop ===
* t = GetTickCount() - Optional: Get Current ticks
+
* <code>t = GetTickCount()</code> - Optional: Get Current ticks
* glColor3us(t,0,0) / glColor3i(t,0,0) - Parse time via gl_Color (saves importing uniform functions)
+
* <code>glColor3us(t,0,0) / glColor3i(t,0,0)</code> - Parse time via gl_Color (saves importing uniform functions)
* glRects(-1,-1,1,1) / glRecti(-1,-1,1,1) - Draw a single quad with current Shader
+
* <code>glRects(-1,-1,1,1) / glRecti(-1,-1,1,1)</code> - Draw a single quad with current Shader
* SwapBuffers(hDC) - Swap Buffers
+
* <code>SwapBuffers(hDC)</code> - Swap Buffers
* PeekMessageA(0, 0, 0, 0, PM_REMOVE) - Optional: Unanswered messages might stack up, but in practice you should be fine in fullscreen
+
* <code>PeekMessageA(0, 0, 0, 0, PM_REMOVE)</code> - Optional: Unanswered messages might stack up, but in practice you should be fine in fullscreen
* GetAsyncKeyState(VK_ESCAPE) - Checks for escape key (required by compo rules)
+
* <code>GetAsyncKeyState(VK_ESCAPE)</code> - Checks for escape key (required by compo rules)
  
 
=== Closedown ===
 
=== Closedown ===
* ExitProcess(0) - Close down application
+
* <code>ExitProcess(0)</code> - Close down application
  
  

Revision as of 05:08, 12 April 2024

Introduction

This category is dedicated to 1K Intros for Windows 32.

Windows 1K Intros can be setup in C or Aseembler, or a combination of both, with only the few windows calls that are used being linked in. In general writing everything in assembler should give you a little more freedom in pushing/popping your function arguments but in the past quality intros have been written in both languages.

Graphics are usualy done using OpenGL / GLSL, but there are 1K intros out there that have used D3D/DX11 instead.


Setup (Windows)

  • ChangeDisplaySettings(&screenSettings, CDS_FULLSCREEN) - Initialise fullscreen view
  • hwnd = CreateWindow((LPCSTR)0xC018, 0, WS_POPUP | WS_VISIBLE | WS_MAXIMIZE, 0, 0, 0, 0, 0, 0, 0, 0) - Setting up a Maximised Window
  • hdc = GetDC(hwnd) - Get DeviceContext handle
  • ChoosePixelFormat(hdc, &pfd) - Set pixelformat describer by pfd to DeviceContext handle
  • ShowCursor(NULL) - Hide mousecursor (usually required by compo rules)

Setup (OpenGL)

  • glContext = wglCreateContext(hdc) - Create OpenGL context
  • <code>wglMakeCurrent(hdc, glContext) - Set OpenGL Context
  • <code>shaderProgam = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &shader) - Create and compile GLSL Shader
  • <code>glUseProgram(shaderProgram) - Set active shader

Update Loop

  • <code>t = GetTickCount() - Optional: Get Current ticks
  • glColor3us(t,0,0) / glColor3i(t,0,0) - Parse time via gl_Color (saves importing uniform functions)
  • glRects(-1,-1,1,1) / glRecti(-1,-1,1,1) - Draw a single quad with current Shader
  • SwapBuffers(hDC) - Swap Buffers
  • PeekMessageA(0, 0, 0, 0, PM_REMOVE) - Optional: Unanswered messages might stack up, but in practice you should be fine in fullscreen
  • GetAsyncKeyState(VK_ESCAPE) - Checks for escape key (required by compo rules)

Closedown

  • ExitProcess(0) - Close down application


Graphics / effect

So when it comes to writing your 1K shader/effect, there are a couple to tricks you can utilise to get a small shader footpring

  • Make use of the benefits of (Legacy) Desktop GLSL by using integers for smaller notation
  • Make use of the fixed resolution to convert gl_FragCoord to UV -1..1 (this will have your centerY slightly off-centered)
  • Pass time via glColor (no uniforms used)
  • Using global variables to save space

Minimal GLSL example code

float t=gl_Color.x*1e7;
void main(){
vec2 p=gl_FragCoord.xy/960-1;
gl_FragColor=vec4(sin(p.x+t),0,p.y,1);
}

Shader minifier

While a shader minifier can be helpful at times, it will not save you from writing sloppy code or unthoughtful approaches. For most 4k's people can get away with sub-par optimised code and let shader-minifier do the work for you, but for 1k this is just not enough.

Sound

  • Win32 Single Note MIDI
  • Win32 MIDI player
  • Bytebeat softsynth
  • Shader softsynth

Compression

Microsoft Cabinet decmpression

These functions allow for MSZIP (deflate) and MSLZ content to be loaded from the binary as payload at the cost of a a few more win32 function imports. Well this might be a good solution for 512 byte intros, the tipping point for Crinkler compression at the moment lies at the 800-850 byte mark give or take.

Crinkler

Crinkler is the most commonly used compression at the moment for many 1K and 4K intros. It has a seperate settings for 1K intro, namely /TINYIMPORT and /TINYHEADER which will better match the 1K usecase.

Crinkler reports

When using the /REPORT:intro_report.html feature, crinkler will generate a report and heatmap for your intro binary. This is helpful to see how good your (shader)code compresses and where you can maybe gain a few more bytes.

Word about the resulting executable

Please note that when using crinkler in TINYHEADER mode, the resulting windows header will most likely trigger virus scanners / microsoft defender and mark it as suspicious content, which is a side-effect in recent years. Just exclude your work directory from this scan during development. Compo machines will run without these scanners too, but it is good practice to include a (slightly larger) safe version too in the final archive.

Frameworks

1K intros for Windows