Skip to content

Commit 3657d8c

Browse files
authored
Merge pull request #573 from diogotrentini/main
Update guides
2 parents 1ca55a1 + 7eb512e commit 3657d8c

File tree

8 files changed

+240
-31
lines changed

8 files changed

+240
-31
lines changed

site/docs/guides/audio.md

+20-2
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ Setting ADSR flags require the use of various bitwise and bitshift operations. T
375375

376376
These functions can be used to understand how they are calculated:
377377

378-
<!-- <MultiLanguageCode> -->
378+
<MultiLanguageCode>
379379

380380
```typescript
381381
function toneFrequency(freq1: i32 = 0, freq2: i32 = 0): u32 {
@@ -395,7 +395,25 @@ function toneFlags(channel: i32 = 0, mode: i32 = 0, pan: i32 = 0): u32 {
395395
}
396396
```
397397

398-
<!-- </MultiLanguageCode> -->
398+
```rust
399+
fn tone_frequency(freq1: u32, freq2: u32) -> u32 {
400+
freq1 | (freq2 << 16)
401+
}
402+
403+
fn tone_duration(attack: u32, decay: u32, sustain: u32, release: u32) -> u32 {
404+
(attack << 24) | (decay << 16) | sustain | (release << 8)
405+
}
406+
407+
fn tone_volume(peak: u32, volume: u32) -> u32 {
408+
(peak << 8) | volume
409+
}
410+
411+
fn tone_flags(channel: u32, mode: u32, pan: u32) -> u32 {
412+
channel | (mode << 2) | (pan << 4)
413+
}
414+
```
415+
416+
</MultiLanguageCode>
399417

400418
## Sound Tool
401419

site/docs/guides/multiplayer.md

+17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Multiplayer
22

3+
import MultiLanguageCode from '@site/src/components/MultiLanguageCode';
4+
35
WASM-4 supports realtime multiplayer of up to 4 players, either locally or online.
46

57
Detecting [gamepad input](/docs/guides/user-input#gamepad) for Player 2 is the same as usual, but instead of
@@ -51,6 +53,8 @@ memory register.
5153
Reading this register is not required to implement netplay, but it can be used to implement advanced
5254
features such as non-shared screen multiplayer:
5355

56+
<MultiLanguageCode>
57+
5458
```c
5559
// If netplay is active
5660
if (*NETPLAY & 0b100) {
@@ -60,6 +64,19 @@ if (*NETPLAY & 0b100) {
6064
}
6165
```
6266

67+
```rust
68+
unsafe {
69+
// If netplay is active
70+
if *NETPLAY & 0b100 != 0 {
71+
let player_idx = *NETPLAY & 0b011;
72+
// Render the game from player_idx's perspective
73+
// ...
74+
}
75+
}
76+
```
77+
78+
</MultiLanguageCode>
79+
6380
This is a powerful feature enabling games with hidden information, like card games, strategy games,
6481
and first person shooters. However, caution must be taken by developers to not introduce
6582
desynchronization. In other words, the netplay player index should only be used to adjust how a

site/docs/guides/sprites.md

+38-2
Original file line numberDiff line numberDiff line change
@@ -338,20 +338,40 @@ w4 png2src --assemblyscript bunny.png
338338

339339
Will print out the following generated source:
340340

341+
<MultiLanguageCode>
342+
341343
```typescript
342344
const bunny_width = 16;
343345
const bunny_height = 16;
344346
const bunny_flags = 1; // BLIT_2BPP
345347
const bunny = memory.data<u8>([ 0xaa,0x9e,0xac,0xaa,0xaa,0x57,0xbf,0x2a,0xaa,0x57,0xbf,0x2a,0xaa,0x17,0xbf,0x2a,0xaa,0x17,0x03,0x2a,0xaa,0x57,0x54,0x2a,0xa8,0x55,0x55,0x6a,0xa9,0x55,0x05,0x0a,0xaf,0xd5,0x55,0x4a,0xa8,0x75,0x55,0x4a,0xaa,0xd5,0x57,0x2a,0xaa,0x1d,0x7c,0xaa,0xa8,0x75,0x15,0x2a,0xa8,0x45,0x15,0x2a,0xaa,0x10,0x54,0xaa,0xaa,0x85,0x52,0xaa ]);
346348
```
347349

350+
```rust
351+
const BUNNY_WIDTH: u32 = 16;
352+
const BUNNY_HEIGHT: u32 = 16;
353+
const BUNNY_FLAGS: u32 = 1; // BLIT_2BPP
354+
const BUNNY: [u8; 64] = [ 0xaa,0x9e,0xac,0xaa,0xaa,0x57,0xbf,0x2a,0xaa,0x57,0xbf,0x2a,0xaa,0x17,0xbf,0x2a,0xaa,0x17,0x03,0x2a,0xaa,0x57,0x54,0x2a,0xa8,0x55,0x55,0x6a,0xa9,0x55,0x05,0x0a,0xaf,0xd5,0x55,0x4a,0xa8,0x75,0x55,0x4a,0xaa,0xd5,0x57,0x2a,0xaa,0x1d,0x7c,0xaa,0xa8,0x75,0x15,0x2a,0xa8,0x45,0x15,0x2a,0xaa,0x10,0x54,0xaa,0xaa,0x85,0x52,0xaa ];
355+
```
356+
357+
</MultiLanguageCode>
358+
348359
Pasting that into our program, we can draw a bunny like so:
349360

361+
<MultiLanguageCode>
362+
350363
```typescript
351364
*DRAW_COLORS = 0x2013;
352365
blit(bunny, 10, 10, bunny_width, bunny_height, bunny_flags);
353366
```
354367

368+
```rust
369+
unsafe { *DRAW_COLORS = 0x2013 }
370+
blit(&BUNNY, 10, 10, BUNNY_WIDTH, BUNNY_HEIGHT, BUNNY_FLAGS);
371+
```
372+
373+
</MultiLanguageCode>
374+
355375
[`DRAW_COLORS`](basic-drawing) is used here to modify the 4 colors of the original sprite. Reading
356376
from right to left: color 1 becomes 3, color 2 becomes 1, color 3 becomes 0 (transparent), and color
357377
4 becomes 2.
@@ -363,8 +383,11 @@ Use a `--template filename` for this.
363383

364384
Templates use the `Mustache` syntax. An array called `sprites` is provided.
365385

366-
Basic template (C):
367-
```
386+
Basic template:
387+
388+
<MultiLanguageCode>
389+
390+
```c
368391
{{#sprites}}
369392
// {{name}}
370393
#define {{name}}Width {{width}}
@@ -375,6 +398,19 @@ const uint8_t {{name}}[{{length}}] = { {{bytes}} };
375398
{{/sprites}}
376399
```
377400
401+
```rust
402+
{{#sprites}}
403+
// {{name}}
404+
const {{rustName}}_WIDTH: u32 = {{width}};
405+
const {{rustName}}_HEIGHT: u32 = {{height}};
406+
const {{rustName}}_FLAGS: u32 = {{flagsHumanReadable}};
407+
const {{rustName}}: [u8; {{length}}] = [ {{bytes}} ];
408+
409+
{{/sprites}}
410+
```
411+
412+
</MultiLanguageCode>
413+
378414
Where:
379415
- `{{#sprites}}`, `{{/sprites}}` - Start and end of the list of sprites
380416
- `{{name}}` - filename (i.e. `wallTop`; string),

site/docs/guides/text.md

+132-19
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ w4.text("Hello world!", 10, 10);
6969

7070
The WASM-4 font contains 224 characters total.
7171

72-
<img src="/img/charset.png" width="256" height="224" class="pixelated"/>
72+
<img src="/img/charset.png" width="256" height="224" className="pixelated"/>
7373

7474
Aside from text and symbols, many slots are empty. This is because in ASCII, the text format used for the `text()` function, doesn't have any character indexed to it. Moreover, some of them *are* mapped, but as control characters.
7575

@@ -80,37 +80,41 @@ It's possible to print one of these characters by escaping it's charcode.
8080

8181
| Key | Escape Character |
8282
|-------------|------------------|
83-
| A button | `\x80` |
84-
| B button | `\x81` |
83+
| X button | `\x80` |
84+
| Y button | `\x81` |
8585
| Left arrow | `\x84` |
8686
| Right arrow | `\x85` |
8787
| Up arrow | `\x86` |
8888
| Down arrow | `\x87` |
8989

9090
We could use those as instructions for our games!
9191

92-
<!-- <MultiLanguageCode> -->
92+
<MultiLanguageCode>
9393

9494
```typescript
9595
// Press UP to jump!
9696
w4.text("Press \x86 to jump!", 10, 10);
9797
```
9898

99-
<!-- </MultiLanguageCode> -->
99+
```rust
100+
// Press UP to jump!
101+
text(b"Press \x86 to jump!", 10, 10);
102+
```
103+
104+
</MultiLanguageCode>
100105

101106
## Custom Fonts
102107

103108
Since WASM-4 doesn't have a custom font, we have to figure a way to implement our own. One way to approach this is treating a font like a tilemap, except we're indexing characters instead of numbers!
104109

105110
The example below will print a text using the [BitScript sprite font](https://opengameart.org/content/bitscript-a-low-res-handwriting-font):
106111

107-
<!-- <MultiLanguageCode> -->
112+
<MultiLanguageCode>
108113

109114
```typescript
110115
import * as w4 from "./wasm4";
111116

112117
const fontWidth = 208;
113-
const fontHeight = 8;
114118
const fontFlags = w4.BLIT_1BPP;
115119
const charWidth = 8;
116120
const charHeight = 8;
@@ -143,6 +147,18 @@ const font = memory.data<u8>([
143147
0x42, 0x2c, 0x82, 0x84, 0x3a, 0x40, 0x08, 0x86,
144148
0x38, 0x40, 0x3a, 0x10, 0x48, 0x46, 0x30, 0x66
145149
]);
150+
151+
function drawSpace(x: i32, y: i32, column: i32, line: i32, colors: u16) {
152+
store<u16>(w4.DRAW_COLORS, w4.DRAW_COLORS & 0x0F);
153+
w4.rect(
154+
x + (column * CHAR_WIDTH),
155+
y + (line * CHAR_HEIGHT),
156+
CHAR_WIDTH,
157+
CHAR_HEIGHT
158+
);
159+
store<u16>(w4.DRAW_COLORS, colors);
160+
}
161+
146162
function write(text: string, x: i32, y: i32, colors: u16): void {
147163
// Set draw colors...
148164
store<u16>(w4.DRAW_COLORS, colors);
@@ -151,32 +167,24 @@ function write(text: string, x: i32, y: i32, colors: u16): void {
151167
let line : i32 = 0;
152168
let column: i32 = 0;
153169

154-
// Special characters: "\n" (newline) and " " (space).
155-
const newline: i32 = 10;
156-
const space : i32 = 32;
157-
158170
// Iterate through each character...
159171
for(let i = 0; i < text.length; i += 1) {
160172
const char: string = text.charAt(i);
161173
const charCode: i32 = char.charCodeAt(0);
162174

163175
// Break into next line when encounter a "\n" (newline)...
164-
if(charCode === newline) {
176+
if(charCode === 10) {
165177
line += 1;
166178
column = 0;
167179
continue;
168180
}
169-
// Advance to next column when encounter a " " (space)...
170-
else if(charCode === space) {
171-
column += 1;
172-
continue;
173-
}
174181

175182
// Character index on charset.
176183
let charIndex: i32 = charset.indexOf(char);
177184

178-
// Skip invalid characters...
185+
// Skip invalid characters, spaces, etc.
179186
if(charIndex < 0 || charIndex >= charset.length) {
187+
drawSpace(x, y, column, line, colors);
180188
column += 1;
181189
continue;
182190
}
@@ -204,4 +212,109 @@ export function update (): void {
204212
}
205213
```
206214

207-
<!-- </MultiLanguageCode> -->
215+
```rust
216+
use crate::wasm4::*;
217+
218+
const FONT_WIDTH: u32 = 208;
219+
const FONT_FLAGS: u32 = BLIT_1BPP;
220+
const CHAR_WIDTH: u32 = 8;
221+
const CHAR_HEIGHT: u32 = 8;
222+
const CHARSET: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
223+
const FONT: &'static [u8] = &[
224+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227+
0x00, 0x00, 0x08, 0x1c, 0x1c, 0x3c, 0x18, 0x3e,
228+
0x1c, 0x26, 0x10, 0x2c, 0x12, 0x08, 0x24, 0x26,
229+
0x1c, 0x3c, 0x1c, 0x78, 0x1c, 0x3c, 0x62, 0x42,
230+
0x82, 0xc4, 0x42, 0x66, 0x08, 0x32, 0x22, 0x52,
231+
0x24, 0x51, 0x22, 0x25, 0x28, 0x14, 0x14, 0x08,
232+
0x24, 0x26, 0x22, 0x52, 0x22, 0xa4, 0x22, 0x52,
233+
0x22, 0xa5, 0x44, 0x2a, 0x24, 0x1c, 0x14, 0x52,
234+
0x20, 0x12, 0x20, 0x10, 0x20, 0x26, 0x28, 0x04,
235+
0x14, 0x08, 0x2c, 0x24, 0x22, 0x52, 0x22, 0xa4,
236+
0x20, 0x10, 0x22, 0x24, 0x54, 0x10, 0x24, 0x04,
237+
0x14, 0x5c, 0x40, 0x22, 0x38, 0x38, 0x4e, 0x7c,
238+
0x28, 0x08, 0x28, 0x10, 0x54, 0x58, 0x42, 0x14,
239+
0x44, 0x78, 0x18, 0x10, 0x24, 0x28, 0x54, 0x10,
240+
0x14, 0x08, 0x24, 0xa4, 0x40, 0x62, 0x40, 0x20,
241+
0x44, 0x48, 0x10, 0x08, 0x34, 0x30, 0x54, 0x48,
242+
0x44, 0x20, 0x54, 0x48, 0x04, 0x20, 0x44, 0x28,
243+
0x2c, 0x28, 0x08, 0x10, 0x3c, 0xa4, 0x42, 0xa4,
244+
0x44, 0xa0, 0x44, 0xc9, 0x10, 0x48, 0x24, 0x52,
245+
0x44, 0x4a, 0x44, 0xa0, 0x3a, 0x48, 0x44, 0xa0,
246+
0x44, 0x10, 0x28, 0xa8, 0x48, 0x38, 0x42, 0x5b,
247+
0x3c, 0x58, 0x38, 0x40, 0x38, 0x46, 0x68, 0x34,
248+
0x42, 0x2c, 0x82, 0x84, 0x3a, 0x40, 0x08, 0x86,
249+
0x38, 0x40, 0x3a, 0x10, 0x48, 0x46, 0x30, 0x66
250+
];
251+
252+
fn draw_space(x: i32, y: i32, column: u32, line: u32, colors: u16) {
253+
unsafe { *DRAW_COLORS = *DRAW_COLORS & 0x0F }
254+
rect(
255+
x + (column * CHAR_WIDTH) as i32,
256+
y + (line * CHAR_HEIGHT) as i32,
257+
CHAR_WIDTH,
258+
CHAR_HEIGHT
259+
);
260+
unsafe { *DRAW_COLORS = colors }
261+
}
262+
263+
pub fn write(text: &str, x: i32, y: i32, colors: u16) {
264+
// Set draw colors...
265+
unsafe { *DRAW_COLORS = colors }
266+
267+
// Line and column counters.
268+
let mut line: u32 = 0;
269+
let mut column: u32 = 0;
270+
271+
// Iterate through each character...
272+
for c in text.chars() {
273+
let char_code = c as u32;
274+
275+
// Break into next line when encounter a "\n" (newline)...
276+
if char_code == 10 {
277+
line += 1;
278+
column = 0;
279+
continue;
280+
}
281+
282+
// Character index on charset.
283+
let char_index: u32;
284+
285+
match CHARSET.find(c) {
286+
Some(x) => char_index = x as u32,
287+
288+
// Skip invalid characters, spaces, etc.
289+
None => {
290+
draw_space(x, y, column, line, colors);
291+
column += 1;
292+
continue;
293+
}
294+
}
295+
296+
// Draw character...
297+
blit_sub(
298+
FONT,
299+
x + (column * CHAR_WIDTH) as i32,
300+
y + (line * CHAR_HEIGHT) as i32,
301+
CHAR_WIDTH,
302+
CHAR_HEIGHT,
303+
char_index * CHAR_WIDTH,
304+
0,
305+
FONT_WIDTH,
306+
FONT_FLAGS
307+
);
308+
309+
// Advance to next column...
310+
column += 1;
311+
}
312+
}
313+
314+
#[no_mangle]
315+
fn update() {
316+
custom::write("HELLO WORLD WITH\nOUR CUSTOM FONT", 4, 4, 0x30);
317+
}
318+
```
319+
320+
</MultiLanguageCode>

0 commit comments

Comments
 (0)