KITAQ SYSTÈME DE DÉVELOPPEMENT
MANUEL D'UTILISATION 2026.09

KITAQ SERIES • ÉDITION DE RÉFÉRENCE

BIBLIOTHÈQUE KITAQGB

Outils pour créer un jeu

De votre première ligne à l'exécution, à l'observation et aux nouveaux tests.
Copie des sources : 14 septembre 2026 · Édition anglaise de référence : 14 septembre 2026

Utiliser la bibliothèque avec le compilateur natif

lib/ contient les en-têtes et sources C compilés dans la ROM de la console. Le compilateur pour PC et les outils auxiliaires sont en Rust ; les sources de jeux, bibliothèques cibles et API restent en C. SOURCE_MANIFEST.json et LIBRARY_MERGE.json consignent les sources retenues lorsqu'ils sont fournis.

kitaqgb · Compilateur natif Rust et outils auxiliaires · GitHub Actions

Les constructions natives et vérifications d'exécution ont réussi sous Windows, Linux, macOS ARM et macOS Intel. KITAQGB a passé 48 tests et 395 vérifications d'outils par environnement ; KITAQFC en a passé 55 et 401. Rust 1.85 a également été testé. PUBLIC_DISTRIBUTION.json consigne les empreintes des binaires installés et la provenance des validations. Les workflows GitHub Actions publics reconstruisent et testent ces sources indépendamment.

Les sorties de référence conservées vérifient les octets ROM, les diagnostics et les formats des outils. Les anciennes preuves d'émulation C# restent des résultats historiques liés à leurs empreintes sources. Elles ne prouvent pas automatiquement toutes les API Rust, le matériel réel ou le démarrage complet d'un jeu par le BIOS FDS. Le script PNG d'origine, indisponible, a été réimplémenté d'après sa spécification ; l'identité des octets avec ce script ne peut être affirmée.

KITAQGB · SHA-256 · KITAQFC · SHA-256

Bibliothèque locale : changements et vérification du 2026-10-03

Les sources de C:/kitaqgb_project/lib ont été comparées à la révision publique 2de7f4b. Les dates seules ne déterminent pas la version la plus récente. La version locale comporte des ajouts ; la version publique contient d’autres ajouts et corrections. Cette section décrit les sources locales conservées, séparément des preuves existantes de l’API publique.

physics2d.c conserve l’API de contact et ajoute des implémentations avec cache pour les contacts et la limite de vitesse sous KQ2D_CACHE_SURFACE. Réservez la banque ROM 13 si vous l’activez. Définir KQ2D_EXTERNAL_SCALE_Q8, KQ2D_EXTERNAL_REST_COMPONENT ou KQ2D_EXTERNAL_SURFACE exige de fournir l’implémentation correspondante. Les 8 872 cas ci-dessous utilisent le chemin par défaut, sans ces définitions.

KQ3D_BODY_SPHERE=0x04 sélectionne les contacts sphère–boîte. Le rayon est half_x. kq3d_overlap_sphere_aabb(sphere, box) inclut la tangence et renvoie 0 si un pointeur est NULL ou si le rayon est nul ou négatif. Aucun solveur dédié aux paires de sphères n’est fourni. Gardez différences, produits et sommes des carrés dans leurs plages de 16 bits.

Un body actif portant KQ3D_BODY_KINEMATIC=0x02 met à jour vitesse et position X/Y dans kq3d_step, même avec une masse inverse nulle. Sa position et sa vitesse Z restent inchangées. Les contacts ne déplacent pas un body de masse inverse nulle. kq3d_integrate_body ignore toujours les bodies statiques. break_speed et KQ3D_BODY_BROKEN ne déclenchent aucune destruction automatique.

Le bank_switch local écrit kq_bank_current et l’adresse 0x2000. Contrairement au chemin public __bankswitch, il ne met pas à jour le suivi de banque du compilateur. Changez de banque depuis la banque fixe ; utilisez __bankswitch si l’état de restauration doit aussi être maintenu.

Les fonctions locales cgb_bg_color/cgb_obj_color et leurs enveloppes RGB unitaires n’activent pas l’incrément automatique de l’index. L’exécution CGB confirme que l’octet bas de 0x1234 est écrasé par 0x12. Utilisez la correction publique ou une API colors prenant un tableau. Aucun accès en écriture n’est effectué sur DMG.

Le metasprite_draw local étend le compteur à first_id+count uniquement après achèvement. Un retour anticipé à la limite de 40 sprites ne le met pas à jour. Avec first_id=39 et count=2, le résultat est 1, l’emplacement 39 est actif et le compteur vaut 0. La version publique actualise le compteur à chaque emplacement traité.

La version locale fournit vram_get_queue_used et vram_get_queue_free, mais pas le vram_get_queue_capacity public. La capacité est VRAM_QUEUE_MAX, soit 32 par défaut. Une commande donne used=1 et free=31.

wire3d_dmg.h déclare DrawRect2D uniquement pour le profil de 96 lignes. DrawBoxEdges2D est déclaré pour les deux profils, DrawIndexedEdges seulement pour 120 lignes. Choisissez une seule source adaptée au profil. Le rendu de ces fonctions n’a pas été revérifié ici. Aucune implémentation de DrawRect2D ou DrawBoxEdges2D n’a été trouvée dans les sources lib conservées. Ce sont des déclarations seules ; leur appel exige une implémentation séparée.

Le audio_vblank local ne contient ni AudioVBlank_QueueReset/QueueRefill/QueuePlay ni audio_vblank_queue.inc de la version publique. ZX0 n’existe également que dans la version publique. Ces ajouts sont exclus des fonctions locales déclarées vérifiées.

kq3d_overlap_sphere_aabb
u8 kq3d_overlap_sphere_aabb(const KQBody3D* sphere, const KQBody3D* box);

KQ3D_BODY_SPHERE=0x04 sélectionne les contacts sphère–boîte. Le rayon est half_x. kq3d_overlap_sphere_aabb(sphere, box) inclut la tangence et renvoie 0 si un pointeur est NULL ou si le rayon est nul ou négatif. Aucun solveur dédié aux paires de sphères n’est fourni. Gardez différences, produits et sommes des carrés dans leurs plages de 16 bits.

physics3d.c / physics3d.h

Vérifications exécutées

Chemin 2D par défaut : 8 872 cas réussis via l’API C de KOKURA, avec sélection automatique du matériel. Limite de vitesse, contacts, multiplication Q8 signée et instant de contact ont été contrôlés. Il ne s’agit pas de deux exécutions DMG/CGB explicitement sélectionnées.

Limites physiques : 19 cas sur DMG et CGB, soit 38 exécutions réussies. Les essais séparés d’extensions 3D et de reproduction sprite/VRAM/palette correspondent aux attentes dans les deux modes. Les résultats palette et sprite reproduisent des défauts ; ils ne valident pas un fonctionnement correct.

Ces essais sur émulateur concernent les ROM produites par le compilateur C#. Ils ne prouvent ni l’équivalence Rust, ni le matériel réel, ni l’audio, ni le rendu, ni la validité de toutes les API. Les images et essais existants restent des résultats historiques liés aux empreintes de sources enregistrées.

Empreintes des sources, entrées, valeurs attendues et observées, procédure de reproduction · evidence.tar.gz · verify_rom_cases.py · verify_surface.py

1. Utiliser la bibliothèque

La bibliothèque rassemble des sources C réutilisables qui s'appuient sur les fonctions intrinsèques __ de KITAQGB. Elle couvre aussi bien l'affichage que la physique, la 3D et la communication.

c
#include "input.h"
// 起動時に一度
input_init();
// ゲームの1フレームに一度
input_update();
if (input_pressed(BTN_A)) { /* 決定処理 */ }
powershell
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\input.c .\kitaq-docs\samples\gb_input.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\input.gb --profile=dev

Chaque entrée d’API présente la déclaration, l’en-tête, l’implémentation et un exemple d’utilisation. Les fragments montrent comment passer les arguments ; le programme appelant doit préparer les tampons et objets nécessaires. La section des programmes complets contient des exemples directement compilables en ROM.

2. Construire une image de jeu

system_init initialise la gestion des images. system_wait_vblank attend puis incrémente le compteur logiciel d'images. Sur GB, le rappel VBlank est appelé de manière coopérative par cette fonction d'attente ; son enregistrement n'installe pas de gestionnaire d'interruption matérielle.

  1. Actualisez les commandes une fois.
  2. Calculez les déplacements, les collisions et l'état du jeu.
  3. Préparez les commandes de dessin et l'OAM.
  4. Appliquez les mises à jour pendant VBlank.
  5. Faites avancer la musique selon le pilote choisi.

Combiner des opérations d'attente comme vram_flush et sprite_flush_oam peut faire attendre deux images pour une seule mise à jour du jeu. Après avoir effectué l'attente vous-même, une opération _now correspondante peut convenir, à condition d'en garantir les contraintes temporelles.

3. Commandes et répétition

input_down(mask) teste un bouton maintenu, input_pressed(mask) un nouvel appui, input_released(mask) un relâchement, et input_repeat(mask) assure une répétition adaptée aux menus. Ces états sont actualisés par input_update(). Répéter cet appel dans une même image peut effacer l'événement de nouvel appui.

BoutonsMasques
Droite, gauche, haut, bas0x01 / 0x02 / 0x04 / 0x08
A, B, SELECT, START0x10 / 0x20 / 0x40 / 0x80

L'exemple gb_input.c compte les appuis sur A. Vérifiez que maintenir A n'incrémente pas le compteur en continu, puis remplacez input_pressed par input_down pour observer la différence.

4. Arrière-plans, texte et VRAM

vram_queue_bg_tile met une tuile en file, vram_queue_bg_rect un rectangle et vram_queue_bg_block le transfert d'un tableau. Vérifiez les valeurs de retour et vram_get_overflowed() pour détecter un dépassement de capacité. Si une opération conserve un pointeur source, ses données doivent rester inchangées, sa mémoire valide et sa banque accessible jusqu'à la fin du transfert.

text.c et menu.c implémentent les services de texte, de choix et de fenêtres déclarés dans rpg.h. Faites correspondre la conversion texte-vers-tuile à la police chargée en VRAM. Elle n'est pas nécessairement identique à celle de la fonction pédagogique m_text de ce manuel.

5. Sprites et animation

Commencez par sprite_init, sprite_alloc, sprite_set_tile et sprite_set_pos. La GB autorise 40 sprites au total et 10 par ligne de balayage : tenez compte de leur concentration horizontale, pas seulement de leur nombre. sprite_warn_scanline_overflow et sprite_max_scanline_count permettent d'examiner une disposition.

MetaSpritePart décrit le placement relatif des OBJ. SpriteAnim décrit les tuiles d'animation et leurs intervalles de mise à jour. Faites correspondre les éléments dessinés par metasprite_draw aux emplacements OBJ alloués. Le A de gb_sprite.c montre comment employer une tuile de caractère comme sprite.

6. Couleur, défilement, effets raster et caméras

Les composantes RGB de cgb_bg_rgb et cgb_obj_rgb vont de 0 à 31, et non de 0 à 255. CGB_RGB15 les regroupe dans une valeur sur 16 bits. Les fonctions de palette CGB de haut niveau sont conçues pour ne rien faire sur DMG.

Scroll_SetBg positionne l'arrière-plan, Scroll_SetWindow la fenêtre, et le module caméra calcule la vue à partir des coordonnées du monde. Distinguez les unités en virgule fixe de la caméra des pixels entiers à l'écran.

raster.c construit des tables de défilement par bandes et des déformations horizontales ligne par ligne. Les opérations Scroll_SplitCommit utilisent les vecteurs VBlank/STAT. Ne laissez pas des gestionnaires de musique et de défilement s'approprier indépendamment le même vecteur ; prévoyez au besoin un répartiteur commun.

7. Musique et effets sonores

Compilez audio_hwregs_gb.c, puis audio.c, puis le source du jeu. Ne dupliquez pas les définitions des registres NR10 à NR52 si le jeu les fournit déjà. Après Audio_Init, appelez normalement Audio_Update une fois par image.

Audio_PlayMusic(bank,song) indique explicitement la banque de la musique. Audio_PlaySFXBanked joue un effet depuis une autre banque. Les priorités départagent les effets qui partagent des canaux physiques. La GB possède quatre canaux sonores physiques : CH1, CH2, CH3 et CH4.

Les commandes du flux musical AUDIO_CMD_NOTE, AUDIO_CMD_SET_INST et AUDIO_CMD_STOP_CHANNEL utilisent les mêmes identifiants de canal que l’API ordinaire : 0=CH1, 1=CH2, 2=CH3, 3=CH4. CH1 produit une onde impulsionnelle avec balayage, CH2 une onde impulsionnelle, CH3 une forme d’onde et CH4 du bruit. L’en-tête définit AUDIO_NOTE_MAX=67.

Le flux d'effet CH1 de base lit une paire note/volume par image et se termine sur la note 0. CH3 utilise un marqueur et un format différents. Consultez gb_sound.c. Les fondus progressent pendant Audio_Update ; arrêter les mises à jour arrête aussi le fondu.

8. Musique par interruption VBlank

audio_vblank.c utilise un format de lecture distinct. Chaque enregistrement temporisé contient cinq octets : delay, ch1_note, ch2_note, ch3_note, ch4_noise_param. Le pilote lit des morceaux directement adressables ou consomme une file en WRAM. Initialisez le mode file avec AudioVBlank_QueueReset, fournissez des enregistrements complets de cinq octets avec AudioVBlank_QueueRefill, puis démarrez avec AudioVBlank_QueuePlay. Un seul producteur, exécuté au premier plan, doit alimenter la file. LOOP est reconnu uniquement dans les flux directs, et IMMEDIATE uniquement en mode file. Les flux ordinaires de audio.c ne peuvent pas être transmis tels quels.

powershell
# この方式を採用したROMに対してのみ行います。
.\kitaqgb\scripts\patch_gb_vblank_irq.ps1 .\out\game.gb .\out\game.map

Le correctif place le vecteur VBlank à 0x0040 et actualise la somme de contrôle. Appliquez-le uniquement à une ROM prévue pour ce pilote. Vérifiez les interactions avec les gestionnaires VBlank personnalisés et le défilement fractionné. Une compilation réussie ne prouve pas que la musique est audible : enregistrez-la avec KOKURA et vérifiez que le morceau avance.

9. Virgule fixe, physique et 3D

Dans le format Q8.8 de fixed.h, 256 représente 1,0 et 128 représente 0,5. L'exemple gb_fixed.c présente fix_from_int, fix_mul et fix_to_int. Définissez les plages de valeurs avant les calculs afin d'éviter les débordements.

physics2d traite les rectangles, physics2d_circle les cercles et physics3d les AABB tridimensionnelles. Préparez et initialisez les tableaux de monde et de corps, réglez la vitesse ou la gravité, puis faites avancer la simulation. Utilisez des unités cohérentes pour la position et la vitesse par pas ; la bibliothèque ne les convertit pas implicitement en pixels. L’exemple des cercles utilise la position 40 et la vitesse 2. Une masse inverse nulle désigne un corps statique. Consultez les en-têtes pour la représentation des coefficients et les limites des calculs intermédiaires. Attention notamment à la fonction kq2d_body_apply_friction : elle convertit son coefficient en octet signé, si bien que 128 à 255 deviennent des valeurs négatives, et non des facteurs d’amortissement Q8 non signés. gb_circle.c présente un pas complet.

wire3d_dmg est une bibliothèque de rendu filaire monochrome pour Game Boy. Compilez wire3d_dmg_96.c pour une vue de 128 × 96 ou wire3d_dmg.c pour 128 × 120, puis utilisez les fonctions Wire3DDMG_*. wire3d et dmg3d offrent aussi des points d’entrée pour les profils de 96 et 120 lignes, respectivement. Compilez un seul point d’entrée par programme. wire3d_cgb est le moteur dédié au rendu couleur. Réservez explicitement la RAM, la VRAM et les zones d’écran propres à chaque moteur. Les deux moteurs monochromes écartent les arêtes qui franchissent les limites de profondeur au lieu de les découper. L’occultation entre objets repose sur les rectangles englobants des faces et cinq points par ligne : c’est une approximation, pas un test de profondeur par pixel. Le rendu CGB utilise la double vitesse et le DMA, et exige --cgb=cgb_only.

Wire3DDMG_BeginFrame (WIRE3D_DMG_HEIGHT=96) efface le tampon de dessin. Wire3DDMG_BeginFrame (WIRE3D_DMG_HEIGHT=120) ne réinitialise que l’état d’occultation : DMG3D consomme et efface les données lors de leur transfert en VRAM. Le transfert des tuiles modifiées inclut celles de l’image précédente afin d’effacer les anciens pixels. Le transfert auxiliaire partage une partie du tampon principal ; il ne dispose pas d’un tampon indépendant. Adaptez l’ordre des opérations de chaque image au moteur choisi.

Pour les lignes CGB, utilisez les couleurs 1, 2 et 3. Le mode normal de 128 × 96 combine les bits de couleur : la superposition des couleurs 1 et 2 donne la couleur 3. La couleur 0 n'efface pas une ligne. Effacez l'image ou utilisez les fonctions d'effacement prévues à cet effet. En mode normal, Wire3DCGB_DrawLine2D et le dessin des modèles ne mémorisent pas la zone à transférer. Pour tracer des lignes en enregistrant cette zone, utilisez Wire3DCGB_DrawLineClipped2D ; pour inclure toute la zone de dessin dans le prochain transfert partiel, appelez Wire3DCGB_InvalidateFrameHistory.

Le mode de 160 × 144 alloue au maximum 127 tuiles par image. Si le tracé rapide ne peut pas allouer une tuile ou rencontre une coordonnée hors écran, Wire3DCGB_GetFullScreenOverflow() renvoie une valeur non nulle et les écritures de pixels sont suspendues jusqu'à l'initialisation de l'image suivante. Gardez les sommets dans la zone sélectionnée. La marge droite du masque triangulaire s'arrête à X=127 en mode 128 × 96 et à X=159 en plein écran. Respectez les exigences de sélection des banques WRAM indiquées pour chaque API, en particulier avec le plein écran ou FastMap.

10. Scènes, réserves d'objets et motifs de tirs

scene gère les états tels que titre, partie et pause ; entity fournit un pool d’objets à capacité fixe ; chain propose le suivi d’un corps articulé et un historique des positions. Utilisez ChainBody pour déplacer un serpent ou une corde articulés. Vérifiez les valeurs d’échec d’allocation, telles que 0xFF, avant d’utiliser le pointeur renvoyé par entity_get.

danmaku propose des réserves de projectiles en virgule fixe, des tirs directionnels ou en éventail, la détection des impacts et des frôlements. Son rendu CGB par composition de l'arrière-plan évite la limite habituelle du nombre d'OBJ, mais le temps de calcul par image et le débit des transferts restent limités. Mesurez le temps de traitement plutôt que de viser uniquement un grand nombre de projectiles.

11. RPG, aventure, stratégie et sauvegarde

rpg.h rassemble les déclarations pour les nombres aléatoires, les indicateurs, les quêtes, la compression, le texte, les menus, les scripts, les cartes, les sauvegardes et la recherche de chemin. Les implémentations sont réparties dans des fichiers comme rng.c, flags.c, rle.c et text.c. Utilisez le dictionnaire pour sélectionner les unités nécessaires.

Une valeur fixe de rng_seed produit une suite reproductible pour les tests. Vérifiez si chaque fonction d'intervalle inclut sa borne supérieure. flag_get et flag_set manipulent des ensembles de bits. save.c utilise un accès à la SRAM de type MBC5 ; faites correspondre la capacité RAM de l'en-tête ROM à la zone de sauvegarde du jeu.

Les services de plateau, de liste de coups autorisés et d'annulation de slg.h, ainsi que la recherche de chemin de slg_path.c, doivent rester distincts des règles et de l'évaluation propres au jeu. La largeur, la hauteur et les tableaux de travail doivent respecter les limites de la bibliothèque et les exigences de chaque argument.

12. Communication

link.c fournit les transferts série d'octets ; link_packet.c ajoute une couche de paquets facultative. Placez link_hwregs_gb.c en premier dans la compilation. Les modes par interrogation et par interruption nécessitent des appels différents ; en mode interruption, le jeu doit raccorder le vecteur 0x0058.

Les opérations logiques Link4_* et les opérations LinkDmg07_* du périphérique Nintendo DMG-07 sont deux systèmes distincts. Le DMG-07 utilise une horloge externe : appelez fréquemment LinkDmg07_Poll et une fois par image LinkDmg07_TickFrame. Une seule interrogation par image peut ne pas respecter les délais nécessaires. Avec les tâches pair/dmg07 de KOKURA, testez séparément la connexion, le démarrage, la déconnexion et la reconnexion.

13. Banques, ressources et débogage

BankPtr associe un numéro de banque à un pointeur. far_data_read lit en RAM des ressources situées dans une autre banque. Le module de ressources associe des identifiants à des descripteurs ; le jeu reste responsable de leur durée de validité, de leurs banques et de leurs tailles.

debug_trace_u8 et debug_trace_u16 consignent des valeurs en RAM ; debug_assert_fail y enregistre un code de diagnostic. Ce ne sont pas des appels printf vers une console PC. Examinez ces données grâce aux outils d'observation mémoire de l'émulateur. L'exemple gb_debug.c enregistre HP=42.

vram_get_queue_capacity() renvoie le nombre total d'emplacements de commande, soit 32 par défaut. vram_get_queue_free() renvoie le nombre d'emplacements libres et vram_get_queue_used() le nombre d'emplacements occupés. Une opération en file occupe un emplacement, quelle que soit la taille du transfert. Ces fonctions décrivent la file de transfert, pas l'espace inutilisé de la VRAM matérielle.

Exemples de programmes complets

Chaque programme, les en-têtes communs, le fichier ascii.c fourni et ses ressources converties sont inclus. Les noms commençant par m_ sont des fonctions écrites pour ces manuels. Lisez chaque commande de compilation avec son résultat attendu et son compte rendu de vérification. Lancez les commandes depuis le dossier parent des dépôts voisins.

Script de compilation par lot / Résultats et captures d'écran

Afficher le jeu de caractères fourni gb_font.c

Objectif : Présente les lettres, chiffres et signes de ponctuation de la police originale fournie, ainsi que leur affichage.

Fonctionnement : m_init prépare l’affichage et la police. m_text dessine chaque ligne ; m_put dessine le guillemet double avec le code de caractère 34.

Commandes et résultat attendu : Repérez les 26 lettres majuscules, les 26 minuscules, les 10 chiffres et les 30 signes de ponctuation. Vérifiez que chaque glyphe est lisible. Aucune saisie n’est nécessaire.

Afficher le jeu de caractères fourni : Repérez les 26 lettres majuscules, les 26 minuscules, les 10 chiffres et les 30 signes de ponctuation. Vérifiez que chaque glyphe est lisible. Aucune saisie n’est nécessaire.
Exemple d’affichage : Repérez les 26 lettres majuscules, les 26 minuscules, les 10 chiffres et les 30 signes de ponctuation. Vérifiez que chaque glyphe est lisible. Aucune saisie n’est nécessaire.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe  kitaq-docs/samples/gb_font.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_font.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Display the letters, digits and punctuation from the supplied ascii.c font.
// Expected: Uppercase, lowercase, numbers and all 30 supplied punctuation glyphs
#include "gb_common.h"


// Lay out every supplied character category, yielding between rows. The final
// m_put uses character code 34 to display the double quote separately.
void main() {
    m_init();
    m_text(2,3,"FONT");
    m_text(2,5,"ABCDEFGHIJKLMNOP"); m_wait();
    m_text(2,6,"QRSTUVWXYZ"); m_wait();
    m_text(2,8,"0123456789"); m_wait();
    m_text(2,10,"abcdefghijklmnop"); m_wait();
    m_text(2,11,"qrstuvwxyz"); m_wait();
    m_text(2,13,"!#$%&'()*+,-./"); m_wait();
    m_text(2,14,":;<=>?@[]^_`{}~"); m_wait();
    m_put(16,13,34); m_wait();
    while (1) { m_wait();  }
}
Votre premier affichage de texte gb_hello.c

Objectif : Présente les étapes de base pour démarrer une ROM et dessiner du texte et un nombre sur le fond.

Fonctionnement : Après m_init, m_text dessine le message d’accueil et m_number formate 42. La boucle finale attend les images en conservant l’affichage.

Commandes et résultat attendu : L’écran affiche HELLO WORLD et 042. Le zéro initial provient du format décimal sur trois chiffres.

Votre premier affichage de texte : L’écran affiche HELLO WORLD et 042. Le zéro initial provient du format décimal sur trois chiffres.
Exemple d’affichage : L’écran affiche HELLO WORLD et 042. Le zéro initial provient du format décimal sur trois chiffres.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe  kitaq-docs/samples/gb_hello.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_hello.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Display a first message on screen.
// Expected: HELLO WORLD and 042
#include "gb_common.h"


// Initialize the display/font, write HELLO WORLD and a three-digit 042,
// then wait for frames so the result remains visible.
void main() {
    m_init();
    m_text(2,3,"HELLO");
    m_text(2,5,"HELLO WORLD");
    m_number(42);
    while (1) { m_wait();  }
}
Calculer avec un intermédiaire plus large gb_arithmetic.c

Objectif : Montre comment conserver un résultat intermédiaire qui dépasse huit bits.

Fonctionnement : (u16)200 + 100 donne 300. Le programme divise ce résultat par 10, puis le convertit en u8 pour l’afficher. Notez que la conversion vers le type plus large précède l’addition.

Commandes et résultat attendu : 030 représente le résultat calculé, 30.

Calculer avec un intermédiaire plus large : 030 représente le résultat calculé, 30.
Exemple d’affichage : 030 représente le résultat calculé, 30.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe  kitaq-docs/samples/gb_arithmetic.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_arithmetic.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Variables, arithmetic and type conversion.
// Expected: 030
#include "gb_common.h"


// Widen before adding 200 + 100, divide the 16-bit sum, and display 30.
// The cast demonstrates avoiding an 8-bit intermediate result.
void main() {
    m_init();
    m_text(2,3,"ARITHMETIC");
    u16 sum;
    sum = (u16)200 + 100;
    m_number((u8)(sum / 10));
    while (1) { m_wait();  }
}
Branchements et boucles gb_control.c

Objectif : Essaie for, continue, while, do/while et switch dans un petit calcul.

Fonctionnement : Additionner 0 à 7 en sautant 3 donne 25. La boucle while avance jusqu’à 30, do/while jusqu’à 32, puis switch choisit case 32 pour affecter 42.

Commandes et résultat attendu : 042 est le résultat final de ces boucles et branchements.

Branches et boucles : 042 est le résultat final de ces boucles et branches.
Exemple d’affichage : 042 est le résultat final de ces boucles et branchements.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe  kitaq-docs/samples/gb_control.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_control.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Conditional branches and loops.
// Expected: 042
#include "gb_common.h"


// Exercise loop control and a final branch, then display the selected value 42.
void main() {
    m_init();
    m_text(2,3,"CONTROL");
    u8 i; u8 sum; sum=0;
    for (i=0;i<8;i++) { if (i==3) continue; sum=(u8)(sum+i); }
    while (sum<30) { sum++; }
    do { sum++; } while (sum<32);
    switch (sum) { case 32: sum=42; break; default: sum=0; break; }
    m_number(sum);
    while (1) { m_wait();  }
}
Fonctions, tableaux, structures et pointeurs gb_aggregate.c

Objectif : Montre comment regrouper des valeurs et y accéder par des fonctions et des pointeurs.

Fonctionnement : Le programme copie un Point contenant (10,20), puis écrit de 1 à 4 dans un tableau via un pointeur. Il additionne le résultat de fonction 30, les valeurs du tableau 1, 2 et 4 et la constante 5.

Commandes et résultat attendu : La somme est affichée sous la forme 042. Suivez la copie de structure, les écritures dans ptr[i] et la valeur renvoyée par la fonction.

Fonctions, tableaux, structures et pointeurs : La somme est affichée sous la forme 042. Suivez la copie de structure, les écritures dans ptr[i] et la valeur renvoyée par la fonction.
Exemple d’affichage : La somme est affichée sous la forme 042. Suivez la copie de structure, les écritures dans ptr[i] et la valeur renvoyée par la fonction.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe  kitaq-docs/samples/gb_aggregate.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_aggregate.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Functions, arrays, structures and pointers.
// Expected: 042
#include "gb_common.h"

typedef struct { u8 x; u8 y; } Point;
// Add two byte values and explicitly narrow the returned result to u8.
u8 add(u8 a,u8 b) { return (u8)(a+b); }
// Copy a structure, fill an array through a pointer, and combine selected values
// through add() to produce 42. Keep the final screen visible in the idle loop.
void main() {
    m_init();
    m_text(2,3,"AGGREGATE");
    Point a; Point b; u8 i; u8 data[4]; u8* ptr;
    a.x=10; a.y=20; b=a; ptr=data;
    for(i=0;i<4;i++) ptr[i]=(u8)(i+1);
    m_number((u8)(add(b.x,b.y)+ptr[0]+ptr[1]+ptr[3]+5));
    while (1) { m_wait();  }
}
Drapeaux binaires et copie de tampon gb_bits_memory.c

Objectif : Regroupe des drapeaux dans un octet et copie un tampon dans une zone distincte.

Fonctionnement : __memset efface quatre octets. Le programme active le bit 3, inverse le bit 1, puis copie les quatre octets avec __memcpy.

Commandes et résultat attendu : le premier octet de destination est affiché sous la forme 010 ; le bit 3 apporte 8 et le bit 1 apporte 2.

Drapeaux binaires et copie de tampon : le premier octet de destination est affiché sous la forme 010 ; le bit 3 apporte 8 et le bit 1 apporte 2.
Exemple d’affichage : le premier octet de destination est affiché sous la forme 010 ; le bit 3 apporte 8 et le bit 1 apporte 2.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe  kitaq-docs/samples/gb_bits_memory.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_bits_memory.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Bit operations and memory copying.
// Expected: 010
#include "gb_common.h"
void __memset(void* dst,u8 value,u16 len);
void __memcpy(void* dst,const void* src,u16 len);
void __bit_set(u8* base,u16 bit);
void __bit_toggle(u8* base,u16 bit);

// Clear the source bytes, set bits 3 and 1, copy the buffer, and display 8 + 2 = 10.
void main() {
    m_init();
    m_text(2,3,"BITS MEMORY");
    u8 data[4]; u8 copy[4];
    __memset(data,0,4); __bit_set(data,3); __bit_toggle(data,1);
    __memcpy(copy,data,4); m_number(copy[0]);
    while (1) { m_wait();  }
}
Compter les nouveaux appuis sur un bouton gb_input.c

Objectif : Distingue un nouvel appui sur un bouton d’un bouton maintenu enfoncé.

Fonctionnement : Chaque image appelle input_update. Le compteur n’avance que si input_pressed(BTN_A) est vrai.

Commandes et résultat attendu : le compteur commence à 000. Appuyez sur A pour obtenir 001 ; maintenir le bouton n’ajoute rien. Relâchez-le puis appuyez de nouveau pour obtenir 002. Le compteur sur un octet revient de 255 à 000.

Compter les nouveaux appuis sur un bouton : le compteur commence à 000. Appuyez sur A pour obtenir 001 ; maintenir le bouton n’ajoute rien. Relâchez-le puis appuyez de nouveau pour obtenir 002. Le compteur sur un octet revient de 255 à 000.
Exemple d’affichage : le compteur commence à 000. Appuyez sur A pour obtenir 001 ; maintenir le bouton n’ajoute rien. Relâchez-le puis appuyez de nouveau pour obtenir 002. Le compteur sur un octet revient de 255 à 000.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/input.c kitaq-docs/samples/gb_input.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_input.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Distinguish a new button press from a held button.
// Expected: 000 initially; A increments once per press
#include "gb_common.h"
#include "input.h"
u8 manual_count;
// Sample buttons once per frame and increment only on a new A press.
// Holding A does not repeatedly increment; the byte-sized counter wraps after 255.
void main() {
    m_init();
    m_text(2,3,"INPUT");
    input_init();
    m_number(0);
    while (1) { m_wait(); input_update(); if(input_pressed(BTN_A)) { manual_count++; m_number(manual_count); } }
}
Multiplier des valeurs à virgule fixe Q8.8 gb_fixed.c

Objectif : Présente la conversion d’entier en Q8.8, la multiplication et le retour à un entier.

Fonctionnement : fix_from_int convertit 3 et 4 en Q8.8. fix_mul les multiplie, puis fix_to_int reconvertit le produit en entier.

Commandes et résultat attendu : 012 signifie 3 × 4 = 12. C’est l’entier converti, pas la valeur interne multipliée par 256.

Multiplier des valeurs à virgule fixe Q8.8 : 012 signifie 3 × 4 = 12. C’est l’entier converti, pas la valeur interne multipliée par 256.
Exemple d’affichage : 012 signifie 3 × 4 = 12. C’est l’entier converti, pas la valeur interne multipliée par 256.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/fixed.c kitaq-docs/samples/gb_fixed.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_fixed.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Calculate with signed Q8.8 fixed-point values.
// Expected: 012
#include "gb_common.h"
#include "fixed.h"

// Convert 3 and 4 to Q8.8, multiply them, convert the result back to an
// integer, and display 12.
void main() {
    m_init();
    m_text(2,3,"FIXED");
    fix8 a; fix8 b; a=fix_from_int(3); b=fix_from_int(4);
    m_number((u8)fix_to_int(fix_mul(a,b)));
    while (1) { m_wait();  }
}
Allouer dans un pool fixe d’objets gb_entity.c

Objectif : Crée un objet dans un ensemble fixe d’emplacements, sans allocation dynamique.

Fonctionnement : entity_init réinitialise le pool. entity_create crée un objet de type 1 en (20,30) ; le programme vérifie l’ID d’échec 0xFF avant de fixer vx à 2.

Commandes et résultat attendu : 001 est le nombre d’objets actifs, pas un ID ni une coordonnée. Cet exemple ne met pas à jour et ne dessine pas l’objet ; aucun personnage ne se déplace donc à l’écran.

Allouer dans un pool fixe d’objets : 001 est le nombre d’objets actifs, pas un ID ni une coordonnée. Cet exemple ne met pas à jour et ne dessine pas l’objet ; aucun personnage ne se déplace donc à l’écran.
Exemple d’affichage : 001 est le nombre d’objets actifs, pas un ID ni une coordonnée. Cet exemple ne met pas à jour et ne dessine pas l’objet ; aucun personnage ne se déplace donc à l’écran.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/entity.c kitaq-docs/samples/gb_entity.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_entity.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Allocate an entity from a fixed-capacity object pool.
// Expected: 001
#include "gb_common.h"
#include "entity.h"

// Create one entity and check the 0xFF allocation-failure sentinel before
// accessing its velocity. Display the pool occupancy, not the entity ID.
void main() {
    m_init();
    m_text(2,3,"ENTITY");
    u8 id; entity_init(); id=entity_create(1,20,30);
    if(id!=0xFF) entity_get(id)->vx=2; m_number(entity_count_active());
    while (1) { m_wait();  }
}
Enregistrer une valeur de diagnostic en RAM gb_debug.c

Objectif : Conserve une valeur de jeu nommée dans un tampon de diagnostic, indépendamment de l’affichage.

Fonctionnement : Le programme initialise le débogage, fixe l’étiquette d’image à 1 et enregistre la valeur 42 sous le nom HP.

Commandes et résultat attendu : 001 est le nombre d’entrées de trace. HP=42 est stocké dans le tampon de diagnostic ; l’écran seul ne montre ni ne vérifie ce contenu.

Enregistrer une valeur de diagnostic en RAM : 001 est le nombre d’entrées de trace. HP=42 est stocké dans le tampon de diagnostic ; l’écran seul ne montre ni ne vérifie ce contenu.
Exemple d’affichage : 001 est le nombre d’entrées de trace. HP=42 est stocké dans le tampon de diagnostic ; l’écran seul ne montre ni ne vérifie ce contenu.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/debug.c kitaq-docs/samples/gb_debug.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_debug.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Record diagnostic values in the debug trace.
// Expected: 001; trace log contains HP=42
#include "gb_common.h"
#include "debug.h"

// Record HP = 42 with frame tag 1 and display the number of trace entries.
// The trace buffer contains the value; the screen displays the count, not HP.
void main() {
    m_init();
    m_text(2,3,"DEBUG");
    debug_init(); debug_set_frame(1); debug_trace_u8("HP",42);
    m_number(debug_get_trace_count());
    while (1) { m_wait();  }
}
Stocker un historique de positions gb_chain.c

Objectif : Montre comment stocker un historique de positions dans un tampon circulaire.

Fonctionnement : chain_init associe un tableau pouvant contenir quatre points. chain_push_head enregistre ensuite (20,30).

Commandes et résultat attendu : 042 est un repère fixe de fin, pas une coordonnée ni un compteur. Examinez trail et points pour vérifier l’historique stocké. Ce programme ne dessine pas de corps suiveur.

Stocker un historique de positions : 042 est un repère fixe de fin, pas une coordonnée ni un compteur. Examinez trail et points pour vérifier l’historique stocké. Ce programme ne dessine pas de corps suiveur.
Exemple d’affichage : 042 est un repère fixe de fin, pas une coordonnée ni un compteur. Examinez trail et points pour vérifier l’historique stocké. Ce programme ne dessine pas de corps suiveur.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/chain.c kitaq-docs/samples/gb_chain.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_chain.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Store a position history in a ring buffer.
// Expected: 042; history contains (20,30)
#include "gb_common.h"
#include "chain.h"
Chain trail; ChainPoint points[4];
// Attach four history slots and record one point. The displayed 42 is a fixed
// completion marker; inspect the chain to verify the stored (20,30) point.
void main() {
    m_init();
    m_text(2,3,"CHAIN");
    chain_init(&trail,points,4); chain_push_head(&trail,20,30);
    m_number(42);
    while (1) { m_wait();  }
}
Lire le compteur d’images de la bibliothèque gb_system.c

Objectif : Montre l’effet des attentes comptées en images sur le compteur d’images de la bibliothèque.

Fonctionnement : Après system_init, le programme appelle deux fois system_wait_vblank et affiche system_get_frame8.

Commandes et résultat attendu : Le résultat est 002. La boucle d’attente utilise la fonction utilitaire m_wait du manuel ; la valeur affichée ne continue donc pas à augmenter.

Lire le compteur d’images de la bibliothèque : Le résultat est 002. La boucle d’attente utilise la fonction utilitaire m_wait du manuel ; la valeur affichée ne continue donc pas à augmenter.
Exemple d’affichage : Le résultat est 002. La boucle d’attente utilise la fonction utilitaire m_wait du manuel ; la valeur affichée ne continue donc pas à augmenter.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/system.c kitaq-docs/samples/gb_system.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_system.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Count completed frame waits.
// Expected: 002
#include "gb_common.h"
#include "system.h"

// Reset the library frame count, perform two counted waits, and display 2.
// Subsequent m_wait calls leave that library counter unchanged.
void main() {
    m_init();
    m_text(2,3,"SYSTEM");
    system_init(); system_wait_vblank(); system_wait_vblank();
    m_number(system_get_frame8());
    while (1) { m_wait();  }
}
Sélectionner l’ID de la scène courante gb_scene.c

Objectif : Montre comment sélectionner un ID pour distinguer des scènes, comme le titre et la partie en cours.

Fonctionnement : Le programme enregistre deux entrées SceneDef initialisées à zéro et sélectionne l’ID 1 avec scene_change.

Commandes et résultat attendu : 001 est l’ID courant renvoyé par scene_get_current. Cet exemple n’enregistre ni callbacks de scène ni dessin de transition.

Sélectionner l’ID de la scène courante : 001 est l’ID courant renvoyé par scene_get_current. Cet exemple n’enregistre ni callbacks de scène ni dessin de transition.
Exemple d’affichage : 001 est l’ID courant renvoyé par scene_get_current. Cet exemple n’enregistre ni callbacks de scène ni dessin de transition.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/scene.c kitaq-docs/samples/gb_scene.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_scene.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Switch the current scene ID.
// Expected: 001; no callbacks registered
#include "gb_common.h"
#include "scene.h"
SceneDef manual_scenes[2];
// Register two zero-initialized scene entries, select ID 1 and display it.
// No callbacks are registered in this example.
void main() {
    m_init();
    m_text(2,3,"SCENE");
    scene_init(manual_scenes,2); scene_change(1);
    m_number(scene_get_current());
    while (1) { m_wait();  }
}
Convertir les coordonnées du monde en coordonnées d’écran gb_camera.c

Objectif : Soustrait la position de la caméra pour obtenir la position à l’écran d’un point du monde.

Fonctionnement : Camera_Set reçoit la valeur Q8.8 2560, soit X=10 pixels. Camera_WorldToScreenX convertit ensuite la coordonnée du monde X=52.

Commandes et résultat attendu : 052 moins 010 donne le 042 affiché. C’est un calcul de coordonnées ; le fond ne défile pas.

Convertir les coordonnées du monde en coordonnées d’écran : 052 moins 010 donne la valeur affichée 042. Il s’agit d’un calcul de coordonnées ; le fond ne défile pas.
Exemple d’affichage : 052 moins 010 donne le 042 affiché. C’est un calcul de coordonnées ; le fond ne défile pas.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/scroll.c kitaqgb/lib/camera.c kitaq-docs/samples/gb_camera.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_camera.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Convert world coordinates to screen coordinates.
// Expected: 042: world x=52 minus camera x=10
#include "gb_common.h"
#include "camera.h"
Camera8_8 cam;
// Set the camera X coordinate to 10 pixels in Q8.8 (10 * 256), then subtract
// it from world X = 52 to display screen X = 42.
void main() {
    m_init();
    m_text(2,3,"CAMERA");
    Camera_Init(&cam); Camera_Set(&cam,2560,0);
    m_number((u8)Camera_WorldToScreenX(&cam,52));
    while (1) { m_wait();  }
}
Décompresser des données RLE en RAM gb_rle.c

Objectif : Essaie une représentation compacte des octets répétés sous forme de paires nombre/valeur.

Fonctionnement : Les octets compressés {3,42,0} représentent trois copies de 42, suivies d’un terminateur de compte nul. rle_decode écrit dans une destination de trois octets.

Commandes et résultat attendu : le dernier octet, out[2], est affiché sous la forme 042. Les trois octets décompressés doivent tous contenir 42.

Décompresser des données RLE en RAM : le dernier octet, out[2], est affiché sous la forme 042. Les trois octets décompressés doivent tous contenir 42.
Exemple d’affichage : le dernier octet, out[2], est affiché sous la forme 042. Les trois octets décompressés doivent tous contenir 42.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/rle.c kitaq-docs/samples/gb_rle.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_rle.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Decode run-length encoded data.
// Expected: 042; three bytes each equal to 42
#include "gb_common.h"
#include "rpg.h"
__prg_rom u8 packed[] = {3,42,0};
// Decode count/value pair (3,42), terminated by a zero count, into a
// three-byte buffer and display the final decoded byte.
void main() {
    m_init();
    m_text(2,3,"RLE");
    u8 out[3]; rle_decode(out,packed); m_number(out[2]);
    while (1) { m_wait();  }
}
Lire et écrire une case du plateau gb_board.c

Objectif : Montre comment les coordonnées d’une grille correspondent au stockage d’un jeu de plateau.

Fonctionnement : Un tableau de 16 octets stocke un plateau de 4×4. Le programme l’efface, écrit 42 dans la case (2,1), puis relit cette case.

Commandes et résultat attendu : 042 est la valeur relue. Le programme ne dessine pas le plateau de 4×4 lui-même.

Lire et écrire une case du plateau : 042 est la valeur relue. Le programme ne dessine pas le plateau de 4×4 lui-même.
Exemple d’affichage : 042 est la valeur relue. Le programme ne dessine pas le plateau de 4×4 lui-même.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/slg_board.c kitaq-docs/samples/gb_board.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_board.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Read and write cells in a game board.
// Expected: 042
#include "gb_common.h"
#include "slg.h"
SLGBoard board; u8 cells[16];
// Create a cleared 4-by-4 board in caller-owned storage, write 42 at (2,1),
// and display the value read back from the same cell.
void main() {
    m_init();
    m_text(2,3,"BOARD");
    slg_board_init(&board,4,4,cells); slg_board_clear(&board,0);
    slg_board_set(&board,2,1,42); m_number(slg_board_get(&board,2,1));
    while (1) { m_wait();  }
}
Faire avancer une boîte d’un pas de physique gb_physics.c

Objectif : Initialise un monde et un corps rectangulaire, puis met à jour la position à partir de la vitesse.

Fonctionnement : Le corps démarre en (40,40), avec une vitesse (2,0) et une gravité nulle. Le programme appelle kq2d_step une fois.

Commandes et résultat attendu : 042 est la coordonnée X obtenue, mesurée ici en pixels entiers. Aucune boîte ni animation continue n’est dessinée.

Faire avancer une boîte d’un pas de physique : 042 est la coordonnée X obtenue, mesurée ici en pixels entiers. Aucune boîte ni animation continue n’est dessinée.
Exemple d’affichage : 042 est la coordonnée X obtenue, mesurée ici en pixels entiers. Aucune boîte ni animation continue n’est dessinée.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/fixed.c kitaqgb/lib/physics2d.c kitaq-docs/samples/gb_physics.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_physics.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Advance a rectangular body through one physics step.
// Expected: 042: integer pixel coordinates
#include "gb_common.h"
#include "physics2d.h"
KQWorld2D world; KQBody2D boxes[1];
// Create one box at X = 40, set horizontal velocity 2 and zero gravity,
// then display its X coordinate after a single physics step.
void main() {
    m_init();
    m_text(2,3,"PHYSICS");
    kq2d_world_init(&world,boxes,1);
    kq2d_body_init(&boxes[0],40,40,4,4);
    kq2d_body_set_velocity(&boxes[0],2,0);
    world.gravity_x=0; world.gravity_y=0;
    kq2d_step(&world); m_number((u8)boxes[0].x);
    while (1) { m_wait();  }
}
Lire des données ROM avec un argument de banque gb_bank.c

Objectif : Présente les arguments nécessaires pour copier des données de la ROM vers la RAM.

Fonctionnement : far_data_read copie les deux octets 7 et 42 dans copied, avec l’argument de banque 0 et une longueur de 2.

Commandes et résultat attendu : Le deuxième octet de destination est affiché sous la forme 042. L’exemple lit la ROM fixe ; il n’illustre pas un transfert entre différentes banques commutables.

Lire des données ROM avec un argument de banque : Le deuxième octet de destination est affiché sous la forme 042. L’exemple lit la ROM fixe ; il n’illustre pas un transfert entre différentes banques commutables.
Exemple d’affichage : Le deuxième octet de destination est affiché sous la forme 042. L’exemple lit la ROM fixe ; il n’illustre pas un transfert entre différentes banques commutables.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/bank.c kitaq-docs/samples/gb_bank.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_bank.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Read data using an explicit ROM bank.
// Expected: 042; explicit bank argument 0
#include "gb_common.h"
#include "bank.h"
__prg_rom u8 values[] = {7,42}; u8 copied[2];
// Copy two ROM bytes using bank argument zero and display the second byte.
// This introduces the API; it does not test switching between distinct payload banks.
void main() {
    m_init();
    m_text(2,3,"BANK");
    far_data_read(0,values,copied,2); m_number(copied[1]);
    while (1) { m_wait();  }
}
Charger des données par ID de ressource gb_asset.c

Objectif : Enregistre l’emplacement et la longueur d’une ressource, puis récupère ses octets par ID.

Fonctionnement : La ressource 0 est de type RAW, dans la banque 0, avec un pointeur vers {7,42} et une longueur de 2. asset_load_raw la copie dans un tampon RAM de deux octets.

Commandes et résultat attendu : Le deuxième octet est affiché sous la forme 042. Cet exemple illustre la recherche et la copie d’une ressource, pas le rendu d’une image.

Charger des données par ID de ressource : Le deuxième octet est affiché sous la forme 042. Cet exemple illustre la recherche et la copie d’une ressource, pas le rendu d’une image.
Exemple d’affichage : Le deuxième octet est affiché sous la forme 042. Cet exemple illustre la recherche et la copie d’une ressource, pas le rendu d’une image.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/asset.c kitaq-docs/samples/gb_asset.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_asset.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Load asset bytes into RAM by asset ID.
// Expected: 042
#include "gb_common.h"
#include "asset.h"
AssetDesc table[1]; __prg_rom u8 values[] = {7,42}; u8 copied[2];
// Register a two-byte raw asset, copy it into RAM and display its second byte.
// This example uses bank zero and a destination sized for the complete payload.
void main() {
    m_init();
    m_text(2,3,"ASSET");
    table[0].type=ASSET_TYPE_RAW; table[0].bank=0;
    table[0].ptr=values; table[0].len=2;
    asset_set_table(0,table,1); asset_load_raw(0,copied,2);
    m_number(copied[1]);
    while (1) { m_wait();  }
}
Allouer un projectile gb_danmaku.c

Objectif : Initialise le pool de projectiles et examine son occupation après une création.

Fonctionnement : Après danmaku_reset, le programme appelle danmaku_spawn(40,40,16,0) et affiche dm_count.

Commandes et résultat attendu : 001 est le nombre de projectiles alloués. Il n’y a ici ni boucle de mise à jour des projectiles ni composition du fond ; aucun projectile mobile n’est dessiné.

Allouer un projectile : 001 est le nombre de projectiles alloués. Il n’y a ici ni boucle de mise à jour des projectiles ni composition du fond ; aucun projectile mobile n’est dessiné.
Exemple d’affichage : 001 est le nombre de projectiles alloués. Il n’y a ici ni boucle de mise à jour des projectiles ni composition du fond ; aucun projectile mobile n’est dessiné.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/danmaku.c kitaq-docs/samples/gb_danmaku.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_danmaku.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Allocate a bullet and inspect the pool count.
// Expected: 001; numeric pool example, no bullet BG compositor
#include "gb_common.h"
#include "danmaku.h"

// Reset the bullet pool, spawn one bullet and display the active count.
// This numeric example does not install the background bullet compositor.
void main() {
    m_init();
    m_text(2,3,"DANMAKU");
    danmaku_reset(); danmaku_spawn(40,40,16,0);
    m_number(dm_count);
    while (1) { m_wait();  }
}
Définir une palette de fond CGB gb_cgb_palette.c

Objectif : Choisit les couleurs du fond et du texte à partir des composantes RGB de la Game Boy Color.

Fonctionnement : Le programme désactive le LCD pendant le VBlank, règle la couleur 0 de la palette 0 sur le blanc (31,31,31) et la couleur 3 sur le violet (12,0,22), puis réactive l’affichage.

Commandes et résultat attendu : Exécutez en mode CGB pour voir le texte violet et 042 sur fond blanc. L’affichage monochrome DMG ne peut pas montrer ces couleurs.

Définir une palette de fond CGB : Exécutez en mode CGB pour voir le texte violet et 042 sur fond blanc. L’affichage monochrome DMG ne peut pas montrer ces couleurs.
Exemple d’affichage : Exécutez en mode CGB pour voir le texte violet et 042 sur fond blanc. L’affichage monochrome DMG ne peut pas montrer ces couleurs.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/cgb_palette.c kitaq-docs/samples/gb_cgb_palette.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_cgb_palette.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb
c
// Set Game Boy Color palette entries.
// Expected: 042 in purple on white; CGB mode
#include "gb_common.h"
#include "cgb_palette.h"

// Set palette-zero background colors to white and purple, then display 42.
// Run the ROM in CGB mode to observe the color result.
void main() {
    m_init();
    m_text(2,3,"CGB PALETTE");
    // Disable the LCD during VBlank so both palette bytes remain accessible.
    m_wait(); M_LCDC = 0;
    cgb_bg_rgb(0,0,31,31,31); cgb_bg_rgb(0,3,12,0,22);
    M_LCDC = 0x91;
    m_number(42);
    while (1) { m_wait();  }
}
Faire défiler le fond horizontalement gb_scroll.c

Objectif : Déplace le point de vue sans redessiner le contenu du fond.

Fonctionnement : Chaque image incrémente phase et le transmet à Scroll_SetBg. La position sur huit bits revient à zéro après 255.

Commandes et résultat attendu : Le mot SCROLL se déplace vers la gauche. Observez sa position au fil du temps ; une seule capture ne peut pas montrer le mouvement.

Faire défiler le fond horizontalement : Le mot SCROLL se déplace vers la gauche. Observez sa position au fil du temps ; une seule capture ne peut pas montrer le mouvement.
Exemple d’affichage : Le mot SCROLL se déplace vers la gauche. Observez sa position au fil du temps ; une seule capture ne peut pas montrer le mouvement.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/scroll.c kitaq-docs/samples/gb_scroll.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_scroll.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Scroll the background horizontally.
// Expected: title moves left as SCX increases
#include "gb_common.h"
#include "scroll.h"
u8 phase;
// Advance an 8-bit horizontal scroll position once per frame, wrapping naturally
// after 255. Background motion demonstrates the changing scroll register.
void main() {
    m_init();
    m_text(2,3,"SCROLL");
    Scroll_SetBg(0,0);
    while (1) { m_wait(); phase++; Scroll_SetBg(phase,0); }
}
Mettre une mise à jour de tuile en file gb_vram_queue.c

Objectif : Sépare une demande de dessin du transfert VRAM qui l’applique.

Fonctionnement : vram_queue_bg_tile met en file la tuile 52 à la coordonnée (3,8), puis vram_flush la transfère. Dans la police fournie, la tuile 52 correspond au chiffre 4.

Commandes et résultat attendu : Repérez un seul 4 à la coordonnée de tuile du fond (3,8). Il s’agit d’une mise à jour de tuile, pas d’un compteur numérique.

Mettre une mise à jour de tuile en file : Repérez un seul 4 à la coordonnée de tuile du fond (3,8). Il s’agit d’une mise à jour de tuile, pas d’un compteur numérique.
Exemple d’affichage : Repérez un seul 4 à la coordonnée de tuile du fond (3,8). Il s’agit d’une mise à jour de tuile, pas d’un compteur numérique.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/vram.c kitaq-docs/samples/gb_vram_queue.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_vram_queue.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Queue a VRAM update and flush it at VBlank.
// Expected: 4 at (3,8)
#include "gb_common.h"
#include "vram.h"

// Queue font tile 52 (the digit 4) at tile coordinate (3,8), then wait for
// VBlank and execute the queued transfer.
void main() {
    m_init();
    m_text(2,3,"VRAM QUEUE");
    vram_init();
    vram_queue_bg_tile(3,8,52); vram_flush();
    while (1) { m_wait();  }
}
Afficher un sprite par DMA OAM gb_sprite.c

Objectif : Alloue et affiche un sprite indépendamment du fond.

Fonctionnement : Le pool initialisé fournit l’emplacement 0. Le programme choisit la tuile 65, fixe la position (70,80), active l’affichage OBJ et transfère l’OAM miroir à chaque image.

Commandes et résultat attendu : Une lettre A immobile apparaît à la position de sprite indiquée. Dans un jeu, vérifiez l’échec éventuel de l’allocation avant d’utiliser l’ID renvoyé.

Afficher un sprite par DMA OAM : une lettre A immobile apparaît à la position indiquée pour le sprite. Dans un jeu, vérifiez que l’allocation a réussi avant d’utiliser l’ID renvoyé.
Exemple d’affichage : Une lettre A immobile apparaît à la position de sprite indiquée. Dans un jeu, vérifiez l’échec éventuel de l’allocation avant d’utiliser l’ID renvoyé.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/sprite.c kitaq-docs/samples/gb_sprite.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_sprite.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Display a sprite through the OAM DMA path.
// Expected: letter A at sprite position
#include "gb_common.h"
#include "sprite.h"

// Allocate the first sprite, choose font tile 65 (A), set its position and
// enable sprite display. Flush shadow OAM after each frame wait.
void main() {
    m_init();
    m_text(2,3,"SPRITE");
    // The freshly reset pool guarantees slot zero for this first allocation.
    // In a running game, check the allocation-failure sentinel before using the returned ID.
    sprite_init(); sprite_set_tile(sprite_alloc(),65);
    sprite_set_pos(0,70,80); M_LCDC=(u8)(M_LCDC|2);
    while (1) { m_wait(); sprite_flush_oam_now(); }
}
Générer une valeur aléatoire reproductible gb_rng.c

Objectif : Utilise une graine pour reproduire une séquence pseudo-aléatoire.

Fonctionnement : rng_seed(1234) initialise le générateur, puis rng_range(10) est appelé une fois. La borne supérieure 10 est exclue.

Commandes et résultat attendu : L’écran affiche une valeur entre 000 et 009. Relancer le même programme avec la même graine reproduit cette valeur ; elle ne change pas à chaque image.

Générer une valeur aléatoire reproductible : L’écran affiche une valeur entre 000 et 009. Relancer le même programme avec la même graine reproduit cette valeur ; elle ne change pas à chaque image.
Exemple d’affichage : L’écran affiche une valeur entre 000 et 009. Relancer le même programme avec la même graine reproduit cette valeur ; elle ne change pas à chaque image.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/rng.c kitaq-docs/samples/gb_rng.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_rng.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Generate a repeatable pseudorandom value from a seed.
// Expected: value 000 through 009; same seed repeats
#include "gb_common.h"
#include "rpg.h"

// Seed the generator with 1234 and display one value in [0,10).
// Restarting with the same seed reproduces the sequence.
void main() {
    m_init();
    m_text(2,3,"RNG");
    rng_seed(1234); m_number(rng_range(10));
    while (1) { m_wait();  }
}
Stocker un drapeau d’état du jeu gb_flags.c

Objectif : Représente un état booléen, comme l’achèvement d’un événement, par un numéro de drapeau.

Fonctionnement : Le programme efface le drapeau 12, le définit, puis le relit avec flag_get.

Commandes et résultat attendu : 001 signifie que le drapeau 12 est vrai. Cet exemple utilise des drapeaux en RAM et ne les conserve pas après extinction.

Stocker un drapeau d’état du jeu : 001 signifie que le drapeau 12 est vrai. Cet exemple utilise des drapeaux en RAM et ne les conserve pas après extinction.
Exemple d’affichage : 001 signifie que le drapeau 12 est vrai. Cet exemple utilise des drapeaux en RAM et ne les conserve pas après extinction.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/flags.c kitaq-docs/samples/gb_flags.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_flags.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Read and write RAM-backed game-state flags.
// Expected: 001
#include "gb_common.h"
#include "rpg.h"

// Clear and set flag 12, then display its Boolean value. This does not write
// a save file or demonstrate persistence across power cycles.
void main() {
    m_init();
    m_text(2,3,"FLAGS");
    flag_clear(12); flag_set(12); m_number(flag_get(12));
    while (1) { m_wait();  }
}
Faire avancer un cercle d’un pas de physique gb_circle.c

Objectif : Configure un corps circulaire et met à jour sa position à partir de sa vitesse.

Fonctionnement : Le cercle actif a un rayon de 4, une position (40,40) et une vitesse (2,0). La gravité est nulle et linear_damping_q8 vaut 255 ; kq2dc_step s’exécute une fois.

Commandes et résultat attendu : 042 est la coordonnée X entière obtenue. Cet exemple ne dessine ni contour de cercle ni animation de collision.

Faire avancer un cercle d’un pas de physique : 042 est la coordonnée X entière obtenue. Cet exemple ne dessine ni contour de cercle ni animation de collision.
Exemple d’affichage : 042 est la coordonnée X entière obtenue. Cet exemple ne dessine ni contour de cercle ni animation de collision.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/physics2d_circle.c kitaq-docs/samples/gb_circle.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_circle.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Advance a circular body through one physics step.
// Expected: 042 after one step; this example uses integer pixels
#include "gb_common.h"
#include "physics2d_circle.h"
KQCircleBody2D balls[1]; KQCircleWorld2D world;
// Activate one circle at X = 40 with horizontal velocity 2 and zero gravity.
// Advance one step and display its resulting integer-pixel X coordinate.
void main() {
    m_init();
    m_text(2,3,"CIRCLE");
    kq2dc_world_init(&world,balls,1);
    balls[0].active=1; balls[0].x=40; balls[0].y=40;
    balls[0].radius=4; balls[0].inv_mass_q8=256;
    balls[0].vx=2; balls[0].vy=0;
    world.gravity_x=0; world.gravity_y=0; world.linear_damping_q8=255;
    kq2dc_step(&world); m_number((u8)balls[0].x);
    while (1) { m_wait();  }
}
Traiter un effet sonore à chaque image gb_sound.c

Objectif : Démarre un flux d’effet sonore et le fait progresser par des mises à jour régulières à chaque image.

Fonctionnement : Après Audio_Init, Audio_PlaySFX lance tone sur le canal d’ID 1. La boucle principale appelle Audio_Update une fois par image.

Commandes et résultat attendu : Un bref effet sonore pulsé joue pendant que 042 reste affiché. Ce nombre est un repère fixe, pas le volume ni la position de lecture. Évaluez le son à l’écoute ou à partir d’un enregistrement.

Traiter un effet sonore à chaque image : Un bref effet sonore pulsé joue pendant que 042 reste affiché. Ce nombre est un repère fixe, pas le volume ni la position de lecture. Évaluez le son à l’écoute ou à partir d’un enregistrement.
Exemple d’affichage : Un bref effet sonore pulsé joue pendant que 042 reste affiché. Ce nombre est un repère fixe, pas le volume ni la position de lecture. Évaluez le son à l’écoute ou à partir d’un enregistrement.

Télécharger le source / État de la vérification

powershell
.\kitaqgb\kitaqgb.exe kitaqgb/lib/audio_hwregs_gb.c kitaqgb/lib/audio.c kitaq-docs/samples/gb_sound.c -I kitaqgb/lib -I kitaq-docs/samples -o out/gb_sound.gb --profile=dev --rst-disable --stack-bank=fixed
c
// Play a Game Boy pulse-channel sound effect.
// Expected: 042 and a short pulse tone
#include "gb_common.h"
#include "audio.h"
__prg_rom u8 tone[] = { 24,0xF0,24,0xE0,24,0xC0,24,0xA0,24,0x80,24,0x60,0 };
// Start a pulse-channel effect and service Audio_Update once per frame
// so the effect stream advances while 42 remains on screen.
void main() {
    m_init();
    m_text(2,3,"SOUND");
    Audio_Init(); Audio_PlaySFX(tone,1); m_number(42);
    while (1) { m_wait(); Audio_Update(); }
}

Dictionnaire de l'API de bibliothèque

554 entrées. Ouvrez une entrée pour consulter sa syntaxe, ses arguments, les notes source et son exemple. Les fragments d'appel nécessitent une initialisation autour du code ; ce ne sont pas des ROM autonomes. Les exemples montrent comment transmettre des valeurs préparées à l'API, sans constituer une validation sur le périphérique.

zx0

Décode les ressources compatibles ZX0 en RAM ou VRAM. Préparez-les sur PC avec kitaqgb-zx0.exe, puis décodez seulement les données nécessaires à l’exécution. --format=auto compare les charges utiles brutes, RLE et ZX0 et choisit la plus petite ; à égalité, l’ordre de préférence est brut, RLE, puis ZX0. Limitez le conteneur complet à 65535 octets, en-tête de neuf octets compris, et divisez les ressources selon les banques CPU et la RAM disponibles.

Einar Saukas a conçu le format ZX0 et l’algorithme de compression original. Le compresseur et le décompresseur fournis ici sont des implémentations KITAQ indépendantes, sous copyright DAISUKE OBA et publiées sous licence MIT.

Exécutez ces commandes sur l’ordinateur hôte depuis la racine du dépôt. Compilez l’outil avec tools/zx0/build.ps1.

.\kitaqgb-zx0.exe tiles.bin tiles.zx0
.\kitaqgb-zx0.exe tiles.bin tiles.h --header=tiles
.\kitaqgb-zx0.exe map.bin map.kqa --format=auto
.\kitaqgb-zx0.exe tiles.zx0 restored.bin --decompress
zx0_decompress

Décode un flux ZX0 v2 dans une zone RAM bornée. Les correspondances référencent des octets déjà décodés ; la destination doit donc être lisible et inscriptible. Utilisez-le pour des cartes de tuiles ou tables de niveaux que le CPU traitera avant utilisation.

Syntaxe

c
u16 zx0_decompress(void* dst, u16 capacity, const void* src, u16 packed_size);

Paramètres

dst

Début de la RAM de destination accessible en écriture ; ne doit pas être null. Exprimez la capacité en octets, pas en éléments de tableau.

capacity

Nombre d’octets inscriptibles en destination. Un flux ZX0 ordinaire nécessite au moins un octet. Une ressource KQA1 brute vide peut réussir avec une capacité nulle.

src

Début des données compressées lisibles avec le mappage de banque courant. Ne doit pas être null.

packed_size

Nombre d’octets de l’entrée complète. Un flux ZX0 inclut son marqueur de fin et n’a pas d’octets supplémentaires après lui. Un conteneur KQA1 inclut son en-tête de neuf octets. Maximum : 65535 octets.

Valeur renvoyée

Renvoie le nombre d’octets décodés en cas de succès, zéro en cas d’erreur. Vérifiez toujours aussi zx0_error.

Conditions et limites

Incluez zx0.h et compilez lib/zx0.c. Ces routines partagent un espace temporaire et ne sont pas réentrantes depuis les interruptions. Entrée et sortie ne doivent ni se chevaucher, ni boucler dans l’espace d’adressage CPU, ni franchir les fenêtres de banques actuellement mappées. La bibliothèque ne change pas les banques de ressources.

Chaque appel met à jour zx0_error : 0 succès, 1 argument invalide, 2 entrée tronquée, 3 flux malformé, 4 espace de sortie insuffisant, 5 affichage actif. Un échec peut laisser une sortie partielle : ne l’utilisez pas. Si plusieurs conditions sont invalides, la première détectée détermine le code.

Accepte les flux ZX0 v2 en sens avant. ZX0 v1, les flux inverses et les dictionnaires externes sont hors de cette interface. Connaissez la taille décodée de la ressource produite sur l’hôte et fournissez assez de stockage.

Format ZX0 — Einar Saukas

Exemple d’utilisation

c
count=zx0_decompress(decoded_map,16,packed_map,packed_map_SIZE);
    if(count!=16||zx0_error!=ZX0_OK)failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.

zx0_decompress: DMG — La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.
DMG — La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.
zx0_decompress: CGB — La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.
CGB — La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\zx0_decode.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\zx0_decode.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/zx0.h:15

Notes de déclaration (texte source)
Return decoded bytes, or zero on error (possibly after partial writes).
Source and output must not overlap or cross their current CPU bank windows.
Capacity and packed_size are byte counts. No prefix/backward/v1 streams.

kitaqgb/lib/zx0.c:52

c
u16 zx0_decompress(void* dst,u16 capacity,const void* src,u16 packed_size) {
    u8 phase; u8 low; u8* out; u8* match;
    u16 count; u16 distance; u16 used; u16 upper;
    zx0_error=ZX0_OK;
    if(!kq_zx_arguments(dst,capacity,src,packed_size)) { zx0_error=ZX0_BAD_ARGUMENT; return 0; }
    kq_zx_input=(const u8*)src; kq_zx_left=packed_size;
    kq_zx_mask=0; kq_zx_borrowed=0;
    out=(u8*)dst; used=0; distance=1; phase=0;
    // Phase 0 is literal, 1 reuses the last distance, 2 carries a new distance.
    while(1) {
        if(phase==2) {
            upper=kq_zx_number(1);
            if(zx0_error) return 0;
            if(upper==256) {
                if(kq_zx_left!=0) { zx0_error=ZX0_BAD_STREAM; return 0; }
                return used;
            }
            if(upper>255) { zx0_error=ZX0_BAD_STREAM; return 0; }
            low=kq_zx_byte();
            distance=(u16)((upper<<7)-(low>>1));
            kq_zx_borrowed=1; kq_zx_borrow_value=(u8)(low&1);
            count=kq_zx_number(0);
            if(count==65535) { zx0_error=ZX0_BAD_STREAM; return 0; }
            count++;
        } else count=kq_zx_number(0);
        if(zx0_error) return 0;
        if(count>capacity-used) { zx0_error=ZX0_OUTPUT_FULL; return 0; }
        if(phase==0) {
            if(count>kq_zx_left) { zx0_error=ZX0_TRUNCATED; return 0; }
            kq_zx_left-=count; used+=count;
            while(count!=0) { *out++=*kq_zx_input++; count--; }
            phase=kq_zx_bit()?2:1;
        } else {
            if(distance>used) { zx0_error=ZX0_BAD_STREAM; return 0; }
            match=out-distance; used+=count;
            // Forward byte copying deliberately supports overlapping matches.
            while(count!=0) { *out++=*match++; count--; }
            phase=kq_zx_bit()?2:0;
        }
        if(zx0_error) return 0;
    }
}
asset_decompress

Lit le codec et les tailles dans l’en-tête KQA1 produit par --format=auto, puis copie les octets bruts ou décode RLE/ZX0 en RAM. L’appelant n’a pas besoin d’une branche distincte par codec.

Syntaxe

c
u16 asset_decompress(void* dst, u16 capacity, const void* src, u16 packed_size);

Paramètres

dst

Début de la RAM de destination accessible en écriture ; ne doit pas être null. Exprimez la capacité en octets, pas en éléments de tableau.

capacity

Nombre d’octets inscriptibles en destination. Un flux ZX0 ordinaire nécessite au moins un octet. Une ressource KQA1 brute vide peut réussir avec une capacité nulle.

src

Début des données compressées lisibles avec le mappage de banque courant. Ne doit pas être null.

packed_size

Nombre d’octets de l’entrée complète. Un flux ZX0 inclut son marqueur de fin et n’a pas d’octets supplémentaires après lui. Un conteneur KQA1 inclut son en-tête de neuf octets. Maximum : 65535 octets.

Valeur renvoyée

Renvoie le nombre d’octets décodés en cas de succès, zéro en cas d’erreur. Vérifiez toujours aussi zx0_error.

Conditions et limites

Incluez zx0.h et compilez lib/zx0.c. Ces routines partagent un espace temporaire et ne sont pas réentrantes depuis les interruptions. Entrée et sortie ne doivent ni se chevaucher, ni boucler dans l’espace d’adressage CPU, ni franchir les fenêtres de banques actuellement mappées. La bibliothèque ne change pas les banques de ressources.

Chaque appel met à jour zx0_error : 0 succès, 1 argument invalide, 2 entrée tronquée, 3 flux malformé, 4 espace de sortie insuffisant, 5 affichage actif. Un échec peut laisser une sortie partielle : ne l’utilisez pas. Si plusieurs conditions sont invalides, la première détectée détermine le code.

KQA1 est le conteneur de ressources KITAQ : signature de quatre octets, codec d’un octet (0 brut, 1 RLE, 2 ZX0), taille décodée u16, taille de charge utile u16, puis charge utile. Les champs u16 sont en petit-boutiste. RLE répète des paires compte/valeur avec comptes de 1 à 255 et un terminateur de compte zéro. Une ressource brute vide réussit avec valeur de retour zéro et erreur zéro.

Format ZX0 — Einar Saukas

Exemple d’utilisation

c
count=asset_decompress(decoded_auto,16,packed_auto,packed_auto_SIZE);
    if(count!=16||zx0_error!=ZX0_OK)failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.

asset_decompress: DMG — La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.
DMG — La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.
asset_decompress: CGB — La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.
CGB — La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\zx0_decode.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\zx0_decode.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/zx0.h:18

Notes de déclaration (texte source)
Decode a KQA1 raw/RLE/ZX0 asset produced with --format=auto.
Empty raw assets return zero with zx0_error==ZX0_OK.

kitaqgb/lib/zx0.c:95

c
u16 asset_decompress(void* dst,u16 capacity,const void* src,u16 packed_size) {
    const u8* in; u8* out; u16 raw; u16 packed; u16 used;
    u8 codec; u8 count; u8 value;
    zx0_error=ZX0_OK;
    if(packed_size<9||!kq_zx_arguments(dst,capacity,src,packed_size)) { zx0_error=ZX0_BAD_ARGUMENT; return 0; }
    in=(const u8*)src; out=(u8*)dst;
    if(in[0]!=75||in[1]!=81||in[2]!=65||in[3]!=49) { zx0_error=ZX0_BAD_STREAM; return 0; }
    codec=in[4]; raw=(u16)((u16)in[5]|((u16)in[6]<<8));
    packed=(u16)((u16)in[7]|((u16)in[8]<<8));
    if(packed!=packed_size-9||codec>2) { zx0_error=ZX0_BAD_STREAM; return 0; }
    if(raw>capacity) { zx0_error=ZX0_OUTPUT_FULL; return 0; }
    in+=9;
    if(codec==2) {
        used=zx0_decompress(dst,raw,in,packed);
        if(zx0_error==0&&used!=raw) zx0_error=ZX0_BAD_STREAM;
        return zx0_error?0:used;
    }
    if(codec==0) {
        if(raw!=packed) { zx0_error=ZX0_BAD_STREAM; return 0; }
        used=raw; while(raw!=0) { *out++=*in++; raw--; } return used;
    }
    used=0;
    while(packed!=0) {
        count=*in++; packed--;
        if(count==0) {
            if(packed!=0||used!=raw) { zx0_error=ZX0_BAD_STREAM; return 0; }
            return used;
        }
        if(packed==0) { zx0_error=ZX0_TRUNCATED; return 0; }
        value=*in++; packed--;
        if((u16)count>raw-used) { zx0_error=ZX0_OUTPUT_FULL; return 0; }
        used+=count; while(count!=0) { *out++=value; count--; }
    }
    zx0_error=ZX0_TRUNCATED; return 0;
}
zx0_decompress_vram

LCD arrêté, décode directement les pixels de tuiles ou données de carte ZX0 dans la banque VRAM sélectionnée. La VRAM fournit elle-même l’historique des correspondances ; aucun tampon RAM intermédiaire n’est nécessaire.

Syntaxe

c
u16 zx0_decompress_vram(u16 vram_addr, const void* src, u16 packed_size);

Paramètres

vram_addr

Adresse de début VRAM, 0x8000..0x9FFF. La sortie est bornée par la fin de VRAM à 0xA000. Sur CGB, sélectionnez VBK avant l’appel.

src

Début des données compressées lisibles avec le mappage de banque courant. Ne doit pas être null.

packed_size

Nombre d’octets de l’entrée complète. Un flux ZX0 inclut son marqueur de fin et n’a pas d’octets supplémentaires après lui. Un conteneur KQA1 inclut son en-tête de neuf octets. Maximum : 65535 octets.

Valeur renvoyée

Renvoie le nombre d’octets décodés en cas de succès, zéro en cas d’erreur. Vérifiez toujours aussi zx0_error.

Conditions et limites

Incluez zx0.h et compilez lib/zx0.c. Ces routines partagent un espace temporaire et ne sont pas réentrantes depuis les interruptions. Entrée et sortie ne doivent ni se chevaucher, ni boucler dans l’espace d’adressage CPU, ni franchir les fenêtres de banques actuellement mappées. La bibliothèque ne change pas les banques de ressources.

Chaque appel met à jour zx0_error : 0 succès, 1 argument invalide, 2 entrée tronquée, 3 flux malformé, 4 espace de sortie insuffisant, 5 affichage actif. Un échec peut laisser une sortie partielle : ne l’utilisez pas. Si plusieurs conditions sont invalides, la première détectée détermine le code.

Accepte les flux ZX0 v2 en sens avant. ZX0 v1, les flux inverses et les dictionnaires externes sont hors de cette interface. Connaissez la taille décodée de la ressource produite sur l’hôte et fournissez assez de stockage.

Renvoie l’erreur 5 si le LCD est activé ; être simplement en VBlank ne suffit pas. Affichage, VBK et interruptions restent inchangés. L’appelant arrête puis redémarre le LCD.

Format ZX0 — Einar Saukas

Exemple d’utilisation

c
count=zx0_decompress_vram(0x8800,packed_tiles,packed_tiles_SIZE);
    if(count!=48||zx0_error!=ZX0_OK)failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.

zx0_decompress_vram: DMG — La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.
DMG — La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.
zx0_decompress_vram: CGB — La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.
CGB — La ligne RAM MAP répète les tuiles carré, losange et damier. AUTO RLE MAP forme une barre horizontale avec seize carrés. VRAM TILES répète les trois mêmes tuiles après décodage de leurs pixels en VRAM. Sur CGB et FC, le carré est blanc, le losange rouge et le damier bleu ; DMG utilise des nuances de gris. CHECKS OK confirme que les trois appels ont renvoyé les tailles décodées attendues sans erreur.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\zx0_decode.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\zx0_decode.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/zx0.h:21

Notes de déclaration (texte source)
Decode directly into the selected GB VRAM bank ($8000..$9FFF), with LCD off.
Preserve LCDC, VBK and interrupt state. Output must fit before $A000.

kitaqgb/lib/zx0.c:132

c
u16 zx0_decompress_vram(u16 vram_addr,const void* src,u16 packed_size) {
    zx0_error=ZX0_OK;
    if(vram_addr<0x8000||vram_addr>=0xA000) { zx0_error=ZX0_BAD_ARGUMENT; return 0; }
    if(kq_zx_lcdc&0x80) { zx0_error=ZX0_DISPLAY_ACTIVE; return 0; }
    return zx0_decompress((void*)vram_addr,(u16)(0xA000-vram_addr),src,packed_size);
}

asset.h — Identifiants de ressources et descripteurs de données

La bibliothèque de ressources retrouve les données en ROM à partir d’un identifiant de 8 bits. Incluez asset.c et, sur FC, également bank.c. Chaque AssetDesc compact occupe 6 octets : type, banque des données, adresse sur 16 bits et longueur en octets. La table et les données peuvent se trouver dans des banques différentes.

Enregistrez la table avant toute recherche. Cet enregistrement est un état global partagé : ne le modifiez pas pendant une recherche. La bibliothèque vérifie les identifiants et le pointeur de sortie de asset_get, mais pas la table enregistrée, les adresses des données ni le contenu de la cartouche.

Recherche une ressource RAW ou TILES et transfère ses desc.len octets avec __vram_copy. Sélectionnez d’abord la banque ROM des données : cette fonction GB utilise directement desc.ptr et ne sélectionne pas desc.bank pour le transfert.

asset_get

Copie un AssetDesc depuis la banque ROM de la table enregistrée vers l’espace fourni par l’appelant. Elle récupère les métadonnées de la ressource, pas son contenu.

Syntaxe

c
u8 asset_get(u8 asset_id, AssetDesc* out_desc);

Paramètres

asset_id

Indice de ressource à partir de zéro. Il doit vérifier asset_id < count dans la table enregistrée.

out_desc

Espace accessible en écriture pour un descripteur de 6 octets. Un pointeur nul est rejeté avant tout accès à la table.

Valeur renvoyée

1 après copie du descripteur ; 0 si la sortie est nulle ou l’identifiant hors limites. Dans ces deux cas, la sortie reste inchangée.

Conditions et limites

Enregistrez la table avant toute recherche. Cet enregistrement est un état global partagé : ne le modifiez pas pendant une recherche. La bibliothèque vérifie les identifiants et le pointeur de sortie de asset_get, mais pas la table enregistrée, les adresses des données ni le contenu de la cartouche.

Les exemples placent le code appelant dans la banque fixe 0 afin qu’un changement de banque source ne le rende pas inaccessible. Les transferts sont synchrones. N’interrompez pas un transfert par une autre copie changeant de banque ; cette fonction ne garantit pas à elle seule la sûreté des interruptions de toute l’application.

Exemple d’utilisation

c
loaded=asset_get(0,&descriptor);
expect(loaded==1,1);
expect(descriptor.type==ASSET_TYPE_TILES && descriptor.bank==2,2);
expect(descriptor.ptr==asset_shapes && descriptor.len==144,3);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple lit le descripteur 0 et vérifie le type TILES, la banque 2, le pointeur et la longueur de 144 octets. Les identifiants invalides et sorties nulles doivent être refusés, sans modifier la valeur de sortie précédente.

Image attendue : une rangée rouge part de (16,32) et occupe 72×8 pixels. Elle répète trois fois un triangle de 8×8, un carré de 8×8 au contour d’un pixel et une tuile dont les quatre colonnes de gauche sont pleines. Le triangle s’élargit d’un pixel en haut à gauche à huit sur sa ligne inférieure.

Sur GB, le triangle et le contour bleus en (16,64) montrent le résultat de __farmemcpy ; la paire verte en (16,96), celui de __far_memcpy. Chaque paire occupe 16×8 pixels. Le CGB utilise ces couleurs ; le DMG affiche les mêmes formes en noir sur blanc.

L’état attendu est FAILED CHECKS 000 et FIRST FAILURE 00. La vérification exécute 300 images puis compare texte, formes et couleurs aux résultats attendus. Il s’agit d’une preuve sur émulateur, pas d’un essai sur matériel physique.

asset_get: DMG
DMG
asset_get: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\asset_banks.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\asset_banks.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/asset.h:24

Notes de déclaration (texte source)
Copy one descriptor from its ROM bank into caller storage. Return zero for a
null destination or an out-of-range ID; table validity is the caller's responsibility.

kitaqgb/lib/asset.c:18

c
u8 asset_get(u8 asset_id, AssetDesc* out_desc)
{
    if (out_desc == 0) return 0;
    if (asset_id >= asset_table_count) return 0;
    __farmemcpy(out_desc, asset_table_bank, asset_table + asset_id, sizeof(AssetDesc));
    return 1;
}
asset_get_bank

Lit dans le descripteur le numéro de banque des données. Ce n’est pas la banque de la table, et la fonction ne laisse pas cette banque de données sélectionnée.

Syntaxe

c
u8 asset_get_bank(u8 asset_id);

Paramètres

asset_id

Indice de ressource à partir de zéro. Il doit vérifier asset_id < count dans la table enregistrée.

Valeur renvoyée

Le champ bank sur 8 bits, ou 0 si la recherche échoue. La banque zéro pouvant être valide, utilisez asset_get() pour distinguer succès et valeur nulle.

Conditions et limites

Enregistrez la table avant toute recherche. Cet enregistrement est un état global partagé : ne le modifiez pas pendant une recherche. La bibliothèque vérifie les identifiants et le pointeur de sortie de asset_get, mais pas la table enregistrée, les adresses des données ni le contenu de la cartouche.

Chaque accesseur rappelle asset_get et copie un descripteur. Pour obtenir banque, pointeur et longueur ensemble, appelez asset_get une seule fois et lisez ses champs.

Les exemples placent le code appelant dans la banque fixe 0 afin qu’un changement de banque source ne le rende pas inaccessible. Les transferts sont synchrones. N’interrompez pas un transfert par une autre copie changeant de banque ; cette fonction ne garantit pas à elle seule la sûreté des interruptions de toute l’application.

Exemple d’utilisation

c
payload_bank=asset_get_bank(0);
expect(payload_bank==2,17); // Payload bank, not descriptor-table bank 3.
expect(asset_get_bank(4)==0,18); // Failure sentinel; a valid descriptor may also use bank 0.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple attend la banque de données 2 alors que la table est dans la banque 3. Il vérifie aussi qu’un identifiant invalide renvoie zéro.

Image attendue : une rangée rouge part de (16,32) et occupe 72×8 pixels. Elle répète trois fois un triangle de 8×8, un carré de 8×8 au contour d’un pixel et une tuile dont les quatre colonnes de gauche sont pleines. Le triangle s’élargit d’un pixel en haut à gauche à huit sur sa ligne inférieure.

Sur GB, le triangle et le contour bleus en (16,64) montrent le résultat de __farmemcpy ; la paire verte en (16,96), celui de __far_memcpy. Chaque paire occupe 16×8 pixels. Le CGB utilise ces couleurs ; le DMG affiche les mêmes formes en noir sur blanc.

L’état attendu est FAILED CHECKS 000 et FIRST FAILURE 00. La vérification exécute 300 images puis compare texte, formes et couleurs aux résultats attendus. Il s’agit d’une preuve sur émulateur, pas d’un essai sur matériel physique.

asset_get_bank: DMG
DMG
asset_get_bank: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\asset_banks.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\asset_banks.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/asset.h:32

Notes de déclaration (texte source)
Return the descriptor bank, or zero on lookup failure; zero can also be a valid bank.

kitaqgb/lib/asset.c:51

c
u8 asset_get_bank(u8 asset_id)
{
    AssetDesc desc;
    if (asset_get(asset_id, &desc) == 0) return 0;
    return desc.bank;
}
asset_get_len

Lit dans le descripteur la longueur de la ressource en octets. Il s’agit d’une métadonnée : la fonction n’examine pas le contenu et ne calcule aucun nombre de tuiles, d’éléments ou d’images.

Syntaxe

c
u16 asset_get_len(u8 asset_id);

Paramètres

asset_id

Indice de ressource à partir de zéro. Il doit vérifier asset_id < count dans la table enregistrée.

Valeur renvoyée

Le champ len sur 16 bits, en octets, ou 0 si la recherche échoue. Une ressource vide a aussi une longueur nulle ; asset_get() permet de faire la distinction.

Conditions et limites

Enregistrez la table avant toute recherche. Cet enregistrement est un état global partagé : ne le modifiez pas pendant une recherche. La bibliothèque vérifie les identifiants et le pointeur de sortie de asset_get, mais pas la table enregistrée, les adresses des données ni le contenu de la cartouche.

Chaque accesseur rappelle asset_get et copie un descripteur. Pour obtenir banque, pointeur et longueur ensemble, appelez asset_get une seule fois et lisez ses champs.

Les exemples placent le code appelant dans la banque fixe 0 afin qu’un changement de banque source ne le rende pas inaccessible. Les transferts sont synchrones. N’interrompez pas un transfert par une autre copie changeant de banque ; cette fonction ne garantit pas à elle seule la sûreté des interruptions de toute l’application.

Exemple d’utilisation

c
expect(asset_get_len(0)==144,21); // Bytes, not tiles.
expect(asset_get_len(3)==0 && asset_get_len(4)==0,22); // Empty asset and invalid ID both yield zero.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La ressource de neuf tuiles doit indiquer 144 octets, et non neuf tuiles. Une ressource vide comme un identifiant invalide doivent renvoyer zéro.

Image attendue : une rangée rouge part de (16,32) et occupe 72×8 pixels. Elle répète trois fois un triangle de 8×8, un carré de 8×8 au contour d’un pixel et une tuile dont les quatre colonnes de gauche sont pleines. Le triangle s’élargit d’un pixel en haut à gauche à huit sur sa ligne inférieure.

Sur GB, le triangle et le contour bleus en (16,64) montrent le résultat de __farmemcpy ; la paire verte en (16,96), celui de __far_memcpy. Chaque paire occupe 16×8 pixels. Le CGB utilise ces couleurs ; le DMG affiche les mêmes formes en noir sur blanc.

L’état attendu est FAILED CHECKS 000 et FIRST FAILURE 00. La vérification exécute 300 images puis compare texte, formes et couleurs aux résultats attendus. Il s’agit d’une preuve sur émulateur, pas d’un essai sur matériel physique.

asset_get_len: DMG
DMG
asset_get_len: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\asset_banks.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\asset_banks.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/asset.h:37

Notes de déclaration (texte source)
Return the descriptor byte length, or zero if its ID cannot be resolved.

kitaqgb/lib/asset.c:68

c
u16 asset_get_len(u8 asset_id)
{
    AssetDesc desc;
    if (asset_get(asset_id, &desc) == 0) return 0;
    return desc.len;
}
asset_get_ptr

Lit l’adresse sur 16 bits conservée dans le descripteur. Le pointeur proche renvoyé ne contient aucun numéro de banque. Pour lire une autre banque ROM, associez-le à asset_get_bank() et à une fonction de copie interbanques.

Syntaxe

c
const u8* asset_get_ptr(u8 asset_id);

Paramètres

asset_id

Indice de ressource à partir de zéro. Il doit vérifier asset_id < count dans la table enregistrée.

Valeur renvoyée

Le const u8* enregistré, ou un pointeur nul si la recherche échoue. Le pointeur du descripteur n’étant pas validé, utilisez asset_get() pour reconnaître un échec de recherche.

Conditions et limites

Enregistrez la table avant toute recherche. Cet enregistrement est un état global partagé : ne le modifiez pas pendant une recherche. La bibliothèque vérifie les identifiants et le pointeur de sortie de asset_get, mais pas la table enregistrée, les adresses des données ni le contenu de la cartouche.

Chaque accesseur rappelle asset_get et copie un descripteur. Pour obtenir banque, pointeur et longueur ensemble, appelez asset_get une seule fois et lisez ses champs.

Les exemples placent le code appelant dans la banque fixe 0 afin qu’un changement de banque source ne le rende pas inaccessible. Les transferts sont synchrones. N’interrompez pas un transfert par une autre copie changeant de banque ; cette fonction ne garantit pas à elle seule la sûreté des interruptions de toute l’application.

Exemple d’utilisation

c
payload_pointer=asset_get_ptr(0);
expect(payload_pointer==asset_shapes,19);
expect(*asset_bank_marker==0xA1,20); // Getting the pointer leaves bank 1 selected.
// Use payload_bank together with payload_pointer for a far copy; do not dereference it here.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le pointeur doit correspondre à l’adresse ROM de la ressource après placement, tandis qu’un marqueur de la banque 1 reste lisible. L’exemple passe ensuite ce pointeur et la banque 2 à une copie interbanques.

Image attendue : une rangée rouge part de (16,32) et occupe 72×8 pixels. Elle répète trois fois un triangle de 8×8, un carré de 8×8 au contour d’un pixel et une tuile dont les quatre colonnes de gauche sont pleines. Le triangle s’élargit d’un pixel en haut à gauche à huit sur sa ligne inférieure.

Sur GB, le triangle et le contour bleus en (16,64) montrent le résultat de __farmemcpy ; la paire verte en (16,96), celui de __far_memcpy. Chaque paire occupe 16×8 pixels. Le CGB utilise ces couleurs ; le DMG affiche les mêmes formes en noir sur blanc.

L’état attendu est FAILED CHECKS 000 et FIRST FAILURE 00. La vérification exécute 300 images puis compare texte, formes et couleurs aux résultats attendus. Il s’agit d’une preuve sur émulateur, pas d’un essai sur matériel physique.

asset_get_ptr: DMG
DMG
asset_get_ptr: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\asset_banks.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\asset_banks.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/asset.h:35

Notes de déclaration (texte source)
Return the stored address without switching banks. Use the descriptor bank
with far-data helpers before dereferencing banked assets; failure returns null.

kitaqgb/lib/asset.c:60

c
const u8* asset_get_ptr(u8 asset_id)
{
    AssetDesc desc;
    if (asset_get(asset_id, &desc) == 0) return 0;
    return desc.ptr;
}
asset_load_raw

Recherche la ressource et copie min(desc.len, max_len) octets de sa banque ROM vers une mémoire accessible en écriture. Le type est ignoré : graphismes, cartes et morceaux sont copiés tels quels, sans décodage ni décompression.

Syntaxe

c
u8 asset_load_raw(u8 asset_id, void* dst, u16 max_len);

Paramètres

asset_id

Indice de ressource à partir de zéro. Il doit vérifier asset_id < count dans la table enregistrée.

dst

Destination en mémoire accessible en écriture, assez grande pour tous les octets copiés. Hors transfert de zéro octet, les adresses nulles ou invalides ne sont pas vérifiées.

max_len

Nombre maximal d’octets à copier, de 0 à 65535. Une limite plus petite tronque la copie ; zéro ne copie aucun octet du contenu.

Valeur renvoyée

0 si la recherche échoue ; sinon 1, même pour une copie tronquée, une limite nulle ou une ressource vide. Ce n’est ni un nombre d’octets ni la garantie que toute la ressource tenait dans le tampon.

Conditions et limites

Enregistrez la table avant toute recherche. Cet enregistrement est un état global partagé : ne le modifiez pas pendant une recherche. La bibliothèque vérifie les identifiants et le pointeur de sortie de asset_get, mais pas la table enregistrée, les adresses des données ni le contenu de la cartouche.

Toute la source doit être lisible dans le mappage ROM prévu, et toute la destination accessible en écriture. La copie ne passe pas automatiquement à la banque suivante, ne gère pas les chevauchements comme memmove et ne synchronise pas les écritures VRAM. Utilisez les API graphiques pour la VRAM.

Les exemples placent le code appelant dans la banque fixe 0 afin qu’un changement de banque source ne le rende pas inaccessible. Les transferts sont synchrones. N’interrompez pas un transfert par une autre copie changeant de banque ; cette fonction ne garantit pas à elle seule la sûreté des interruptions de toute l’application.

Exemple d’utilisation

c
loaded=asset_load_raw(0,buffer,7); // Success with truncation: copy seven of 144 bytes.
expect(loaded==1 && buffer[7]==0x55,7);
for(i=0;i<7;i++) expect(buffer[(__safe_index u8)i]==expected_shape_byte(i),8);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Une limite de sept copie seulement sept octets d’une ressource de 144, laisse le suivant à 0x55 et renvoie pourtant un succès. Le programme teste aussi la copie complète, une limite nulle, une ressource vide et la copie brute de données MAP.

Image attendue : une rangée rouge part de (16,32) et occupe 72×8 pixels. Elle répète trois fois un triangle de 8×8, un carré de 8×8 au contour d’un pixel et une tuile dont les quatre colonnes de gauche sont pleines. Le triangle s’élargit d’un pixel en haut à gauche à huit sur sa ligne inférieure.

Sur GB, le triangle et le contour bleus en (16,64) montrent le résultat de __farmemcpy ; la paire verte en (16,96), celui de __far_memcpy. Chaque paire occupe 16×8 pixels. Le CGB utilise ces couleurs ; le DMG affiche les mêmes formes en noir sur blanc.

L’état attendu est FAILED CHECKS 000 et FIRST FAILURE 00. La vérification exécute 300 images puis compare texte, formes et couleurs aux résultats attendus. Il s’agit d’une preuve sur émulateur, pas d’un essai sur matériel physique.

asset_load_raw: DMG
DMG
asset_load_raw: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\asset_banks.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\asset_banks.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/asset.h:27

Notes de déclaration (texte source)
Copy at most max_len bytes using the asset's bank. Success means the ID was
valid, even when the payload was truncated to fit the supplied limit.

kitaqgb/lib/asset.c:28

c
u8 asset_load_raw(u8 asset_id, void* dst, u16 max_len)
{
    AssetDesc desc;
    u16 len;
    if (asset_get(asset_id, &desc) == 0) return 0;
    len = desc.len;
    if (len > max_len) len = max_len;
    __farmemcpy(dst, desc.bank, desc.ptr, len);
    return 1;
}
asset_load_tiles

Recherche une ressource RAW ou TILES et transfère ses desc.len octets avec __vram_copy. Sélectionnez d’abord la banque ROM des données : cette fonction GB utilise directement desc.ptr et ne sélectionne pas desc.bank pour le transfert.

Syntaxe

c
u8 asset_load_tiles(u8 asset_id, u16 vram_dst);

Paramètres

asset_id

Indice de ressource à partir de zéro. Il doit vérifier asset_id < count dans la table enregistrée.

vram_dst

Adresse en octets dans la VRAM, entre $8000 et $9FFF, et non numéro de tuile. Pour les motifs, utilisez une adresse alignée sur 16 octets et une longueur multiple de 16 ; la bibliothèque ne vérifie pas ces règles de format.

Valeur renvoyée

0 pour un identifiant invalide ou un type autre que RAW/TILES ; 1 après un transfert accepté, même de longueur nulle. Ce succès ne valide ni l’encodage des tuiles ni leur affichage.

Conditions et limites

Enregistrez la table avant toute recherche. Cet enregistrement est un état global partagé : ne le modifiez pas pendant une recherche. La bibliothèque vérifie les identifiants et le pointeur de sortie de asset_get, mais pas la table enregistrée, les adresses des données ni le contenu de la cartouche.

Les exemples placent le code appelant dans la banque fixe 0 afin qu’un changement de banque source ne le rende pas inaccessible. Les transferts sont synchrones. N’interrompez pas un transfert par une autre copie changeant de banque ; cette fonction ne garantit pas à elle seule la sûreté des interruptions de toute l’application.

Le transfert écrit uniquement des octets : il ne place pas les tuiles sur la carte, n’attribue pas de couleurs et n’alloue pas de VRAM. Configurez séparément la carte et les palettes. Les exemples effectuent le transfert avec le rendu désactivé, puis activent l’affichage.

La routine GB rétablit la banque mémorisée par le compilateur. Maintenez cet état avec __bankswitch : une écriture directe dans le mapper ne le met pas à jour. L’emplacement HRAM de sauvegarde est partagé ; des transferts imbriqués qui l’écrasent ne sont pas sûrs.

Exemple d’utilisation

c
__bankswitch(payload_bank); // GB tile upload expects the payload bank already visible.
loaded=asset_load_tiles(0,0x8010); // Nine tiles = 144 bytes, LCD off.
expect(loaded==1,24);
__bankswitch(1);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple charge neuf motifs originaux de 8×8 pixels, soit 144 octets, et vérifie le rejet du type MAP et des identifiants invalides. Sur FC, cette longueur teste le bloc de 128 octets ainsi que les 16 octets restants.

Image attendue : une rangée rouge part de (16,32) et occupe 72×8 pixels. Elle répète trois fois un triangle de 8×8, un carré de 8×8 au contour d’un pixel et une tuile dont les quatre colonnes de gauche sont pleines. Le triangle s’élargit d’un pixel en haut à gauche à huit sur sa ligne inférieure.

Sur GB, le triangle et le contour bleus en (16,64) montrent le résultat de __farmemcpy ; la paire verte en (16,96), celui de __far_memcpy. Chaque paire occupe 16×8 pixels. Le CGB utilise ces couleurs ; le DMG affiche les mêmes formes en noir sur blanc.

L’état attendu est FAILED CHECKS 000 et FIRST FAILURE 00. La vérification exécute 300 images puis compare texte, formes et couleurs aux résultats attendus. Il s’agit d’une preuve sur émulateur, pas d’un essai sur matériel physique.

asset_load_tiles: DMG
DMG
asset_load_tiles: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\asset_banks.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\asset_banks.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/asset.h:30

Notes de déclaration (texte source)
Accept tile/raw descriptors and transfer their bytes to VRAM. This path passes
the descriptor pointer directly; callers must arrange the correct visible ROM bank.

kitaqgb/lib/asset.c:41

c
u8 asset_load_tiles(u8 asset_id, u16 vram_dst)
{
    AssetDesc desc;
    if (asset_get(asset_id, &desc) == 0) return 0;
    if (desc.type != ASSET_TYPE_TILES && desc.type != ASSET_TYPE_RAW) return 0;
    __vram_copy(vram_dst, desc.ptr, desc.len);
    return 1;
}
asset_set_table

Enregistre la banque, l’adresse et le nombre d’entrées de l’unique table active. La fonction conserve ces trois valeurs sans copier la table, charger de ressource ni allouer de mémoire.

Syntaxe

c
void asset_set_table(u8 bank, const AssetDesc* table, u8 count);

Paramètres

bank

Numéro sur 8 bits de la banque ROM de la table, et non de celle des données.

table

Pointeur proche vers count entrées AssetDesc consécutives. Les count * 6 octets doivent rester lisibles dans la banque de la table tant qu’elle est enregistrée.

count

Nombre d’entrées, de 0 à 255. Avec zéro, aucun identifiant n’est valide ; asset_set_table(0, 0, 0) permet d’enregistrer une table vide.

Valeur renvoyée

Aucune (void).

Conditions et limites

Enregistrez la table avant toute recherche. Cet enregistrement est un état global partagé : ne le modifiez pas pendant une recherche. La bibliothèque vérifie les identifiants et le pointeur de sortie de asset_get, mais pas la table enregistrée, les adresses des données ni le contenu de la cartouche.

Exemple d’utilisation

c
asset_set_table(3,asset_descriptors,4); // Four descriptors in bank 3, payloads in bank 2.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple enregistre quatre descripteurs dans la banque 3, avec les contenus non vides dans la banque 2. Il vérifie aussi qu’une table vide fait échouer la recherche sans lire l’adresse zéro.

Image attendue : une rangée rouge part de (16,32) et occupe 72×8 pixels. Elle répète trois fois un triangle de 8×8, un carré de 8×8 au contour d’un pixel et une tuile dont les quatre colonnes de gauche sont pleines. Le triangle s’élargit d’un pixel en haut à gauche à huit sur sa ligne inférieure.

Sur GB, le triangle et le contour bleus en (16,64) montrent le résultat de __farmemcpy ; la paire verte en (16,96), celui de __far_memcpy. Chaque paire occupe 16×8 pixels. Le CGB utilise ces couleurs ; le DMG affiche les mêmes formes en noir sur blanc.

L’état attendu est FAILED CHECKS 000 et FIRST FAILURE 00. La vérification exécute 300 images puis compare texte, formes et couleurs aux résultats attendus. Il s’agit d’une preuve sur émulateur, pas d’un essai sur matériel physique.

asset_set_table: DMG
DMG
asset_set_table: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\asset_banks.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\asset_banks.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/asset.h:21

Notes de déclaration (texte source)
Retain the descriptor table address, bank and count; the table is not copied.

kitaqgb/lib/asset.c:9

c
void asset_set_table(u8 bank, const AssetDesc* table, u8 count)
{
    asset_table_bank = bank;
    asset_table = table;
    asset_table_count = count;
}

audio.h — Musique, effets sonores et commandes audio

Fournit l’accès direct aux quatre voix, musique/effets en banques, routage stéréo, fondus et ondes personnalisées. Les identifiants des flux musicaux et API directes sont CH1=0, CH2=1, CH3=2, CH4=3. CH3 joue des formes d’onde ; CH4 génère du bruit.

Incluez audio_hwregs_gb.c avant audio.c et appelez Audio_Init au démarrage. Appelez Audio_Update exactement une fois par image, à environ 59,7 Hz. La lecture du flux modifie temporairement le mappage ROM ; ne réentrez pas dans ce pilote depuis une interruption.

Un effet consomme une paire (note,value) par mise à jour et se termine à note=0. value correspond à NR12 pour les effets d’impulsion, à NR32 pour CH3. Préfixez les données CH3 par 0xFF. Conservez le stockage jusqu’à la fin. Les priorités s’appliquent au sein d’un emplacement ; une priorité égale peut remplacer l’effet courant.

Audio_CancelMasterVolumeFade

Arrête les étapes de fondu suivantes en conservant les niveaux et registres actuels.

Syntaxe

c
void Audio_CancelMasterVolumeFade();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Exemple d’utilisation

c
// A sustained pulse moves left, right and center, then fades to a quieter level.
#include "gb_sound_example.h"
void main() {
    sound_begin("PAN AND VOLUME");
    Audio_SetMasterVolume(7,7);
    Audio_Ch1NoteOn(33,0xC0,2);
    Audio_SetPan(AUDIO_CHANNEL_CH1,AUDIO_PAN_LEFT);
    sound_result[0]=NR51;
    sound_wait(30);
    // Packed low two bits are CH1: 2 means right. Other channels remain centered.
    Audio_SetPanPacked(2);
    sound_result[1]=NR51;
    sound_wait(30);
    Audio_SetPanPacked(0);
    sound_result[2]=NR51;
    Audio_FadeToMasterVolume(1,1,5);
    sound_wait(30);
    sound_result[3]=NR50;
    sound_result[4]=Audio_FadeActive;
    sound_wait(30);
    // Cancel halfway through a rise: retain volume 4 instead of reaching 7.
    Audio_FadeToMasterVolume(7,7,5);
    sound_wait(15);
    Audio_CancelMasterVolumeFade();
    sound_result[5]=NR50;
    sound_wait(30);
    sound_result[6]=NR50;
    // A zero fade interval sets the target immediately. Level zero is not mute.
    Audio_FadeToMasterVolume(0,0,0);
    sound_result[7]=NR50;
    sound_wait(30);
    Audio_StopChannel(AUDIO_CHANNEL_CH1);
    sound_wait(15);
    sound_end();
}

Résultat attendu

A4 passe à gauche, à droite puis au centre. Au centre, le niveau descend de 7 à 1, puis remonte à 4 et s’y maintient. Le niveau 0 reste faiblement audible ; arrêter le canal produit le silence. Un changement de routage peut laisser un transitoire de filtre qui décroît.

Audio_CancelMasterVolumeFade: DMG
DMG
Audio_CancelMasterVolumeFade: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_mix.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-mix.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:125

Notes de déclaration (texte source)
Cancel further volume steps, retaining the current cached levels and hardware output.

kitaqgb/lib/audio.c:548

c
void Audio_CancelMasterVolumeFade() {
    Audio_FadeTargetLeft = Audio_MasterLeft;
    Audio_FadeTargetRight = Audio_MasterRight;
    Audio_FadeStepFrames = 0;
    Audio_FadeCounter = 0;
    Audio_FadeActive = 0;
}
Audio_Ch1NoteOn

Programme le balayage, le rapport cyclique, l’enveloppe et la hauteur CH1, puis déclenche l’impulsion.

Syntaxe

c
void __stackcall Audio_Ch1NoteOn(u8 note, u8 vol_env, u8 duty2);

Paramètres

note

Indice de hauteur de 0 à 67. Voir les notes sur le repli de plage et l’écart d’octave de CH3.

vol_env

Codage NR12/NR22/NR42 : demi-octet haut pour le volume initial, bit 3 pour une enveloppe croissante, trois bits bas pour sa période. 0xC0 maintient le volume à 12.

duty2

Rapport cyclique : 0=12,5 %, 1=25 %, 3=75 % ; toutes les autres valeurs choisissent 50 %.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

note indexe une table de hauteurs de 0 à 67 : 0 correspond à C2 et 33 à A4. Les valeurs supérieures à 67 sont bornées à 67 ; 60..67 utilisent les fréquences de 48..55. Au même indice, CH3 sonne une octave sous un canal d’impulsion. Les fonctions de déclenchement agissent directement sur le matériel, sans vérifier l’activation ni la pause.

Exemple d’utilisation

c
// Four isolated voices, each lasting 30 frames, separated by 15 silent frames.
#include "gb_sound_example.h"
void main() {
    sound_begin("FOUR SOUND CHANNELS");
    Audio_SetMasterVolume(3,3);
    // CH1: A4, 50% duty, fixed envelope volume 12.
    Audio_SetCh1Duty(2);
    sound_result[0]=Audio_Ch1Duty;
    Audio_Ch1NoteOn(33,0xC0,Audio_Ch1Duty);
    sound_result[1]=NR12;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH1); sound_wait(15);
    // CH2: A4, 25% duty. Changing the cached duty takes effect on this trigger.
    Audio_SetCh2Duty(1);
    sound_result[2]=Audio_Ch2Duty;
    Audio_Ch2NoteOn(33,0xC0,Audio_Ch2Duty);
    sound_result[3]=NR22;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH2); sound_wait(15);
    // CH3: the initialized triangle wave, at 50% digital output level.
    Audio_SetCh3Level(AUDIO_CH3_LEVEL_50);
    sound_result[4]=Audio_Ch3Level;
    Audio_Ch3NoteOn(33,Audio_Ch3Level);
    sound_result[5]=NR32;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // CH4: a sustained noise burst; param is NR43, not a pitched note number.
    Audio_SetCh4Param(0x35);
    sound_result[6]=Audio_Ch4Param;
    Audio_Ch4NoteOn(Audio_Ch4Param,0xC0);
    sound_result[7]=NR43;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH4); sound_wait(15);
    sound_end();
}

Résultat attendu

Après environ une demi-seconde de silence, écoutez CH1 A4, CH2 A4, CH3 A3 puis le bruit. Chaque voix dure 30 images, avec des pauses de 15 images. SEQUENCE COMPLETE marque la fin du programme ; utilisez l’enregistrement pour apprécier le son.

Audio_Ch1NoteOn: DMG
DMG
Audio_Ch1NoteOn: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_channels.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-channels.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:151

Notes de déclaration (texte source)
Trigger CH1 with the cached sweep and the supplied raw envelope. Clamp the
note index; duty values 0, 1 and 3 select their encodings, and all others use 2.

kitaqgb/lib/audio.c:132

c
void __stackcall Audio_Ch1NoteOn(u8 note, u8 vol_env, u8 duty2) {
    u16 freq;
    u8 duty_reg;
    u8 hi;

    if (note > AUDIO_NOTE_MAX) note = AUDIO_NOTE_MAX;
    freq = GB_FREQ_TABLE[note];

    duty_reg = 128;
    if (duty2 == 0) duty_reg = 0;
    else if (duty2 == 1) duty_reg = 64;
    else if (duty2 == 3) duty_reg = 192;

    NR10 = Audio_Ch1Sweep;
    NR11 = duty_reg;
    NR12 = vol_env;
    NR13 = (u8)(freq & 0xFF);
    hi = (u8)((u16)freq >> 8);
    NR14 = (u8)(hi | 0x80);
}
Audio_Ch2NoteOn

Programme le rapport cyclique, l’enveloppe et la hauteur CH2, puis déclenche l’impulsion.

Syntaxe

c
void __stackcall Audio_Ch2NoteOn(u8 note, u8 vol_env, u8 duty2);

Paramètres

note

Indice de hauteur de 0 à 67. Voir les notes sur le repli de plage et l’écart d’octave de CH3.

vol_env

Codage NR12/NR22/NR42 : demi-octet haut pour le volume initial, bit 3 pour une enveloppe croissante, trois bits bas pour sa période. 0xC0 maintient le volume à 12.

duty2

Rapport cyclique : 0=12,5 %, 1=25 %, 3=75 % ; toutes les autres valeurs choisissent 50 %.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

note indexe une table de hauteurs de 0 à 67 : 0 correspond à C2 et 33 à A4. Les valeurs supérieures à 67 sont bornées à 67 ; 60..67 utilisent les fréquences de 48..55. Au même indice, CH3 sonne une octave sous un canal d’impulsion. Les fonctions de déclenchement agissent directement sur le matériel, sans vérifier l’activation ni la pause.

Exemple d’utilisation

c
// Four isolated voices, each lasting 30 frames, separated by 15 silent frames.
#include "gb_sound_example.h"
void main() {
    sound_begin("FOUR SOUND CHANNELS");
    Audio_SetMasterVolume(3,3);
    // CH1: A4, 50% duty, fixed envelope volume 12.
    Audio_SetCh1Duty(2);
    sound_result[0]=Audio_Ch1Duty;
    Audio_Ch1NoteOn(33,0xC0,Audio_Ch1Duty);
    sound_result[1]=NR12;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH1); sound_wait(15);
    // CH2: A4, 25% duty. Changing the cached duty takes effect on this trigger.
    Audio_SetCh2Duty(1);
    sound_result[2]=Audio_Ch2Duty;
    Audio_Ch2NoteOn(33,0xC0,Audio_Ch2Duty);
    sound_result[3]=NR22;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH2); sound_wait(15);
    // CH3: the initialized triangle wave, at 50% digital output level.
    Audio_SetCh3Level(AUDIO_CH3_LEVEL_50);
    sound_result[4]=Audio_Ch3Level;
    Audio_Ch3NoteOn(33,Audio_Ch3Level);
    sound_result[5]=NR32;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // CH4: a sustained noise burst; param is NR43, not a pitched note number.
    Audio_SetCh4Param(0x35);
    sound_result[6]=Audio_Ch4Param;
    Audio_Ch4NoteOn(Audio_Ch4Param,0xC0);
    sound_result[7]=NR43;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH4); sound_wait(15);
    sound_end();
}

Résultat attendu

Après environ une demi-seconde de silence, écoutez CH1 A4, CH2 A4, CH3 A3 puis le bruit. Chaque voix dure 30 images, avec des pauses de 15 images. SEQUENCE COMPLETE marque la fin du programme ; utilisez l’enregistrement pour apprécier le son.

Audio_Ch2NoteOn: DMG
DMG
Audio_Ch2NoteOn: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_channels.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-channels.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:154

Notes de déclaration (texte source)
Trigger CH2 with the supplied raw envelope and a clamped note index. Duty
values 0, 1 and 3 select their encodings; all other values use duty 2.

kitaqgb/lib/audio.c:666

c
void __stackcall Audio_Ch2NoteOn(u8 note, u8 vol_env, u8 duty2) {
    u16 freq;
    u8 duty_reg;
    u8 hi;

    if (note > AUDIO_NOTE_MAX) note = AUDIO_NOTE_MAX;
    freq = GB_FREQ_TABLE[note];

    duty_reg = 128;
    if (duty2 == 0) duty_reg = 0;
    else if (duty2 == 1) duty_reg = 64;
    else if (duty2 == 3) duty_reg = 192;

    NR21 = duty_reg;
    NR22 = vol_env;
    NR23 = (u8)(freq & 0xFF);
    hi = (u8)((u16)freq >> 8);
    NR24 = (u8)(hi | 0x80);
}
Audio_Ch3NoteOn

Déclenche l’onde CH3 chargée à la hauteur et au niveau NR32 demandés.

Syntaxe

c
void __stackcall Audio_Ch3NoteOn(u8 note, u8 level);

Paramètres

note

Indice de hauteur de 0 à 67. Voir les notes sur le repli de plage et l’écart d’octave de CH3.

level

Codage NR32 : 0x00=muet, 0x20=100 %, 0x40=50 %, 0x60=25 %.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

note indexe une table de hauteurs de 0 à 67 : 0 correspond à C2 et 33 à A4. Les valeurs supérieures à 67 sont bornées à 67 ; 60..67 utilisent les fréquences de 48..55. Au même indice, CH3 sonne une octave sous un canal d’impulsion. Les fonctions de déclenchement agissent directement sur le matériel, sans vérifier l’activation ni la pause.

Exemple d’utilisation

c
// Four isolated voices, each lasting 30 frames, separated by 15 silent frames.
#include "gb_sound_example.h"
void main() {
    sound_begin("FOUR SOUND CHANNELS");
    Audio_SetMasterVolume(3,3);
    // CH1: A4, 50% duty, fixed envelope volume 12.
    Audio_SetCh1Duty(2);
    sound_result[0]=Audio_Ch1Duty;
    Audio_Ch1NoteOn(33,0xC0,Audio_Ch1Duty);
    sound_result[1]=NR12;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH1); sound_wait(15);
    // CH2: A4, 25% duty. Changing the cached duty takes effect on this trigger.
    Audio_SetCh2Duty(1);
    sound_result[2]=Audio_Ch2Duty;
    Audio_Ch2NoteOn(33,0xC0,Audio_Ch2Duty);
    sound_result[3]=NR22;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH2); sound_wait(15);
    // CH3: the initialized triangle wave, at 50% digital output level.
    Audio_SetCh3Level(AUDIO_CH3_LEVEL_50);
    sound_result[4]=Audio_Ch3Level;
    Audio_Ch3NoteOn(33,Audio_Ch3Level);
    sound_result[5]=NR32;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // CH4: a sustained noise burst; param is NR43, not a pitched note number.
    Audio_SetCh4Param(0x35);
    sound_result[6]=Audio_Ch4Param;
    Audio_Ch4NoteOn(Audio_Ch4Param,0xC0);
    sound_result[7]=NR43;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH4); sound_wait(15);
    sound_end();
}

Résultat attendu

Après environ une demi-seconde de silence, écoutez CH1 A4, CH2 A4, CH3 A3 puis le bruit. Chaque voix dure 30 images, avec des pauses de 15 images. SEQUENCE COMPLETE marque la fin du programme ; utilisez l’enregistrement pour apprécier le son.

Audio_Ch3NoteOn: DMG
DMG
Audio_Ch3NoteOn: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_channels.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-channels.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:157

Notes de déclaration (texte source)
Clamp the note index, program the raw NR32 output level, and trigger CH3.
Wave RAM must already contain the desired waveform; this does not load one.

kitaqgb/lib/audio.c:115

c
void __stackcall Audio_Ch3NoteOn(u8 note, u8 level) {
    u16 freq;
    u8 hi;

    if (note > AUDIO_NOTE_MAX) note = AUDIO_NOTE_MAX;
    freq = GB_FREQ_TABLE[note];

    NR30 = 128;
    NR31 = 0;
    NR32 = level;
    NR33 = (u8)(freq & 255);
    hi = (u8)((u16)freq >> 8);
    NR34 = (u8)(hi | 128);
}
Audio_Ch4NoteOn

Mémorise les paramètres de bruit, programme les registres d’enveloppe et de compteur polynomial, puis déclenche CH4.

Syntaxe

c
void __stackcall Audio_Ch4NoteOn(u8 param, u8 vol_env);

Paramètres

param

NR43 brut : bits 7..4 pour le décalage d’horloge, bit 3 pour le LFSR court, bits 2..0 pour le code de diviseur.

vol_env

Codage NR12/NR22/NR42 : demi-octet haut pour le volume initial, bit 3 pour une enveloppe croissante, trois bits bas pour sa période. 0xC0 maintient le volume à 12.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

L’arrêt automatique par longueur n’est pas activé. Terminez le son avec l’enveloppe ou un arrêt explicite.

Exemple d’utilisation

c
// Four isolated voices, each lasting 30 frames, separated by 15 silent frames.
#include "gb_sound_example.h"
void main() {
    sound_begin("FOUR SOUND CHANNELS");
    Audio_SetMasterVolume(3,3);
    // CH1: A4, 50% duty, fixed envelope volume 12.
    Audio_SetCh1Duty(2);
    sound_result[0]=Audio_Ch1Duty;
    Audio_Ch1NoteOn(33,0xC0,Audio_Ch1Duty);
    sound_result[1]=NR12;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH1); sound_wait(15);
    // CH2: A4, 25% duty. Changing the cached duty takes effect on this trigger.
    Audio_SetCh2Duty(1);
    sound_result[2]=Audio_Ch2Duty;
    Audio_Ch2NoteOn(33,0xC0,Audio_Ch2Duty);
    sound_result[3]=NR22;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH2); sound_wait(15);
    // CH3: the initialized triangle wave, at 50% digital output level.
    Audio_SetCh3Level(AUDIO_CH3_LEVEL_50);
    sound_result[4]=Audio_Ch3Level;
    Audio_Ch3NoteOn(33,Audio_Ch3Level);
    sound_result[5]=NR32;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // CH4: a sustained noise burst; param is NR43, not a pitched note number.
    Audio_SetCh4Param(0x35);
    sound_result[6]=Audio_Ch4Param;
    Audio_Ch4NoteOn(Audio_Ch4Param,0xC0);
    sound_result[7]=NR43;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH4); sound_wait(15);
    sound_end();
}

Résultat attendu

Après environ une demi-seconde de silence, écoutez CH1 A4, CH2 A4, CH3 A3 puis le bruit. Chaque voix dure 30 images, avec des pauses de 15 images. SEQUENCE COMPLETE marque la fin du programme ; utilisez l’enregistrement pour apprécier le son.

Audio_Ch4NoteOn: DMG
DMG
Audio_Ch4NoteOn: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_channels.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-channels.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:160

Notes de déclaration (texte source)
Cache the supplied noise parameter, program the raw envelope and polynomial
registers, then trigger CH4 with the length-enable bit clear.

kitaqgb/lib/audio.c:688

c
void __stackcall Audio_Ch4NoteOn(u8 param, u8 vol_env) {
    Audio_SetCh4Param(param);
    NR41 = 0x20;
    NR42 = vol_env;
    NR43 = Audio_Ch4Param;
    NR44 = 0x80;
}
Audio_FadeToMasterVolume

Rapproche chaque niveau de sortie d’un pas de sa cible à l’intervalle demandé.

Syntaxe

c
void __stackcall Audio_FadeToMasterVolume(u8 left, u8 right, u8 step_frames);

Paramètres

left

Niveau maître gauche, de 0 à 7 ; les valeurs supérieures sont bornées à 7. Zéro n’est pas un silence complet.

right

Niveau maître droit, de 0 à 7 ; les valeurs supérieures sont bornées à 7.

step_frames

Nombre d’appels Audio_Update par changement d’un niveau. Zéro applique immédiatement la cible.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Incluez audio_hwregs_gb.c avant audio.c et appelez Audio_Init au démarrage. Appelez Audio_Update exactement une fois par image, à environ 59,7 Hz. La lecture du flux modifie temporairement le mappage ROM ; ne réentrez pas dans ce pilote depuis une interruption.

Exemple d’utilisation

c
// A sustained pulse moves left, right and center, then fades to a quieter level.
#include "gb_sound_example.h"
void main() {
    sound_begin("PAN AND VOLUME");
    Audio_SetMasterVolume(7,7);
    Audio_Ch1NoteOn(33,0xC0,2);
    Audio_SetPan(AUDIO_CHANNEL_CH1,AUDIO_PAN_LEFT);
    sound_result[0]=NR51;
    sound_wait(30);
    // Packed low two bits are CH1: 2 means right. Other channels remain centered.
    Audio_SetPanPacked(2);
    sound_result[1]=NR51;
    sound_wait(30);
    Audio_SetPanPacked(0);
    sound_result[2]=NR51;
    Audio_FadeToMasterVolume(1,1,5);
    sound_wait(30);
    sound_result[3]=NR50;
    sound_result[4]=Audio_FadeActive;
    sound_wait(30);
    // Cancel halfway through a rise: retain volume 4 instead of reaching 7.
    Audio_FadeToMasterVolume(7,7,5);
    sound_wait(15);
    Audio_CancelMasterVolumeFade();
    sound_result[5]=NR50;
    sound_wait(30);
    sound_result[6]=NR50;
    // A zero fade interval sets the target immediately. Level zero is not mute.
    Audio_FadeToMasterVolume(0,0,0);
    sound_result[7]=NR50;
    sound_wait(30);
    Audio_StopChannel(AUDIO_CHANNEL_CH1);
    sound_wait(15);
    sound_end();
}

Résultat attendu

A4 passe à gauche, à droite puis au centre. Au centre, le niveau descend de 7 à 1, puis remonte à 4 et s’y maintient. Le niveau 0 reste faiblement audible ; arrêter le canal produit le silence. Un changement de routage peut laisser un transitoire de filtre qui décroît.

Audio_FadeToMasterVolume: DMG
DMG
Audio_FadeToMasterVolume: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_mix.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-mix.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:123

Notes de déclaration (texte source)
Move left/right volume toward clamped targets at the requested Audio_Update
call interval. An interval of zero applies the levels immediately.

kitaqgb/lib/audio.c:528

c
void __stackcall Audio_FadeToMasterVolume(u8 left, u8 right, u8 step_frames) {
    Audio_FadeTargetLeft = Audio_ClampVolume(left);
    Audio_FadeTargetRight = Audio_ClampVolume(right);

    if (step_frames == 0) {
        Audio_SetMasterVolume(Audio_FadeTargetLeft, Audio_FadeTargetRight);
        return;
    }

    Audio_FadeStepFrames = step_frames;
    Audio_FadeCounter = step_frames;
    if (Audio_MasterLeft == Audio_FadeTargetLeft && Audio_MasterRight == Audio_FadeTargetRight) {
        Audio_FadeActive = 0;
        Audio_FadeCounter = 0;
    } else {
        Audio_FadeActive = 1;
    }
}
Audio_Init

Active l’APU, initialise les états musique, effets, pause, mixage et onde, et laisse tous les canaux silencieux.

Syntaxe

c
void Audio_Init();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Incluez audio_hwregs_gb.c avant audio.c et appelez Audio_Init au démarrage. Appelez Audio_Update exactement une fois par image, à environ 59,7 Hz. La lecture du flux modifie temporairement le mappage ROM ; ne réentrez pas dans ce pilote depuis une interruption.

Exemple d’utilisation

c
// Four isolated voices, each lasting 30 frames, separated by 15 silent frames.
#include "gb_sound_example.h"
void main() {
    sound_begin("FOUR SOUND CHANNELS");
    Audio_SetMasterVolume(3,3);
    // CH1: A4, 50% duty, fixed envelope volume 12.
    Audio_SetCh1Duty(2);
    sound_result[0]=Audio_Ch1Duty;
    Audio_Ch1NoteOn(33,0xC0,Audio_Ch1Duty);
    sound_result[1]=NR12;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH1); sound_wait(15);
    // CH2: A4, 25% duty. Changing the cached duty takes effect on this trigger.
    Audio_SetCh2Duty(1);
    sound_result[2]=Audio_Ch2Duty;
    Audio_Ch2NoteOn(33,0xC0,Audio_Ch2Duty);
    sound_result[3]=NR22;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH2); sound_wait(15);
    // CH3: the initialized triangle wave, at 50% digital output level.
    Audio_SetCh3Level(AUDIO_CH3_LEVEL_50);
    sound_result[4]=Audio_Ch3Level;
    Audio_Ch3NoteOn(33,Audio_Ch3Level);
    sound_result[5]=NR32;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // CH4: a sustained noise burst; param is NR43, not a pitched note number.
    Audio_SetCh4Param(0x35);
    sound_result[6]=Audio_Ch4Param;
    Audio_Ch4NoteOn(Audio_Ch4Param,0xC0);
    sound_result[7]=NR43;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH4); sound_wait(15);
    sound_end();
}

Résultat attendu

Après environ une demi-seconde de silence, écoutez CH1 A4, CH2 A4, CH3 A3 puis le bruit. Chaque voix dure 30 images, avec des pauses de 15 images. SEQUENCE COMPLETE marque la fin du programme ; utilisez l’enregistrement pour apprécier le son.

Audio_Init: DMG
DMG
Audio_Init: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_channels.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-channels.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:76

Notes de déclaration (texte source)
Enable the APU and reset software streams, instruments, mix and fade state.
Load the initial triangle wave, then leave every channel silent. Call at startup
before concurrent interrupt-driven audio service can access these shared fields.

kitaqgb/lib/audio.c:864

c
void Audio_Init() {
    NR52 = 0x80;
    NR51 = 0xFF;
    Audio_Pan = 0xFF;
    Audio_EffectPan = AUDIO_PAN_INHERIT;
    Audio_EffectPan3 = AUDIO_PAN_INHERIT;
    Audio_UpdateNR51();

    Audio_SetMasterVolume(AUDIO_VOLUME_MAX, AUDIO_VOLUME_MAX);
    Audio_SilenceAll();

    Audio_PlayingMusic = 0;
    Audio_Paused = 0;
    Audio_MusicEnabled = 1;
    Audio_SfxEnabled = 1;
    Audio_Delay = 0;
    Audio_MusicBank = 0;
    Audio_MusicPointer = 0;
    Audio_MusicLoopPoint = 0;

    Audio_EffectPointer = 0;
    Audio_EffectPriority = 0;
    Audio_EffectBank = 0;
    Audio_EffectPointer3 = 0;
    Audio_EffectPriority3 = 0;
    Audio_EffectBank3 = 0;
    Audio_EffectUsesCh2 = 0;
    Audio_EffectPan = AUDIO_PAN_INHERIT;
    Audio_EffectPan3 = AUDIO_PAN_INHERIT;

    Audio_LastChMask = 0;
    Audio_LastCh1Note = 0;
    Audio_LastCh2Note = 0;
    Audio_LastCh3Note = 0;
    Audio_LastCh4Param = 0;

    Audio_Ch1Duty = 2;
    Audio_Ch2Duty = 2;
    Audio_Ch1Env = 0xF1;
    Audio_Ch2Env = 0xF2;
    Audio_Ch4Env = 0xF1;
    Audio_Ch4Param = 0x00;
    Audio_Ch3Level = AUDIO_CH3_LEVEL_100;
    Audio_Ch3Wave = AUDIO_WAVE_TRIANGLE;
    Audio_Ch1Sweep = 0x00;

    Audio_SetCustomWaveTriangle();
#ifdef AUDIO_EXCLUDE_WAVE_LOAD_API
    Audio_ApplyWaveBytes(Audio_CustomWave);
#else
    Audio_LoadWave(Audio_Ch3Wave);
#endif
    Audio_Ch3Off();
}
Audio_LoadCustomWave

Copie seize octets dans le cache d’onde personnalisée et la RAM d’onde CH3.

Syntaxe

c
void __stackcall Audio_LoadCustomWave(const u8 *wave16);

Paramètres

wave16

Seize octets lisibles ; les demi-octets haut et bas codent des échantillons successifs. NULL est ignoré.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

L’appelant peut réutiliser la source après copie. La fonction désactive le DAC pour écrire ; l’appelant doit redéclencher une note.

Exemple d’utilisation

c
// Compare a triangle preset with an original packed 32-sample pulse waveform.
#include "gb_sound_example.h"
__prg_rom u8 custom_wave[16]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0,0,0,0,0,0,0,0};
void main() {
    sound_begin("WAVE PRESET CUSTOM");
    Audio_SetMasterVolume(3,3);
    Audio_LoadWave(AUDIO_WAVE_TRIANGLE);
    Audio_Ch3NoteOn(33,AUDIO_CH3_LEVEL_100);
    sound_wait(45); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // Loading copies all sixteen bytes and enables the DAC without triggering a note.
    Audio_LoadCustomWave(custom_wave);
    sound_result[0]=Audio_CustomWave[0]; sound_result[1]=Audio_CustomWave[8];
    Audio_Ch3NoteOn(33,AUDIO_CH3_LEVEL_100);
    sound_wait(45); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // The cache survives another preset load; select CUSTOM to reuse it.
    Audio_LoadWave(AUDIO_WAVE_SAW);
    Audio_LoadWave(AUDIO_WAVE_CUSTOM);
    sound_result[2]=WAVE0; sound_result[3]=WAVE8;
    Audio_Ch3NoteOn(33,AUDIO_CH3_LEVEL_100);
    sound_wait(45); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    sound_end();
}

Résultat attendu

Écoutez le préréglage triangle, une onde d’impulsion originale, puis la même onde rechargée depuis le cache. Chaque son dure 45 images, avec des pauses de 15 images. Tous sont à environ 220 Hz ; seul le premier a un timbre différent.

Audio_LoadCustomWave: DMG
DMG
Audio_LoadCustomWave: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_wave.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-wave.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:138

Notes de déclaration (texte source)
Copy 16 packed sample bytes into the persistent custom cache and wave RAM.
A null pointer is ignored; the source is needed only for this call.

kitaqgb/lib/audio.c:614

c
void __stackcall Audio_LoadCustomWave(const u8 *wave16) {
    if (wave16 == 0) return;

    Audio_CustomWave[0] = wave16[0];   Audio_CustomWave[1] = wave16[1];
    Audio_CustomWave[2] = wave16[2];   Audio_CustomWave[3] = wave16[3];
    Audio_CustomWave[4] = wave16[4];   Audio_CustomWave[5] = wave16[5];
    Audio_CustomWave[6] = wave16[6];   Audio_CustomWave[7] = wave16[7];
    Audio_CustomWave[8] = wave16[8];   Audio_CustomWave[9] = wave16[9];
    Audio_CustomWave[10] = wave16[10]; Audio_CustomWave[11] = wave16[11];
    Audio_CustomWave[12] = wave16[12]; Audio_CustomWave[13] = wave16[13];
    Audio_CustomWave[14] = wave16[14]; Audio_CustomWave[15] = wave16[15];

    Audio_ApplyWaveBytes(Audio_CustomWave);
}
Audio_LoadWave

Installe une onde prédéfinie ou personnalisée en cache dans la RAM d’onde CH3.

Syntaxe

c
void __stackcall Audio_LoadWave(u8 wave_id);

Paramètres

wave_id

Identifiant AUDIO_WAVE_* de 0 à 7 ; 7 choisit l’onde personnalisée en cache. Les valeurs supérieures à 7 n’ont aucun effet.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Le chargement ne déclenche pas de note et ne modifie pas Audio_Ch3Wave. Le préréglage triangle remet aussi le cache personnalisé à une onde triangulaire. Appelez Audio_Ch3NoteOn pour déclencher la voix.

Exemple d’utilisation

c
// Compare a triangle preset with an original packed 32-sample pulse waveform.
#include "gb_sound_example.h"
__prg_rom u8 custom_wave[16]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0,0,0,0,0,0,0,0};
void main() {
    sound_begin("WAVE PRESET CUSTOM");
    Audio_SetMasterVolume(3,3);
    Audio_LoadWave(AUDIO_WAVE_TRIANGLE);
    Audio_Ch3NoteOn(33,AUDIO_CH3_LEVEL_100);
    sound_wait(45); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // Loading copies all sixteen bytes and enables the DAC without triggering a note.
    Audio_LoadCustomWave(custom_wave);
    sound_result[0]=Audio_CustomWave[0]; sound_result[1]=Audio_CustomWave[8];
    Audio_Ch3NoteOn(33,AUDIO_CH3_LEVEL_100);
    sound_wait(45); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // The cache survives another preset load; select CUSTOM to reuse it.
    Audio_LoadWave(AUDIO_WAVE_SAW);
    Audio_LoadWave(AUDIO_WAVE_CUSTOM);
    sound_result[2]=WAVE0; sound_result[3]=WAVE8;
    Audio_Ch3NoteOn(33,AUDIO_CH3_LEVEL_100);
    sound_wait(45); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    sound_end();
}

Résultat attendu

Écoutez le préréglage triangle, une onde d’impulsion originale, puis la même onde rechargée depuis le cache. Chaque son dure 45 images, avec des pauses de 15 images. Tous sont à environ 220 Hz ; seul le premier a un timbre différent.

Audio_LoadWave: DMG
DMG
Audio_LoadWave: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_wave.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-wave.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:135

Notes de déclaration (texte source)
Install a named preset or the cached custom wave. Unknown IDs are ignored.
This does not update Audio_Ch3Wave or trigger a new note.

kitaqgb/lib/audio.c:631

c
void __stackcall Audio_LoadWave(u8 wave_id) {
    if (wave_id == AUDIO_WAVE_TRIANGLE) Audio_LoadWave0();
    else if (wave_id == AUDIO_WAVE_SAW) Audio_LoadWave1();
    else if (wave_id == AUDIO_WAVE_VOWEL_A) Audio_LoadWave2();
    else if (wave_id == AUDIO_WAVE_VOWEL_I) Audio_LoadWave3();
    else if (wave_id == AUDIO_WAVE_VOWEL_U) Audio_LoadWave4();
    else if (wave_id == AUDIO_WAVE_VOWEL_E) Audio_LoadWave5();
    else if (wave_id == AUDIO_WAVE_VOWEL_O) Audio_LoadWave6();
    else if (wave_id == AUDIO_WAVE_CUSTOM) Audio_ApplyWaveBytes(Audio_CustomWave);
}
Audio_PlayMusic

Prépare le morceau de la banque indiquée depuis son début et réinitialise instruments, panoramique et delay.

Syntaxe

c
void __stackcall Audio_PlayMusic(u8 bank, u8 *song);

Paramètres

bank

Banque ROM contenant le flux ; elle doit correspondre à son emplacement.

song

Adresse de début du morceau. Le pilote emprunte le tableau, qui doit rester lisible pendant toute la lecture.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Incluez audio_hwregs_gb.c avant audio.c et appelez Audio_Init au démarrage. Appelez Audio_Update exactement une fois par image, à environ 59,7 Hz. La lecture du flux modifie temporairement le mappage ROM ; ne réentrez pas dans ce pilote depuis une interruption.

Le prochain Audio_Update lit les données. NULL n’est pas vérifié. Les effets existants restent actifs.

Exemple d’utilisation

c
// Original two-note phrase: pause preserves the cursor; the enable gate does not.
#include "gb_sound_example.h"
__prg_rom u8 song[]={
    AUDIO_CMD_SET_INST,AUDIO_STREAM_CHANNEL_CH1,2,0xC0,
    AUDIO_CMD_NOTE,AUDIO_STREAM_CHANNEL_CH1,33,AUDIO_CMD_WAIT,59,
    AUDIO_CMD_NOTE,AUDIO_STREAM_CHANNEL_CH1,40,AUDIO_CMD_WAIT,59,
    AUDIO_CMD_LOOP
};
void main() {
    u8 delay;
    sound_begin("MUSIC PAUSE GATE");
    Audio_SetMasterVolume(3,3);
    Audio_PlayMusic(0,song);
    sound_wait(30);
    delay=Audio_Delay;
    Audio_SetPaused(1);
    sound_wait(30);
    sound_result[0]=(u8)(Audio_Delay==delay);
    sound_result[1]=Audio_Paused;
    Audio_SetPaused(0);
    sound_wait(30);
    sound_result[2]=Audio_Paused;
    // Disabling suppresses note writes; the next 30 updates still consume data.
    Audio_SetMusicEnabled(0);
    sound_wait(30);
    sound_result[3]=Audio_Delay;
    sound_result[4]=Audio_MusicEnabled;
    // Explicitly stop the sounding channel while leaving the stream running.
    Audio_StopChannel(AUDIO_CHANNEL_CH1);
    sound_wait(30);
    Audio_SetMusicEnabled(1);
    sound_wait(30);
    Audio_StopMusic();
    sound_result[5]=Audio_PlayingMusic;
    sound_wait(30);
    sound_end();
}

Résultat attendu

Écoutez une note, le silence de pause, la reprise, une note maintenue lorsque la musique est désactivée, le silence explicite du canal, la note suivante après réactivation, puis l’arrêt. La RAM confirme aussi que 30 mises à jour en pause préservent delay, tandis que la simple désactivation le fait avancer jusqu’à 30.

Audio_PlayMusic: DMG
DMG
Audio_PlayMusic: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_music.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-music.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:83

Notes de déclaration (texte source)
Retain the bank and song pointer, reset legacy instruments/cursors, and arm
playback from the beginning. Supply a valid, persistent song; no bytes are copied
and null is not checked. Existing effect streams remain active.

kitaqgb/lib/audio.c:924

c
void __stackcall Audio_PlayMusic(u8 bank, u8 *song) {
    Audio_PlayingMusic = 0;
    Audio_MusicBank = bank;
    Audio_MusicPointer = song;
    Audio_MusicLoopPoint = song;
    Audio_Delay = 0;
    Audio_LastChMask = 0;

    Audio_Ch1Duty = 2;
    Audio_Ch2Duty = 2;
    Audio_Ch1Env = 0xF1;
    Audio_Ch2Env = 0xF2;
    Audio_Ch4Env = 0xF1;
    Audio_Ch4Param = 0x00;
    Audio_Ch3Level = AUDIO_CH3_LEVEL_100;
    Audio_Ch3Wave = AUDIO_WAVE_TRIANGLE;
    Audio_Ch1Sweep = 0x00;
    Audio_Pan = 0xFF;
    Audio_UpdateNR51();
    Audio_LoadWave(Audio_Ch3Wave);

    Audio_PlayingMusic = 1;
}
Audio_PlaySFX

Mémorise la banque ROM courante et demande un effet héritant du panoramique de base.

Syntaxe

c
void __stackcall Audio_PlaySFX(u8 *sfx, u8 priority);

Paramètres

sfx

Début du flux d’octets de l’effet. Voir les notes pour les formats d’impulsion et CH3.

priority

Priorité de 0 à 255. La plus grande gagne ; une valeur égale peut aussi remplacer l’effet courant.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Un effet consomme une paire (note,value) par mise à jour et se termine à note=0. value correspond à NR12 pour les effets d’impulsion, à NR32 pour CH3. Préfixez les données CH3 par 0xFF. Conservez le stockage jusqu’à la fin. Les priorités s’appliquent au sein d’un emplacement ; une priorité égale peut remplacer l’effet courant.

Dans la configuration ordinaire, la libération d’un effet coupe CH3. Elle coupe CH1 si la musique est arrêtée, mais ne rejoue pas automatiquement une ancienne note lorsque la musique tourne. Avec AUDIO_VBLANK_SFX_RESTORE, elle demande la restauration par l’ISR.

Exemple d’utilisation

c
// Each pair lasts one update. Priority controls replacement within each slot.
#include "gb_sound_example.h"
#pragma bank 2
__prg_rom u8 effect[]={33,0xC0,33,0xC0,33,0xC0,33,0xC0,33,0xC0,33,0xC0,
    40,0xC0,40,0xC0,40,0xC0,40,0xC0,40,0xC0,40,0xC0,0};
__prg_rom u8 wave_effect[]={AUDIO_SFX_CH3_MARKER,
    33,0x20,33,0x20,33,0x20,33,0x20,33,0x20,33,0x20,
    40,0x20,40,0x20,40,0x20,40,0x20,40,0x20,40,0x20,0};
#pragma bank 0
void main() {
    sound_begin("BANKED SOUND EFFECT");
    Audio_SetMasterVolume(3,3);
    // Read the marker in bank 2 while restoring the caller's original mapping.
    Audio_PlaySFXPannedBanked(2,effect,5,AUDIO_PAN_LEFT);
    sound_result[0]=Audio_EffectPriority;
    Audio_PlaySFXBanked(2,effect,4);
    sound_result[1]=Audio_EffectPriority;
    sound_wait(30);
    Audio_PlaySFXPannedBanked(2,wave_effect,5,AUDIO_PAN_RIGHT);
    sound_result[2]=Audio_EffectPriority3;
    sound_wait(30);
    // Implicit-bank entry points capture bank 2; the service restores bank 1.
    __bankswitch(2);
    Audio_PlaySFX(effect,5);
    __bankswitch(1);
    sound_result[3]=Audio_EffectBank;
    sound_wait(30);
    __bankswitch(2);
    Audio_PlaySFXPanned(effect,5,AUDIO_PAN_RIGHT);
    __bankswitch(1);
    sound_wait(6);
    Audio_StopSfx();
    sound_result[4]=(u8)(Audio_EffectPointer==0);
    sound_wait(24);
    // Disabling effects releases current owners; re-enable before the next request.
    Audio_PlaySFXBanked(2,effect,5);
    sound_wait(6);
    Audio_SetSfxEnabled(0);
    sound_result[5]=Audio_SfxEnabled;
    sound_result[6]=(u8)(Audio_EffectPointer==0);
    sound_wait(24);
    Audio_SetSfxEnabled(1);
    Audio_PlaySFXBanked(2,effect,5);
    sound_wait(30);
    sound_result[7]=Audio_SfxEnabled;
    sound_end();
}

Résultat attendu

Les données de la banque 2 jouent une courte montée d’impulsion à gauche, un effet d’onde à droite puis une impulsion centrée. Les exemples suivants arrêtent tôt une impulsion droite, désactivent un effet puis réactivent la lecture. Une requête de priorité 4 ne peut pas remplacer la priorité 5.

Audio_PlaySFX: DMG
DMG
Audio_PlaySFX: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_sfx.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-sfx.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:93

Notes de déclaration (texte source)
Capture the currently mapped ROM bank and start an effect with inherited pan.
Use the explicit-bank API when the pointer belongs to another bank.

kitaqgb/lib/audio.c:1085

c
void __stackcall Audio_PlaySFX(u8 *sfx, u8 priority) {
    Audio_PlaySFXBanked(__rom_bank, sfx, priority);
}
Audio_PlaySFXBanked

Identifie le type d’effet dans sa banque source explicite et demande sa lecture avec le panoramique de base.

Syntaxe

c
void __stackcall Audio_PlaySFXBanked(u8 bank, u8 *sfx, u8 priority);

Paramètres

bank

Banque ROM contenant le flux ; elle doit correspondre à son emplacement.

sfx

Début du flux d’octets de l’effet. Voir les notes pour les formats d’impulsion et CH3.

priority

Priorité de 0 à 255. La plus grande gagne ; une valeur égale peut aussi remplacer l’effet courant.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Un effet consomme une paire (note,value) par mise à jour et se termine à note=0. value correspond à NR12 pour les effets d’impulsion, à NR32 pour CH3. Préfixez les données CH3 par 0xFF. Conservez le stockage jusqu’à la fin. Les priorités s’appliquent au sein d’un emplacement ; une priorité égale peut remplacer l’effet courant.

Dans la configuration ordinaire, la libération d’un effet coupe CH3. Elle coupe CH1 si la musique est arrêtée, mais ne rejoue pas automatiquement une ancienne note lorsque la musique tourne. Avec AUDIO_VBLANK_SFX_RESTORE, elle demande la restauration par l’ISR.

Exemple d’utilisation

c
// Each pair lasts one update. Priority controls replacement within each slot.
#include "gb_sound_example.h"
#pragma bank 2
__prg_rom u8 effect[]={33,0xC0,33,0xC0,33,0xC0,33,0xC0,33,0xC0,33,0xC0,
    40,0xC0,40,0xC0,40,0xC0,40,0xC0,40,0xC0,40,0xC0,0};
__prg_rom u8 wave_effect[]={AUDIO_SFX_CH3_MARKER,
    33,0x20,33,0x20,33,0x20,33,0x20,33,0x20,33,0x20,
    40,0x20,40,0x20,40,0x20,40,0x20,40,0x20,40,0x20,0};
#pragma bank 0
void main() {
    sound_begin("BANKED SOUND EFFECT");
    Audio_SetMasterVolume(3,3);
    // Read the marker in bank 2 while restoring the caller's original mapping.
    Audio_PlaySFXPannedBanked(2,effect,5,AUDIO_PAN_LEFT);
    sound_result[0]=Audio_EffectPriority;
    Audio_PlaySFXBanked(2,effect,4);
    sound_result[1]=Audio_EffectPriority;
    sound_wait(30);
    Audio_PlaySFXPannedBanked(2,wave_effect,5,AUDIO_PAN_RIGHT);
    sound_result[2]=Audio_EffectPriority3;
    sound_wait(30);
    // Implicit-bank entry points capture bank 2; the service restores bank 1.
    __bankswitch(2);
    Audio_PlaySFX(effect,5);
    __bankswitch(1);
    sound_result[3]=Audio_EffectBank;
    sound_wait(30);
    __bankswitch(2);
    Audio_PlaySFXPanned(effect,5,AUDIO_PAN_RIGHT);
    __bankswitch(1);
    sound_wait(6);
    Audio_StopSfx();
    sound_result[4]=(u8)(Audio_EffectPointer==0);
    sound_wait(24);
    // Disabling effects releases current owners; re-enable before the next request.
    Audio_PlaySFXBanked(2,effect,5);
    sound_wait(6);
    Audio_SetSfxEnabled(0);
    sound_result[5]=Audio_SfxEnabled;
    sound_result[6]=(u8)(Audio_EffectPointer==0);
    sound_wait(24);
    Audio_SetSfxEnabled(1);
    Audio_PlaySFXBanked(2,effect,5);
    sound_wait(30);
    sound_result[7]=Audio_SfxEnabled;
    sound_end();
}

Résultat attendu

Les données de la banque 2 jouent une courte montée d’impulsion à gauche, un effet d’onde à droite puis une impulsion centrée. Les exemples suivants arrêtent tôt une impulsion droite, désactivent un effet puis réactivent la lecture. Une requête de priorité 4 ne peut pas remplacer la priorité 5.

Audio_PlaySFXBanked: DMG
DMG
Audio_PlaySFXBanked: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_sfx.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-sfx.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:95

Notes de déclaration (texte source)
Start a banked effect with the channel's base pan, subject to priority arbitration.

kitaqgb/lib/audio.c:1078

c
void __stackcall Audio_PlaySFXBanked(u8 bank, u8 *sfx, u8 priority) {
    Audio_PlaySFXPannedBanked(bank, sfx, priority, AUDIO_PAN_INHERIT);
}
Audio_PlaySFXPanned

Mémorise la banque ROM courante et demande un effet avec un panoramique imposé.

Syntaxe

c
void __stackcall Audio_PlaySFXPanned(u8 *sfx, u8 priority, u8 pan);

Paramètres

sfx

Début du flux d’octets de l’effet. Voir les notes pour les formats d’impulsion et CH3.

priority

Priorité de 0 à 255. La plus grande gagne ; une valeur égale peut aussi remplacer l’effet courant.

pan

0=centre, 1=gauche, 2=droite, 3=muet. Les API d’effet interprètent les valeurs supérieures à 3, dont 0xFF, comme l’héritage du panoramique de base.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Un effet consomme une paire (note,value) par mise à jour et se termine à note=0. value correspond à NR12 pour les effets d’impulsion, à NR32 pour CH3. Préfixez les données CH3 par 0xFF. Conservez le stockage jusqu’à la fin. Les priorités s’appliquent au sein d’un emplacement ; une priorité égale peut remplacer l’effet courant.

Dans la configuration ordinaire, la libération d’un effet coupe CH3. Elle coupe CH1 si la musique est arrêtée, mais ne rejoue pas automatiquement une ancienne note lorsque la musique tourne. Avec AUDIO_VBLANK_SFX_RESTORE, elle demande la restauration par l’ISR.

Exemple d’utilisation

c
// Each pair lasts one update. Priority controls replacement within each slot.
#include "gb_sound_example.h"
#pragma bank 2
__prg_rom u8 effect[]={33,0xC0,33,0xC0,33,0xC0,33,0xC0,33,0xC0,33,0xC0,
    40,0xC0,40,0xC0,40,0xC0,40,0xC0,40,0xC0,40,0xC0,0};
__prg_rom u8 wave_effect[]={AUDIO_SFX_CH3_MARKER,
    33,0x20,33,0x20,33,0x20,33,0x20,33,0x20,33,0x20,
    40,0x20,40,0x20,40,0x20,40,0x20,40,0x20,40,0x20,0};
#pragma bank 0
void main() {
    sound_begin("BANKED SOUND EFFECT");
    Audio_SetMasterVolume(3,3);
    // Read the marker in bank 2 while restoring the caller's original mapping.
    Audio_PlaySFXPannedBanked(2,effect,5,AUDIO_PAN_LEFT);
    sound_result[0]=Audio_EffectPriority;
    Audio_PlaySFXBanked(2,effect,4);
    sound_result[1]=Audio_EffectPriority;
    sound_wait(30);
    Audio_PlaySFXPannedBanked(2,wave_effect,5,AUDIO_PAN_RIGHT);
    sound_result[2]=Audio_EffectPriority3;
    sound_wait(30);
    // Implicit-bank entry points capture bank 2; the service restores bank 1.
    __bankswitch(2);
    Audio_PlaySFX(effect,5);
    __bankswitch(1);
    sound_result[3]=Audio_EffectBank;
    sound_wait(30);
    __bankswitch(2);
    Audio_PlaySFXPanned(effect,5,AUDIO_PAN_RIGHT);
    __bankswitch(1);
    sound_wait(6);
    Audio_StopSfx();
    sound_result[4]=(u8)(Audio_EffectPointer==0);
    sound_wait(24);
    // Disabling effects releases current owners; re-enable before the next request.
    Audio_PlaySFXBanked(2,effect,5);
    sound_wait(6);
    Audio_SetSfxEnabled(0);
    sound_result[5]=Audio_SfxEnabled;
    sound_result[6]=(u8)(Audio_EffectPointer==0);
    sound_wait(24);
    Audio_SetSfxEnabled(1);
    Audio_PlaySFXBanked(2,effect,5);
    sound_wait(30);
    sound_result[7]=Audio_SfxEnabled;
    sound_end();
}

Résultat attendu

Les données de la banque 2 jouent une courte montée d’impulsion à gauche, un effet d’onde à droite puis une impulsion centrée. Les exemples suivants arrêtent tôt une impulsion droite, désactivent un effet puis réactivent la lecture. Une requête de priorité 4 ne peut pas remplacer la priorité 5.

Audio_PlaySFXPanned: DMG
DMG
Audio_PlaySFXPanned: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_sfx.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-sfx.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:98

Notes de déclaration (texte source)
Capture the currently mapped ROM bank and request an effect with a pan override.
Use the explicit-bank API when the pointer belongs to another bank.

kitaqgb/lib/audio.c:1091

c
void __stackcall Audio_PlaySFXPanned(u8 *sfx, u8 priority, u8 pan) {
    Audio_PlaySFXPannedBanked(__rom_bank, sfx, priority, pan);
}
Audio_PlaySFXPannedBanked

Réserve un emplacement d’effet d’impulsion ou CH3 avec banque, priorité et panoramique explicites.

Syntaxe

c
void __stackcall Audio_PlaySFXPannedBanked(u8 bank, u8 *sfx, u8 priority, u8 pan);

Paramètres

bank

Banque ROM contenant le flux ; elle doit correspondre à son emplacement.

sfx

Début du flux d’octets de l’effet. Voir les notes pour les formats d’impulsion et CH3.

priority

Priorité de 0 à 255. La plus grande gagne ; une valeur égale peut aussi remplacer l’effet courant.

pan

0=centre, 1=gauche, 2=droite, 3=muet. Les API d’effet interprètent les valeurs supérieures à 3, dont 0xFF, comme l’héritage du panoramique de base.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Un effet consomme une paire (note,value) par mise à jour et se termine à note=0. value correspond à NR12 pour les effets d’impulsion, à NR32 pour CH3. Préfixez les données CH3 par 0xFF. Conservez le stockage jusqu’à la fin. Les priorités s’appliquent au sein d’un emplacement ; une priorité égale peut remplacer l’effet courant.

Dans la configuration ordinaire, la libération d’un effet coupe CH3. Elle coupe CH1 si la musique est arrêtée, mais ne rejoue pas automatiquement une ancienne note lorsque la musique tourne. Avec AUDIO_VBLANK_SFX_RESTORE, elle demande la restauration par l’ISR.

Exemple d’utilisation

c
// Each pair lasts one update. Priority controls replacement within each slot.
#include "gb_sound_example.h"
#pragma bank 2
__prg_rom u8 effect[]={33,0xC0,33,0xC0,33,0xC0,33,0xC0,33,0xC0,33,0xC0,
    40,0xC0,40,0xC0,40,0xC0,40,0xC0,40,0xC0,40,0xC0,0};
__prg_rom u8 wave_effect[]={AUDIO_SFX_CH3_MARKER,
    33,0x20,33,0x20,33,0x20,33,0x20,33,0x20,33,0x20,
    40,0x20,40,0x20,40,0x20,40,0x20,40,0x20,40,0x20,0};
#pragma bank 0
void main() {
    sound_begin("BANKED SOUND EFFECT");
    Audio_SetMasterVolume(3,3);
    // Read the marker in bank 2 while restoring the caller's original mapping.
    Audio_PlaySFXPannedBanked(2,effect,5,AUDIO_PAN_LEFT);
    sound_result[0]=Audio_EffectPriority;
    Audio_PlaySFXBanked(2,effect,4);
    sound_result[1]=Audio_EffectPriority;
    sound_wait(30);
    Audio_PlaySFXPannedBanked(2,wave_effect,5,AUDIO_PAN_RIGHT);
    sound_result[2]=Audio_EffectPriority3;
    sound_wait(30);
    // Implicit-bank entry points capture bank 2; the service restores bank 1.
    __bankswitch(2);
    Audio_PlaySFX(effect,5);
    __bankswitch(1);
    sound_result[3]=Audio_EffectBank;
    sound_wait(30);
    __bankswitch(2);
    Audio_PlaySFXPanned(effect,5,AUDIO_PAN_RIGHT);
    __bankswitch(1);
    sound_wait(6);
    Audio_StopSfx();
    sound_result[4]=(u8)(Audio_EffectPointer==0);
    sound_wait(24);
    // Disabling effects releases current owners; re-enable before the next request.
    Audio_PlaySFXBanked(2,effect,5);
    sound_wait(6);
    Audio_SetSfxEnabled(0);
    sound_result[5]=Audio_SfxEnabled;
    sound_result[6]=(u8)(Audio_EffectPointer==0);
    sound_wait(24);
    Audio_SetSfxEnabled(1);
    Audio_PlaySFXBanked(2,effect,5);
    sound_wait(30);
    sound_result[7]=Audio_SfxEnabled;
    sound_end();
}

Résultat attendu

Les données de la banque 2 jouent une courte montée d’impulsion à gauche, un effet d’onde à droite puis une impulsion centrée. Les exemples suivants arrêtent tôt une impulsion droite, désactivent un effet puis réactivent la lecture. Une requête de priorité 4 ne peut pas remplacer la priorité 5.

Audio_PlaySFXPannedBanked: DMG
DMG
Audio_PlaySFXPannedBanked: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_sfx.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-sfx.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:103

Notes de déclaration (texte source)
Retain a banked effect stream if its priority equals or exceeds the current
owner's priority, or that slot is empty. A leading CH3 marker selects the wave
slot and is skipped; other streams use the pulse slot. Paused requests are ignored.
Keep stream storage valid until completion; acceptance does not trigger a note.

kitaqgb/lib/audio.c:1041

c
void __stackcall Audio_PlaySFXPannedBanked(u8 bank, u8 *sfx, u8 priority, u8 pan) {
    u8 sfx_pan = pan;
    u8 use_ch3 = 0;
    if (sfx_pan > AUDIO_PAN_MUTE) sfx_pan = AUDIO_PAN_INHERIT;

    if (Audio_Paused != 0) return;
    if (sfx != 0) {
        use_ch3 = Audio_SfxStartsOnCh3Banked(bank, sfx);
        if (use_ch3 != 0) {
            if (Audio_EffectPointer3 == 0 || priority >= Audio_EffectPriority3) {
                Audio_EffectPointer3 = sfx + 1;
                Audio_EffectPriority3 = priority;
                Audio_EffectBank3 = bank;
                Audio_EffectPan3 = sfx_pan;
                Audio_UpdateNR51();
            }
            return;
        }
    }
    if (Audio_EffectPointer == 0 || priority >= Audio_EffectPriority) {
#ifdef AUDIO_VBLANK_SFX_AUTO_CH2
        // Choose pulse-channel ownership when accepting the effect, so its later
        // updates and deferred recovery agree on which physical channel was borrowed.
        Audio_EffectUsesCh2 = (u8)(AudioVBlank_MusicPlaying != 0 &&
                                   AudioVBlank_MusicEnabled != 0);
#else
        Audio_EffectUsesCh2 = 0;
#endif
        Audio_EffectPointer = sfx;
        Audio_EffectPriority = priority;
        Audio_EffectBank = bank;
        Audio_EffectPan = sfx_pan;
        Audio_UpdateNR51();
    }
}
Audio_SetCh1Duty

Mémorise le rapport cyclique de la prochaine note CH1.

Syntaxe

c
void __stackcall Audio_SetCh1Duty(u8 duty);

Paramètres

duty

Indice de rapport cyclique ; les deux bits bas sont stockés. 0=12,5 %, 1=25 %, 2=50 %, 3=75 %.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Cet appel seul ne change pas les registres audio actifs. Passez la valeur mémorisée au déclenchement de note ou utilisez le flux correspondant pour l’appliquer.

Exemple d’utilisation

c
// Four isolated voices, each lasting 30 frames, separated by 15 silent frames.
#include "gb_sound_example.h"
void main() {
    sound_begin("FOUR SOUND CHANNELS");
    Audio_SetMasterVolume(3,3);
    // CH1: A4, 50% duty, fixed envelope volume 12.
    Audio_SetCh1Duty(2);
    sound_result[0]=Audio_Ch1Duty;
    Audio_Ch1NoteOn(33,0xC0,Audio_Ch1Duty);
    sound_result[1]=NR12;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH1); sound_wait(15);
    // CH2: A4, 25% duty. Changing the cached duty takes effect on this trigger.
    Audio_SetCh2Duty(1);
    sound_result[2]=Audio_Ch2Duty;
    Audio_Ch2NoteOn(33,0xC0,Audio_Ch2Duty);
    sound_result[3]=NR22;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH2); sound_wait(15);
    // CH3: the initialized triangle wave, at 50% digital output level.
    Audio_SetCh3Level(AUDIO_CH3_LEVEL_50);
    sound_result[4]=Audio_Ch3Level;
    Audio_Ch3NoteOn(33,Audio_Ch3Level);
    sound_result[5]=NR32;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // CH4: a sustained noise burst; param is NR43, not a pitched note number.
    Audio_SetCh4Param(0x35);
    sound_result[6]=Audio_Ch4Param;
    Audio_Ch4NoteOn(Audio_Ch4Param,0xC0);
    sound_result[7]=NR43;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH4); sound_wait(15);
    sound_end();
}

Résultat attendu

Après environ une demi-seconde de silence, écoutez CH1 A4, CH2 A4, CH3 A3 puis le bruit. Chaque voix dure 30 images, avec des pauses de 15 images. SEQUENCE COMPLETE marque la fin du programme ; utilisez l’enregistrement pour apprécier le son.

Audio_SetCh1Duty: DMG
DMG
Audio_SetCh1Duty: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_channels.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-channels.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:141

Notes de déclaration (texte source)
Cache the low two duty bits for the next CH1 note; do not change the active register.

kitaqgb/lib/audio.c:644

c
void __stackcall Audio_SetCh1Duty(u8 duty) {
    Audio_Ch1Duty = (u8)(duty & 3);
}
Audio_SetCh2Duty

Mémorise le rapport cyclique de la prochaine note CH2.

Syntaxe

c
void __stackcall Audio_SetCh2Duty(u8 duty);

Paramètres

duty

Indice de rapport cyclique ; les deux bits bas sont stockés. 0=12,5 %, 1=25 %, 2=50 %, 3=75 %.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Cet appel seul ne change pas les registres audio actifs. Passez la valeur mémorisée au déclenchement de note ou utilisez le flux correspondant pour l’appliquer.

Exemple d’utilisation

c
// Four isolated voices, each lasting 30 frames, separated by 15 silent frames.
#include "gb_sound_example.h"
void main() {
    sound_begin("FOUR SOUND CHANNELS");
    Audio_SetMasterVolume(3,3);
    // CH1: A4, 50% duty, fixed envelope volume 12.
    Audio_SetCh1Duty(2);
    sound_result[0]=Audio_Ch1Duty;
    Audio_Ch1NoteOn(33,0xC0,Audio_Ch1Duty);
    sound_result[1]=NR12;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH1); sound_wait(15);
    // CH2: A4, 25% duty. Changing the cached duty takes effect on this trigger.
    Audio_SetCh2Duty(1);
    sound_result[2]=Audio_Ch2Duty;
    Audio_Ch2NoteOn(33,0xC0,Audio_Ch2Duty);
    sound_result[3]=NR22;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH2); sound_wait(15);
    // CH3: the initialized triangle wave, at 50% digital output level.
    Audio_SetCh3Level(AUDIO_CH3_LEVEL_50);
    sound_result[4]=Audio_Ch3Level;
    Audio_Ch3NoteOn(33,Audio_Ch3Level);
    sound_result[5]=NR32;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // CH4: a sustained noise burst; param is NR43, not a pitched note number.
    Audio_SetCh4Param(0x35);
    sound_result[6]=Audio_Ch4Param;
    Audio_Ch4NoteOn(Audio_Ch4Param,0xC0);
    sound_result[7]=NR43;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH4); sound_wait(15);
    sound_end();
}

Résultat attendu

Après environ une demi-seconde de silence, écoutez CH1 A4, CH2 A4, CH3 A3 puis le bruit. Chaque voix dure 30 images, avec des pauses de 15 images. SEQUENCE COMPLETE marque la fin du programme ; utilisez l’enregistrement pour apprécier le son.

Audio_SetCh2Duty: DMG
DMG
Audio_SetCh2Duty: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_channels.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-channels.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:143

Notes de déclaration (texte source)
Cache the low two duty bits for the next CH2 note; do not change the active register.

kitaqgb/lib/audio.c:649

c
void __stackcall Audio_SetCh2Duty(u8 duty) {
    Audio_Ch2Duty = (u8)(duty & 3);
}
Audio_SetCh3Level

Mémorise le niveau de sortie NR32 de la prochaine note CH3.

Syntaxe

c
void __stackcall Audio_SetCh3Level(u8 level);

Paramètres

level

Codage NR32 : 0x00=muet, 0x20=100 %, 0x40=50 %, 0x60=25 %.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Cet appel seul ne change pas les registres audio actifs. Passez la valeur mémorisée au déclenchement de note ou utilisez le flux correspondant pour l’appliquer.

Exemple d’utilisation

c
// Four isolated voices, each lasting 30 frames, separated by 15 silent frames.
#include "gb_sound_example.h"
void main() {
    sound_begin("FOUR SOUND CHANNELS");
    Audio_SetMasterVolume(3,3);
    // CH1: A4, 50% duty, fixed envelope volume 12.
    Audio_SetCh1Duty(2);
    sound_result[0]=Audio_Ch1Duty;
    Audio_Ch1NoteOn(33,0xC0,Audio_Ch1Duty);
    sound_result[1]=NR12;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH1); sound_wait(15);
    // CH2: A4, 25% duty. Changing the cached duty takes effect on this trigger.
    Audio_SetCh2Duty(1);
    sound_result[2]=Audio_Ch2Duty;
    Audio_Ch2NoteOn(33,0xC0,Audio_Ch2Duty);
    sound_result[3]=NR22;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH2); sound_wait(15);
    // CH3: the initialized triangle wave, at 50% digital output level.
    Audio_SetCh3Level(AUDIO_CH3_LEVEL_50);
    sound_result[4]=Audio_Ch3Level;
    Audio_Ch3NoteOn(33,Audio_Ch3Level);
    sound_result[5]=NR32;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // CH4: a sustained noise burst; param is NR43, not a pitched note number.
    Audio_SetCh4Param(0x35);
    sound_result[6]=Audio_Ch4Param;
    Audio_Ch4NoteOn(Audio_Ch4Param,0xC0);
    sound_result[7]=NR43;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH4); sound_wait(15);
    sound_end();
}

Résultat attendu

Après environ une demi-seconde de silence, écoutez CH1 A4, CH2 A4, CH3 A3 puis le bruit. Chaque voix dure 30 images, avec des pauses de 15 images. SEQUENCE COMPLETE marque la fin du programme ; utilisez l’enregistrement pour apprécier le son.

Audio_SetCh3Level: DMG
DMG
Audio_SetCh3Level: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_channels.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-channels.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:145

Notes de déclaration (texte source)
Cache the raw NR32 level encoding for the next CH3 note without writing hardware.

kitaqgb/lib/audio.c:654

c
void __stackcall Audio_SetCh3Level(u8 level) {
    Audio_Ch3Level = level;
}
Audio_SetCh4Param

Mémorise les paramètres de bruit NR43 de la prochaine note CH4.

Syntaxe

c
void __stackcall Audio_SetCh4Param(u8 param);

Paramètres

param

NR43 brut : bits 7..4 pour le décalage d’horloge, bit 3 pour le LFSR court, bits 2..0 pour le code de diviseur.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Cet appel seul ne change pas les registres audio actifs. Passez la valeur mémorisée au déclenchement de note ou utilisez le flux correspondant pour l’appliquer.

Exemple d’utilisation

c
// Four isolated voices, each lasting 30 frames, separated by 15 silent frames.
#include "gb_sound_example.h"
void main() {
    sound_begin("FOUR SOUND CHANNELS");
    Audio_SetMasterVolume(3,3);
    // CH1: A4, 50% duty, fixed envelope volume 12.
    Audio_SetCh1Duty(2);
    sound_result[0]=Audio_Ch1Duty;
    Audio_Ch1NoteOn(33,0xC0,Audio_Ch1Duty);
    sound_result[1]=NR12;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH1); sound_wait(15);
    // CH2: A4, 25% duty. Changing the cached duty takes effect on this trigger.
    Audio_SetCh2Duty(1);
    sound_result[2]=Audio_Ch2Duty;
    Audio_Ch2NoteOn(33,0xC0,Audio_Ch2Duty);
    sound_result[3]=NR22;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH2); sound_wait(15);
    // CH3: the initialized triangle wave, at 50% digital output level.
    Audio_SetCh3Level(AUDIO_CH3_LEVEL_50);
    sound_result[4]=Audio_Ch3Level;
    Audio_Ch3NoteOn(33,Audio_Ch3Level);
    sound_result[5]=NR32;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // CH4: a sustained noise burst; param is NR43, not a pitched note number.
    Audio_SetCh4Param(0x35);
    sound_result[6]=Audio_Ch4Param;
    Audio_Ch4NoteOn(Audio_Ch4Param,0xC0);
    sound_result[7]=NR43;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH4); sound_wait(15);
    sound_end();
}

Résultat attendu

Après environ une demi-seconde de silence, écoutez CH1 A4, CH2 A4, CH3 A3 puis le bruit. Chaque voix dure 30 images, avec des pauses de 15 images. SEQUENCE COMPLETE marque la fin du programme ; utilisez l’enregistrement pour apprécier le son.

Audio_SetCh4Param: DMG
DMG
Audio_SetCh4Param: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_channels.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-channels.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:147

Notes de déclaration (texte source)
Cache the raw noise polynomial encoding for the next CH4 note without writing hardware.

kitaqgb/lib/audio.c:659

c
void __stackcall Audio_SetCh4Param(u8 param) {
    Audio_Ch4Param = param;
}
Audio_SetMasterVolume

Borne les niveaux maîtres gauche/droit à 0..7, les écrit immédiatement et annule le fondu actif.

Syntaxe

c
void __stackcall Audio_SetMasterVolume(u8 left, u8 right);

Paramètres

left

Niveau maître gauche, de 0 à 7 ; les valeurs supérieures sont bornées à 7. Zéro n’est pas un silence complet.

right

Niveau maître droit, de 0 à 7 ; les valeurs supérieures sont bornées à 7.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Exemple d’utilisation

c
// A sustained pulse moves left, right and center, then fades to a quieter level.
#include "gb_sound_example.h"
void main() {
    sound_begin("PAN AND VOLUME");
    Audio_SetMasterVolume(7,7);
    Audio_Ch1NoteOn(33,0xC0,2);
    Audio_SetPan(AUDIO_CHANNEL_CH1,AUDIO_PAN_LEFT);
    sound_result[0]=NR51;
    sound_wait(30);
    // Packed low two bits are CH1: 2 means right. Other channels remain centered.
    Audio_SetPanPacked(2);
    sound_result[1]=NR51;
    sound_wait(30);
    Audio_SetPanPacked(0);
    sound_result[2]=NR51;
    Audio_FadeToMasterVolume(1,1,5);
    sound_wait(30);
    sound_result[3]=NR50;
    sound_result[4]=Audio_FadeActive;
    sound_wait(30);
    // Cancel halfway through a rise: retain volume 4 instead of reaching 7.
    Audio_FadeToMasterVolume(7,7,5);
    sound_wait(15);
    Audio_CancelMasterVolumeFade();
    sound_result[5]=NR50;
    sound_wait(30);
    sound_result[6]=NR50;
    // A zero fade interval sets the target immediately. Level zero is not mute.
    Audio_FadeToMasterVolume(0,0,0);
    sound_result[7]=NR50;
    sound_wait(30);
    Audio_StopChannel(AUDIO_CHANNEL_CH1);
    sound_wait(15);
    sound_end();
}

Résultat attendu

A4 passe à gauche, à droite puis au centre. Au centre, le niveau descend de 7 à 1, puis remonte à 4 et s’y maintient. Le niveau 0 reste faiblement audible ; arrêter le canal produit le silence. Un changement de routage peut laisser un transitoire de filtre qui décroît.

Audio_SetMasterVolume: DMG
DMG
Audio_SetMasterVolume: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_mix.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-mix.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:120

Notes de déclaration (texte source)
Clamp both output levels to 0..7, cancel any fade, and write NR50 immediately.

kitaqgb/lib/audio.c:515

c
void __stackcall Audio_SetMasterVolume(u8 left, u8 right) {
    Audio_MasterLeft = Audio_ClampVolume(left);
    Audio_MasterRight = Audio_ClampVolume(right);
    Audio_FadeTargetLeft = Audio_MasterLeft;
    Audio_FadeTargetRight = Audio_MasterRight;
    Audio_FadeStepFrames = 0;
    Audio_FadeCounter = 0;
    Audio_FadeActive = 0;
    Audio_UpdateNR50();
}
Audio_SetMusicEnabled

Détermine si le décodeur musical ordinaire écrit de nouvelles notes.

Syntaxe

c
void __stackcall Audio_SetMusicEnabled(u8 on);

Paramètres

on

Zéro désactive, non-zéro active. Consultez la description pour distinguer mise en sourdine et suspension des mises à jour.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

La désactivation laisse avancer le flux et traite instruments et panoramique. Elle ne coupe pas la note courante. Utilisez Audio_SetPaused pour mettre la lecture en pause.

Exemple d’utilisation

c
// Original two-note phrase: pause preserves the cursor; the enable gate does not.
#include "gb_sound_example.h"
__prg_rom u8 song[]={
    AUDIO_CMD_SET_INST,AUDIO_STREAM_CHANNEL_CH1,2,0xC0,
    AUDIO_CMD_NOTE,AUDIO_STREAM_CHANNEL_CH1,33,AUDIO_CMD_WAIT,59,
    AUDIO_CMD_NOTE,AUDIO_STREAM_CHANNEL_CH1,40,AUDIO_CMD_WAIT,59,
    AUDIO_CMD_LOOP
};
void main() {
    u8 delay;
    sound_begin("MUSIC PAUSE GATE");
    Audio_SetMasterVolume(3,3);
    Audio_PlayMusic(0,song);
    sound_wait(30);
    delay=Audio_Delay;
    Audio_SetPaused(1);
    sound_wait(30);
    sound_result[0]=(u8)(Audio_Delay==delay);
    sound_result[1]=Audio_Paused;
    Audio_SetPaused(0);
    sound_wait(30);
    sound_result[2]=Audio_Paused;
    // Disabling suppresses note writes; the next 30 updates still consume data.
    Audio_SetMusicEnabled(0);
    sound_wait(30);
    sound_result[3]=Audio_Delay;
    sound_result[4]=Audio_MusicEnabled;
    // Explicitly stop the sounding channel while leaving the stream running.
    Audio_StopChannel(AUDIO_CHANNEL_CH1);
    sound_wait(30);
    Audio_SetMusicEnabled(1);
    sound_wait(30);
    Audio_StopMusic();
    sound_result[5]=Audio_PlayingMusic;
    sound_wait(30);
    sound_end();
}

Résultat attendu

Écoutez une note, le silence de pause, la reprise, une note maintenue lorsque la musique est désactivée, le silence explicite du canal, la note suivante après réactivation, puis l’arrêt. La RAM confirme aussi que 30 mises à jour en pause préservent delay, tandis que la simple désactivation le fait avancer jusqu’à 30.

Audio_SetMusicEnabled: DMG
DMG
Audio_SetMusicEnabled: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_music.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-music.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:114

Notes de déclaration (texte source)
Set the music-processing gate. This does not silence notes already playing
or stop the legacy stream cursor from consuming commands.

kitaqgb/lib/audio.c:498

c
void __stackcall Audio_SetMusicEnabled(u8 on) {
    if (on != 0) Audio_MusicEnabled = 1;
    else Audio_MusicEnabled = 0;
}
Audio_SetPan

Modifie le panoramique de base d’une voix physique, puis réapplique les remplacements des effets actifs.

Syntaxe

c
void __stackcall Audio_SetPan(u8 ch, u8 pan);

Paramètres

ch

Identifiants de canal : 0=CH1, 1=CH2, 2=CH3, 3=CH4. Les API directes et les flux musicaux utilisent les mêmes identifiants.

pan

0=centre, 1=gauche, 2=droite, 3=muet. Les API d’effet interprètent les valeurs supérieures à 3, dont 0xFF, comme l’héritage du panoramique de base.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Un canal inconnu sélectionne CH4. Ici, pan hors de 0..3 coupe le son ; ce n’est pas le réglage d’héritage des API d’effet.

Exemple d’utilisation

c
// A sustained pulse moves left, right and center, then fades to a quieter level.
#include "gb_sound_example.h"
void main() {
    sound_begin("PAN AND VOLUME");
    Audio_SetMasterVolume(7,7);
    Audio_Ch1NoteOn(33,0xC0,2);
    Audio_SetPan(AUDIO_CHANNEL_CH1,AUDIO_PAN_LEFT);
    sound_result[0]=NR51;
    sound_wait(30);
    // Packed low two bits are CH1: 2 means right. Other channels remain centered.
    Audio_SetPanPacked(2);
    sound_result[1]=NR51;
    sound_wait(30);
    Audio_SetPanPacked(0);
    sound_result[2]=NR51;
    Audio_FadeToMasterVolume(1,1,5);
    sound_wait(30);
    sound_result[3]=NR50;
    sound_result[4]=Audio_FadeActive;
    sound_wait(30);
    // Cancel halfway through a rise: retain volume 4 instead of reaching 7.
    Audio_FadeToMasterVolume(7,7,5);
    sound_wait(15);
    Audio_CancelMasterVolumeFade();
    sound_result[5]=NR50;
    sound_wait(30);
    sound_result[6]=NR50;
    // A zero fade interval sets the target immediately. Level zero is not mute.
    Audio_FadeToMasterVolume(0,0,0);
    sound_result[7]=NR50;
    sound_wait(30);
    Audio_StopChannel(AUDIO_CHANNEL_CH1);
    sound_wait(15);
    sound_end();
}

Résultat attendu

A4 passe à gauche, à droite puis au centre. Au centre, le niveau descend de 7 à 1, puis remonte à 4 et s’y maintient. Le niveau 0 reste faiblement audible ; arrêter le canal produit le silence. Un changement de routage peut laisser un transitoire de filtre qui décroît.

Audio_SetPan: DMG
DMG
Audio_SetPan: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_mix.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-mix.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:129

Notes de déclaration (texte source)
Update the base pan for a physical channel and reapply active effect overrides.
Unknown channel IDs select CH4; unsupported pan values mute the selected channel.

kitaqgb/lib/audio.c:558

c
void __stackcall Audio_SetPan(u8 ch, u8 pan) {
    u8 r_bit;
    u8 l_bit;
    u8 mask;

    if (ch == AUDIO_CHANNEL_CH1) {
        r_bit = 0x01;
        l_bit = 0x10;
    } else if (ch == AUDIO_CHANNEL_CH2) {
        r_bit = 0x02;
        l_bit = 0x20;
    } else if (ch == AUDIO_CHANNEL_CH3) {
        r_bit = 0x04;
        l_bit = 0x40;
    } else {
        r_bit = 0x08;
        l_bit = 0x80;
    }

    mask = (u8)(l_bit | r_bit);
    Audio_Pan = (u8)(Audio_Pan & (u8)~mask);

    if (pan == AUDIO_PAN_CENTER) Audio_Pan = (u8)(Audio_Pan | mask);
    else if (pan == AUDIO_PAN_LEFT) Audio_Pan = (u8)(Audio_Pan | l_bit);
    else if (pan == AUDIO_PAN_RIGHT) Audio_Pan = (u8)(Audio_Pan | r_bit);

    Audio_UpdateNR51();
}
Audio_SetPanPacked

Décompacte quatre panoramiques de base depuis un octet et met à jour NR51 une seule fois.

Syntaxe

c
void __stackcall Audio_SetPanPacked(u8 packed);

Paramètres

packed

Deux bits par canal physique : CH1 bits 0..1, CH2 2..3, CH3 4..5, CH4 6..7. Chaque champ utilise les valeurs de panoramique.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Exemple d’utilisation

c
// A sustained pulse moves left, right and center, then fades to a quieter level.
#include "gb_sound_example.h"
void main() {
    sound_begin("PAN AND VOLUME");
    Audio_SetMasterVolume(7,7);
    Audio_Ch1NoteOn(33,0xC0,2);
    Audio_SetPan(AUDIO_CHANNEL_CH1,AUDIO_PAN_LEFT);
    sound_result[0]=NR51;
    sound_wait(30);
    // Packed low two bits are CH1: 2 means right. Other channels remain centered.
    Audio_SetPanPacked(2);
    sound_result[1]=NR51;
    sound_wait(30);
    Audio_SetPanPacked(0);
    sound_result[2]=NR51;
    Audio_FadeToMasterVolume(1,1,5);
    sound_wait(30);
    sound_result[3]=NR50;
    sound_result[4]=Audio_FadeActive;
    sound_wait(30);
    // Cancel halfway through a rise: retain volume 4 instead of reaching 7.
    Audio_FadeToMasterVolume(7,7,5);
    sound_wait(15);
    Audio_CancelMasterVolumeFade();
    sound_result[5]=NR50;
    sound_wait(30);
    sound_result[6]=NR50;
    // A zero fade interval sets the target immediately. Level zero is not mute.
    Audio_FadeToMasterVolume(0,0,0);
    sound_result[7]=NR50;
    sound_wait(30);
    Audio_StopChannel(AUDIO_CHANNEL_CH1);
    sound_wait(15);
    sound_end();
}

Résultat attendu

A4 passe à gauche, à droite puis au centre. Au centre, le niveau descend de 7 à 1, puis remonte à 4 et s’y maintient. Le niveau 0 reste faiblement audible ; arrêter le canal produit le silence. Un changement de routage peut laisser un transitoire de filtre qui décroît.

Audio_SetPanPacked: DMG
DMG
Audio_SetPanPacked: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_mix.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-mix.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:132

Notes de déclaration (texte source)
Two bits per channel (CH1 in bits 0-1): center, left, right, mute.
Applies all four positions with one NR51 update for sequencer automation.

kitaqgb/lib/audio.c:589

c
void __stackcall Audio_SetPanPacked(u8 packed) {
    u8 mix = 0;
    u8 pan = (u8)(packed & 3);
    if (pan == AUDIO_PAN_CENTER) mix = (u8)(mix | 0x11);
    else if (pan == AUDIO_PAN_LEFT) mix = (u8)(mix | 0x10);
    else if (pan == AUDIO_PAN_RIGHT) mix = (u8)(mix | 0x01);
    pan = (u8)((packed >> 2) & 3);
    if (pan == AUDIO_PAN_CENTER) mix = (u8)(mix | 0x22);
    else if (pan == AUDIO_PAN_LEFT) mix = (u8)(mix | 0x20);
    else if (pan == AUDIO_PAN_RIGHT) mix = (u8)(mix | 0x02);
    pan = (u8)((packed >> 4) & 3);
    if (pan == AUDIO_PAN_CENTER) mix = (u8)(mix | 0x44);
    else if (pan == AUDIO_PAN_LEFT) mix = (u8)(mix | 0x40);
    else if (pan == AUDIO_PAN_RIGHT) mix = (u8)(mix | 0x04);
    pan = (u8)((packed >> 6) & 3);
    if (pan == AUDIO_PAN_CENTER) mix = (u8)(mix | 0x88);
    else if (pan == AUDIO_PAN_LEFT) mix = (u8)(mix | 0x80);
    else if (pan == AUDIO_PAN_RIGHT) mix = (u8)(mix | 0x08);
    Audio_Pan = mix;
    Audio_UpdateNR51();
}
Audio_SetPaused

Coupe le son en pause tout en conservant les positions musique/effets. La reprise redéclenche les notes admissibles de CH1, CH2 et CH4.

Syntaxe

c
void __stackcall Audio_SetPaused(u8 on);

Paramètres

on

Zéro désactive, non-zéro active. Consultez la description pour distinguer mise en sourdine et suspension des mises à jour.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Incluez audio_hwregs_gb.c avant audio.c et appelez Audio_Init au démarrage. Appelez Audio_Update exactement une fois par image, à environ 59,7 Hz. La lecture du flux modifie temporairement le mappage ROM ; ne réentrez pas dans ce pilote depuis une interruption.

Cette routine ne redéclenche pas CH3. Les effets continuent lors d’une mise à jour ultérieure. Les appels directs de note peuvent encore sonner pendant la pause.

Exemple d’utilisation

c
// Original two-note phrase: pause preserves the cursor; the enable gate does not.
#include "gb_sound_example.h"
__prg_rom u8 song[]={
    AUDIO_CMD_SET_INST,AUDIO_STREAM_CHANNEL_CH1,2,0xC0,
    AUDIO_CMD_NOTE,AUDIO_STREAM_CHANNEL_CH1,33,AUDIO_CMD_WAIT,59,
    AUDIO_CMD_NOTE,AUDIO_STREAM_CHANNEL_CH1,40,AUDIO_CMD_WAIT,59,
    AUDIO_CMD_LOOP
};
void main() {
    u8 delay;
    sound_begin("MUSIC PAUSE GATE");
    Audio_SetMasterVolume(3,3);
    Audio_PlayMusic(0,song);
    sound_wait(30);
    delay=Audio_Delay;
    Audio_SetPaused(1);
    sound_wait(30);
    sound_result[0]=(u8)(Audio_Delay==delay);
    sound_result[1]=Audio_Paused;
    Audio_SetPaused(0);
    sound_wait(30);
    sound_result[2]=Audio_Paused;
    // Disabling suppresses note writes; the next 30 updates still consume data.
    Audio_SetMusicEnabled(0);
    sound_wait(30);
    sound_result[3]=Audio_Delay;
    sound_result[4]=Audio_MusicEnabled;
    // Explicitly stop the sounding channel while leaving the stream running.
    Audio_StopChannel(AUDIO_CHANNEL_CH1);
    sound_wait(30);
    Audio_SetMusicEnabled(1);
    sound_wait(30);
    Audio_StopMusic();
    sound_result[5]=Audio_PlayingMusic;
    sound_wait(30);
    sound_end();
}

Résultat attendu

Écoutez une note, le silence de pause, la reprise, une note maintenue lorsque la musique est désactivée, le silence explicite du canal, la note suivante après réactivation, puis l’arrêt. La RAM confirme aussi que 30 mises à jour en pause préservent delay, tandis que la simple désactivation le fait avancer jusqu’à 30.

Audio_SetPaused: DMG
DMG
Audio_SetPaused: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_music.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-music.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:90

Notes de déclaration (texte source)
On pause entry, silence hardware while retaining cursors. On resume, retrigger
eligible legacy CH1, CH2 and CH4 notes; CH3 is not retriggered here. Updates still
advance master fades while paused, and effect playback resumes on a later update.

kitaqgb/lib/audio.c:1010

c
void __stackcall Audio_SetPaused(u8 on) {
    if (on != 0) {
        if (Audio_Paused == 0) {
            Audio_Paused = 1;
            Audio_SilenceAll();
        }
    } else {
        if (Audio_Paused != 0) {
            Audio_Paused = 0;
            if (Audio_PlayingMusic != 0 && Audio_MusicEnabled != 0) {
                if ((Audio_LastChMask & AUDIO_RESUME_CH1) != 0 && Audio_EffectPointer == 0) {
                    Audio_Ch1NoteOn(Audio_LastCh1Note, Audio_Ch1Env, Audio_Ch1Duty);
                }
                if ((Audio_LastChMask & AUDIO_RESUME_CH2) != 0) {
                    Audio_Ch2NoteOn(Audio_LastCh2Note, Audio_Ch2Env, Audio_Ch2Duty);
                }
                if ((Audio_LastChMask & AUDIO_RESUME_CH4) != 0) {
                    Audio_Ch4NoteOn(Audio_LastCh4Param, Audio_Ch4Env);
                }
            }
        }
    }
}
Audio_SetSfxEnabled

Autorise ou bloque les écritures de notes d’effet ; la désactivation libère aussi les emplacements d’effet.

Syntaxe

c
void __stackcall Audio_SetSfxEnabled(u8 on);

Paramètres

on

Zéro désactive, non-zéro active. Consultez la description pour distinguer mise en sourdine et suspension des mises à jour.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Dans la configuration ordinaire, la libération d’un effet coupe CH3. Elle coupe CH1 si la musique est arrêtée, mais ne rejoue pas automatiquement une ancienne note lorsque la musique tourne. Avec AUDIO_VBLANK_SFX_RESTORE, elle demande la restauration par l’ISR.

Démarrer alors que les effets sont désactivés peut enregistrer un flux, mais les mises à jour suppriment ses écritures de notes. Activez les effets avant de demander une lecture audible.

Exemple d’utilisation

c
// Each pair lasts one update. Priority controls replacement within each slot.
#include "gb_sound_example.h"
#pragma bank 2
__prg_rom u8 effect[]={33,0xC0,33,0xC0,33,0xC0,33,0xC0,33,0xC0,33,0xC0,
    40,0xC0,40,0xC0,40,0xC0,40,0xC0,40,0xC0,40,0xC0,0};
__prg_rom u8 wave_effect[]={AUDIO_SFX_CH3_MARKER,
    33,0x20,33,0x20,33,0x20,33,0x20,33,0x20,33,0x20,
    40,0x20,40,0x20,40,0x20,40,0x20,40,0x20,40,0x20,0};
#pragma bank 0
void main() {
    sound_begin("BANKED SOUND EFFECT");
    Audio_SetMasterVolume(3,3);
    // Read the marker in bank 2 while restoring the caller's original mapping.
    Audio_PlaySFXPannedBanked(2,effect,5,AUDIO_PAN_LEFT);
    sound_result[0]=Audio_EffectPriority;
    Audio_PlaySFXBanked(2,effect,4);
    sound_result[1]=Audio_EffectPriority;
    sound_wait(30);
    Audio_PlaySFXPannedBanked(2,wave_effect,5,AUDIO_PAN_RIGHT);
    sound_result[2]=Audio_EffectPriority3;
    sound_wait(30);
    // Implicit-bank entry points capture bank 2; the service restores bank 1.
    __bankswitch(2);
    Audio_PlaySFX(effect,5);
    __bankswitch(1);
    sound_result[3]=Audio_EffectBank;
    sound_wait(30);
    __bankswitch(2);
    Audio_PlaySFXPanned(effect,5,AUDIO_PAN_RIGHT);
    __bankswitch(1);
    sound_wait(6);
    Audio_StopSfx();
    sound_result[4]=(u8)(Audio_EffectPointer==0);
    sound_wait(24);
    // Disabling effects releases current owners; re-enable before the next request.
    Audio_PlaySFXBanked(2,effect,5);
    sound_wait(6);
    Audio_SetSfxEnabled(0);
    sound_result[5]=Audio_SfxEnabled;
    sound_result[6]=(u8)(Audio_EffectPointer==0);
    sound_wait(24);
    Audio_SetSfxEnabled(1);
    Audio_PlaySFXBanked(2,effect,5);
    sound_wait(30);
    sound_result[7]=Audio_SfxEnabled;
    sound_end();
}

Résultat attendu

Les données de la banque 2 jouent une courte montée d’impulsion à gauche, un effet d’onde à droite puis une impulsion centrée. Les exemples suivants arrêtent tôt une impulsion droite, désactivent un effet puis réactivent la lecture. Une requête de priorité 4 ne peut pas remplacer la priorité 5.

Audio_SetSfxEnabled: DMG
DMG
Audio_SetSfxEnabled: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_sfx.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-sfx.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:117

Notes de déclaration (texte source)
Enable effect note writes, or disable them and release both effect streams.
Disabling follows Audio_StopSfx recovery rules rather than silencing all channels.

kitaqgb/lib/audio.c:505

c
void __stackcall Audio_SetSfxEnabled(u8 on) {
    if (on != 0) {
        Audio_SfxEnabled = 1;
    } else {
        Audio_SfxEnabled = 0;
        Audio_StopSfx();
    }
}
Audio_StopChannel

Arrête une voix physique et retire sa note musicale du masque de reprise.

Syntaxe

c
void __stackcall Audio_StopChannel(u8 ch);

Paramètres

ch

Identifiants de canal : 0=CH1, 1=CH2, 2=CH3, 3=CH4. Les API directes et les flux musicaux utilisent les mêmes identifiants.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

CH1/CH3 effacent aussi leur emplacement d’effet. Hors de 0..3, aucun effet. Les notes mémorisées par VBlank sont gérées séparément.

Exemple d’utilisation

c
// Four isolated voices, each lasting 30 frames, separated by 15 silent frames.
#include "gb_sound_example.h"
void main() {
    sound_begin("FOUR SOUND CHANNELS");
    Audio_SetMasterVolume(3,3);
    // CH1: A4, 50% duty, fixed envelope volume 12.
    Audio_SetCh1Duty(2);
    sound_result[0]=Audio_Ch1Duty;
    Audio_Ch1NoteOn(33,0xC0,Audio_Ch1Duty);
    sound_result[1]=NR12;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH1); sound_wait(15);
    // CH2: A4, 25% duty. Changing the cached duty takes effect on this trigger.
    Audio_SetCh2Duty(1);
    sound_result[2]=Audio_Ch2Duty;
    Audio_Ch2NoteOn(33,0xC0,Audio_Ch2Duty);
    sound_result[3]=NR22;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH2); sound_wait(15);
    // CH3: the initialized triangle wave, at 50% digital output level.
    Audio_SetCh3Level(AUDIO_CH3_LEVEL_50);
    sound_result[4]=Audio_Ch3Level;
    Audio_Ch3NoteOn(33,Audio_Ch3Level);
    sound_result[5]=NR32;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH3); sound_wait(15);
    // CH4: a sustained noise burst; param is NR43, not a pitched note number.
    Audio_SetCh4Param(0x35);
    sound_result[6]=Audio_Ch4Param;
    Audio_Ch4NoteOn(Audio_Ch4Param,0xC0);
    sound_result[7]=NR43;
    sound_wait(30); Audio_StopChannel(AUDIO_CHANNEL_CH4); sound_wait(15);
    sound_end();
}

Résultat attendu

Après environ une demi-seconde de silence, écoutez CH1 A4, CH2 A4, CH3 A3 puis le bruit. Chaque voix dure 30 images, avec des pauses de 15 images. SEQUENCE COMPLETE marque la fin du programme ; utilisez l’enregistrement pour apprécier le son.

Audio_StopChannel: DMG
DMG
Audio_StopChannel: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_channels.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-channels.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:110

Notes de déclaration (texte source)
Stop a physical channel and clear its legacy resume bit. CH1 also clears the
pulse effect stream; CH3 clears the wave effect stream. This is the legacy
channel API and does not clear a VBlank driver's independently latched notes.

kitaqgb/lib/audio.c:981

c
void __stackcall Audio_StopChannel(u8 ch) {
    if (ch == AUDIO_CHANNEL_CH1) {
        Audio_EffectPointer = 0;
        Audio_EffectPriority = 0;
        Audio_EffectBank = 0;
        Audio_EffectPan = AUDIO_PAN_INHERIT;
        Audio_LastChMask = (u8)(Audio_LastChMask & (u8)~AUDIO_RESUME_CH1);
        Audio_UpdateNR51();
        Audio_SilenceCh1();
    } else if (ch == AUDIO_CHANNEL_CH2) {
        Audio_LastChMask = (u8)(Audio_LastChMask & (u8)~AUDIO_RESUME_CH2);
        Audio_SilenceCh2();
    } else if (ch == AUDIO_CHANNEL_CH3) {
        Audio_EffectPointer3 = 0;
        Audio_EffectPriority3 = 0;
        Audio_EffectBank3 = 0;
        Audio_EffectPan3 = AUDIO_PAN_INHERIT;
        Audio_LastChMask = (u8)(Audio_LastChMask & (u8)~AUDIO_RESUME_CH3);
        Audio_UpdateNR51();
        Audio_Ch3Off();
    } else if (ch == AUDIO_CHANNEL_CH4) {
        Audio_LastChMask = (u8)(Audio_LastChMask & (u8)~AUDIO_RESUME_CH4);
        Audio_SilenceCh4();
    }
}
Audio_StopMusic

Efface la lecture du morceau et son masque de reprise, puis coupe immédiatement les quatre voix.

Syntaxe

c
void Audio_StopMusic();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Les pointeurs d’effet restent présents ; un Audio_Update ultérieur peut donc produire un effet. Appelez aussi Audio_StopSfx pour tout arrêter.

Exemple d’utilisation

c
// Original two-note phrase: pause preserves the cursor; the enable gate does not.
#include "gb_sound_example.h"
__prg_rom u8 song[]={
    AUDIO_CMD_SET_INST,AUDIO_STREAM_CHANNEL_CH1,2,0xC0,
    AUDIO_CMD_NOTE,AUDIO_STREAM_CHANNEL_CH1,33,AUDIO_CMD_WAIT,59,
    AUDIO_CMD_NOTE,AUDIO_STREAM_CHANNEL_CH1,40,AUDIO_CMD_WAIT,59,
    AUDIO_CMD_LOOP
};
void main() {
    u8 delay;
    sound_begin("MUSIC PAUSE GATE");
    Audio_SetMasterVolume(3,3);
    Audio_PlayMusic(0,song);
    sound_wait(30);
    delay=Audio_Delay;
    Audio_SetPaused(1);
    sound_wait(30);
    sound_result[0]=(u8)(Audio_Delay==delay);
    sound_result[1]=Audio_Paused;
    Audio_SetPaused(0);
    sound_wait(30);
    sound_result[2]=Audio_Paused;
    // Disabling suppresses note writes; the next 30 updates still consume data.
    Audio_SetMusicEnabled(0);
    sound_wait(30);
    sound_result[3]=Audio_Delay;
    sound_result[4]=Audio_MusicEnabled;
    // Explicitly stop the sounding channel while leaving the stream running.
    Audio_StopChannel(AUDIO_CHANNEL_CH1);
    sound_wait(30);
    Audio_SetMusicEnabled(1);
    sound_wait(30);
    Audio_StopMusic();
    sound_result[5]=Audio_PlayingMusic;
    sound_wait(30);
    sound_end();
}

Résultat attendu

Écoutez une note, le silence de pause, la reprise, une note maintenue lorsque la musique est désactivée, le silence explicite du canal, la note suivante après réactivation, puis l’arrêt. La RAM confirme aussi que 30 mises à jour en pause préservent delay, tandis que la simple désactivation le fait avancer jusqu’à 30.

Audio_StopMusic: DMG
DMG
Audio_StopMusic: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_music.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-music.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:86

Notes de déclaration (texte source)
Stop legacy music and clear its resume mask, then silence all physical channels.
Effect pointers remain active and may produce sound on a later update.

kitaqgb/lib/audio.c:952

c
void Audio_StopMusic() {
    Audio_PlayingMusic = 0;
    Audio_LastChMask = 0;
    Audio_SilenceAll();
}
Audio_StopSfx

Efface les deux flux d’effet et leurs panoramiques imposés, puis libère les canaux empruntés.

Syntaxe

c
void Audio_StopSfx();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Un effet consomme une paire (note,value) par mise à jour et se termine à note=0. value correspond à NR12 pour les effets d’impulsion, à NR32 pour CH3. Préfixez les données CH3 par 0xFF. Conservez le stockage jusqu’à la fin. Les priorités s’appliquent au sein d’un emplacement ; une priorité égale peut remplacer l’effet courant.

Dans la configuration ordinaire, la libération d’un effet coupe CH3. Elle coupe CH1 si la musique est arrêtée, mais ne rejoue pas automatiquement une ancienne note lorsque la musique tourne. Avec AUDIO_VBLANK_SFX_RESTORE, elle demande la restauration par l’ISR.

Exemple d’utilisation

c
// Each pair lasts one update. Priority controls replacement within each slot.
#include "gb_sound_example.h"
#pragma bank 2
__prg_rom u8 effect[]={33,0xC0,33,0xC0,33,0xC0,33,0xC0,33,0xC0,33,0xC0,
    40,0xC0,40,0xC0,40,0xC0,40,0xC0,40,0xC0,40,0xC0,0};
__prg_rom u8 wave_effect[]={AUDIO_SFX_CH3_MARKER,
    33,0x20,33,0x20,33,0x20,33,0x20,33,0x20,33,0x20,
    40,0x20,40,0x20,40,0x20,40,0x20,40,0x20,40,0x20,0};
#pragma bank 0
void main() {
    sound_begin("BANKED SOUND EFFECT");
    Audio_SetMasterVolume(3,3);
    // Read the marker in bank 2 while restoring the caller's original mapping.
    Audio_PlaySFXPannedBanked(2,effect,5,AUDIO_PAN_LEFT);
    sound_result[0]=Audio_EffectPriority;
    Audio_PlaySFXBanked(2,effect,4);
    sound_result[1]=Audio_EffectPriority;
    sound_wait(30);
    Audio_PlaySFXPannedBanked(2,wave_effect,5,AUDIO_PAN_RIGHT);
    sound_result[2]=Audio_EffectPriority3;
    sound_wait(30);
    // Implicit-bank entry points capture bank 2; the service restores bank 1.
    __bankswitch(2);
    Audio_PlaySFX(effect,5);
    __bankswitch(1);
    sound_result[3]=Audio_EffectBank;
    sound_wait(30);
    __bankswitch(2);
    Audio_PlaySFXPanned(effect,5,AUDIO_PAN_RIGHT);
    __bankswitch(1);
    sound_wait(6);
    Audio_StopSfx();
    sound_result[4]=(u8)(Audio_EffectPointer==0);
    sound_wait(24);
    // Disabling effects releases current owners; re-enable before the next request.
    Audio_PlaySFXBanked(2,effect,5);
    sound_wait(6);
    Audio_SetSfxEnabled(0);
    sound_result[5]=Audio_SfxEnabled;
    sound_result[6]=(u8)(Audio_EffectPointer==0);
    sound_wait(24);
    Audio_SetSfxEnabled(1);
    Audio_PlaySFXBanked(2,effect,5);
    sound_wait(30);
    sound_result[7]=Audio_SfxEnabled;
    sound_end();
}

Résultat attendu

Les données de la banque 2 jouent une courte montée d’impulsion à gauche, un effet d’onde à droite puis une impulsion centrée. Les exemples suivants arrêtent tôt une impulsion droite, désactivent un effet puis réactivent la lecture. Une requête de priorité 4 ne peut pas remplacer la priorité 5.

Audio_StopSfx: DMG
DMG
Audio_StopSfx: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_sfx.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-sfx.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:106

Notes de déclaration (texte source)
Clear both effect streams and their pan overrides. When not paused, release
borrowed channels through the configured legacy or VBlank recovery path.

kitaqgb/lib/audio.c:960

c
void Audio_StopSfx() {
    Audio_EffectPointer = 0;
    Audio_EffectPriority = 0;
    Audio_EffectBank = 0;
    Audio_EffectPointer3 = 0;
    Audio_EffectPriority3 = 0;
    Audio_EffectBank3 = 0;
    Audio_EffectPan = AUDIO_PAN_INHERIT;
    Audio_EffectPan3 = AUDIO_PAN_INHERIT;
    Audio_UpdateNR51();

    if (Audio_Paused != 0) return;
    Audio_ReleaseCh1AfterSfx();
    Audio_RestoreCh3FromMusic();
}
Audio_Update

Avance le fondu de volume d’un pas ; hors pause, traite ensuite les effets puis la musique.

Syntaxe

c
void Audio_Update();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

Incluez audio_hwregs_gb.c avant audio.c et appelez Audio_Init au démarrage. Appelez Audio_Update exactement une fois par image, à environ 59,7 Hz. La lecture du flux modifie temporairement le mappage ROM ; ne réentrez pas dans ce pilote depuis une interruption.

Les fondus continuent pendant la pause. La lecture de WAIT n est suivie de n appels d’attente ; la commande suivante arrive donc après n+1 mises à jour.

Exemple d’utilisation

c
// Original two-note phrase: pause preserves the cursor; the enable gate does not.
#include "gb_sound_example.h"
__prg_rom u8 song[]={
    AUDIO_CMD_SET_INST,AUDIO_STREAM_CHANNEL_CH1,2,0xC0,
    AUDIO_CMD_NOTE,AUDIO_STREAM_CHANNEL_CH1,33,AUDIO_CMD_WAIT,59,
    AUDIO_CMD_NOTE,AUDIO_STREAM_CHANNEL_CH1,40,AUDIO_CMD_WAIT,59,
    AUDIO_CMD_LOOP
};
void main() {
    u8 delay;
    sound_begin("MUSIC PAUSE GATE");
    Audio_SetMasterVolume(3,3);
    Audio_PlayMusic(0,song);
    sound_wait(30);
    delay=Audio_Delay;
    Audio_SetPaused(1);
    sound_wait(30);
    sound_result[0]=(u8)(Audio_Delay==delay);
    sound_result[1]=Audio_Paused;
    Audio_SetPaused(0);
    sound_wait(30);
    sound_result[2]=Audio_Paused;
    // Disabling suppresses note writes; the next 30 updates still consume data.
    Audio_SetMusicEnabled(0);
    sound_wait(30);
    sound_result[3]=Audio_Delay;
    sound_result[4]=Audio_MusicEnabled;
    // Explicitly stop the sounding channel while leaving the stream running.
    Audio_StopChannel(AUDIO_CHANNEL_CH1);
    sound_wait(30);
    Audio_SetMusicEnabled(1);
    sound_wait(30);
    Audio_StopMusic();
    sound_result[5]=Audio_PlayingMusic;
    sound_wait(30);
    sound_end();
}

Résultat attendu

Écoutez une note, le silence de pause, la reprise, une note maintenue lorsque la musique est désactivée, le silence explicite du canal, la note suivante après réactivation, puis l’arrêt. La RAM confirme aussi que 30 mises à jour en pause préservent delay, tandis que la simple désactivation le fait avancer jusqu’à 30.

Audio_Update: DMG
DMG
Audio_Update: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_music.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-music.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio.h:79

Notes de déclaration (texte source)
Advance the master fade first. Unless paused, service both effect streams
then the optional legacy music decoder. Call once per frame for frame-based timing.

kitaqgb/lib/audio.c:849

c
void Audio_Update() {
    Audio_UpdateFade();
    if (Audio_Paused != 0) return;

    Audio_ServiceSfx();
#ifndef AUDIO_EXCLUDE_LEGACY_MUSIC_SERVICE
    Audio_ServiceMusic();
#endif
}

audio_vblank.h — Lecture musicale par interruption VBlank

Traite la musique en VBlank, coordonne l’occupation des voix par les effets et fournit un hook par image. Ne faites pas aussi avancer le même morceau avec le décodeur musical ordinaire.

audio_vblank.c implémente __kq_vblank_vector ; n’installez pas un autre vecteur VBlank concurrent. L’exemple définit Audio_NoiseEffectActive, exclut le décodeur musical ordinaire et réserve Audio_Update aux effets et fondus. Masquez les interruptions lorsque vous modifiez les pointeurs de morceau ou l’état partagé.

Gardez les données musicales directes en ROM fixe ou dans une zone toujours visible par l’ISR. Un enregistrement contient cinq octets : delay, CH1, CH2, CH3, CH4. Dans les champs de note, 0xFF maintient la voix et 0xFD l’arrête. Dans delay, 0xFF termine la lecture et 0xFE boucle. Il s’agit de l’ordre des champs, pas des identifiants de canal. La file WRAM est un mode distinct ; fournissez des enregistrements complets de cinq octets avec AudioVBlank_QueueRefill.

AudioVBlank_DisableIrq

Efface seulement le bit VBlank de IE, sans modifier les autres sources d’interruption ni le son.

Syntaxe

c
void AudioVBlank_DisableIrq();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

audio_vblank.c implémente __kq_vblank_vector ; n’installez pas un autre vecteur VBlank concurrent. L’exemple définit Audio_NoiseEffectActive, exclut le décodeur musical ordinaire et réserve Audio_Update aux effets et fondus. Masquez les interruptions lorsque vous modifiez les pointeurs de morceau ou l’état partagé.

Gardez les données musicales directes en ROM fixe ou dans une zone toujours visible par l’ISR. Un enregistrement contient cinq octets : delay, CH1, CH2, CH3, CH4. Dans les champs de note, 0xFF maintient la voix et 0xFD l’arrête. Dans delay, 0xFF termine la lecture et 0xFE boucle. Il s’agit de l’ordre des champs, pas des identifiants de canal. La file WRAM est un mode distinct ; fournissez des enregistrements complets de cinq octets avec AudioVBlank_QueueRefill.

Exemple d’utilisation

c
// Direct fixed-bank music with an actual VBlank ISR and a counting frame hook.
#define SOUND_VBLANK
#include "gb_sound_example.h"
__wram u8 hook_count;
__prg_rom u8 irq_song[]={30,33,0xFF,0xFF,0xFF,30,40,0xFF,0xFF,0xFF,0xFE};
void frame_hook() { hook_count++; }
void main() {
    u8 before;
    sound_begin("VBLANK MUSIC GATES");
    Audio_NoiseEffectActive=0;
    AudioVBlank_Init();
    sound_result[0]=AudioVBlank_MusicPlaying;
    AudioVBlank_Ch1Envelope=0xC0;
    Audio_SetMasterVolume(3,3);
    hook_count=0; AudioVBlank_FrameHook=frame_hook;
    AudioVBlank_SetMusic(irq_song);
    AudioVBlank_Play();
    AudioVBlank_EnableIrq();
    sound_wait(45);
    // Disable music processing while the hook and current note remain active.
    __asm { DI }
    AudioVBlank_SetEnabled(0); before=hook_count;
    __asm { EI }
    sound_wait(30);
    sound_result[1]=(u8)(hook_count!=before);
    __asm { DI }
    AudioVBlank_Stop();
    __asm { EI }
    sound_wait(30);
    __asm { DI }
    AudioVBlank_SetEnabled(1); AudioVBlank_PlayMusic(irq_song);
    __asm { EI }
    sound_wait(45);
    AudioVBlank_DisableIrq();
    before=hook_count;
    sound_wait(30);
    sound_result[2]=(u8)(hook_count==before);
    sound_result[3]=(u8)(AudioVBlank_IE&1);
    AudioVBlank_Stop(); sound_wait(30);
    sound_end();
}

Résultat attendu

L’ISR joue un morceau de deux notes. Comparez la suspension des mises à jour musicales, qui conserve le son, Stop, qui le coupe, et la désactivation IRQ après redémarrage, qui conserve aussi le son. La RAM vérifie que le hook tourne musique désactivée et s’arrête IRQ désactivée.

AudioVBlank_DisableIrq: DMG
DMG
AudioVBlank_DisableIrq: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_vblank.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-vblank.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:118

Notes de déclaration (texte source)
Clear only the VBlank bit in IE. Other interrupt sources and current sound remain unchanged.

kitaqgb/lib/audio_vblank_control.inc:129

c
void AudioVBlank_DisableIrq()
{
    AudioVBlank_IE = (u8)(AudioVBlank_IE & 0xFE);
}
AudioVBlank_EnableIrq

Active le bit VBlank de IE et exécute EI pour autoriser globalement les interruptions CPU.

Syntaxe

c
void AudioVBlank_EnableIrq();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

audio_vblank.c implémente __kq_vblank_vector ; n’installez pas un autre vecteur VBlank concurrent. L’exemple définit Audio_NoiseEffectActive, exclut le décodeur musical ordinaire et réserve Audio_Update aux effets et fondus. Masquez les interruptions lorsque vous modifiez les pointeurs de morceau ou l’état partagé.

Gardez les données musicales directes en ROM fixe ou dans une zone toujours visible par l’ISR. Un enregistrement contient cinq octets : delay, CH1, CH2, CH3, CH4. Dans les champs de note, 0xFF maintient la voix et 0xFD l’arrête. Dans delay, 0xFF termine la lecture et 0xFE boucle. Il s’agit de l’ordre des champs, pas des identifiants de canal. La file WRAM est un mode distinct ; fournissez des enregistrements complets de cinq octets avec AudioVBlank_QueueRefill.

Exemple d’utilisation

c
// Direct fixed-bank music with an actual VBlank ISR and a counting frame hook.
#define SOUND_VBLANK
#include "gb_sound_example.h"
__wram u8 hook_count;
__prg_rom u8 irq_song[]={30,33,0xFF,0xFF,0xFF,30,40,0xFF,0xFF,0xFF,0xFE};
void frame_hook() { hook_count++; }
void main() {
    u8 before;
    sound_begin("VBLANK MUSIC GATES");
    Audio_NoiseEffectActive=0;
    AudioVBlank_Init();
    sound_result[0]=AudioVBlank_MusicPlaying;
    AudioVBlank_Ch1Envelope=0xC0;
    Audio_SetMasterVolume(3,3);
    hook_count=0; AudioVBlank_FrameHook=frame_hook;
    AudioVBlank_SetMusic(irq_song);
    AudioVBlank_Play();
    AudioVBlank_EnableIrq();
    sound_wait(45);
    // Disable music processing while the hook and current note remain active.
    __asm { DI }
    AudioVBlank_SetEnabled(0); before=hook_count;
    __asm { EI }
    sound_wait(30);
    sound_result[1]=(u8)(hook_count!=before);
    __asm { DI }
    AudioVBlank_Stop();
    __asm { EI }
    sound_wait(30);
    __asm { DI }
    AudioVBlank_SetEnabled(1); AudioVBlank_PlayMusic(irq_song);
    __asm { EI }
    sound_wait(45);
    AudioVBlank_DisableIrq();
    before=hook_count;
    sound_wait(30);
    sound_result[2]=(u8)(hook_count==before);
    sound_result[3]=(u8)(AudioVBlank_IE&1);
    AudioVBlank_Stop(); sound_wait(30);
    sound_end();
}

Résultat attendu

L’ISR joue un morceau de deux notes. Comparez la suspension des mises à jour musicales, qui conserve le son, Stop, qui le coupe, et la désactivation IRQ après redémarrage, qui conserve aussi le son. La RAM vérifie que le hook tourne musique désactivée et s’arrête IRQ désactivée.

AudioVBlank_EnableIrq: DMG
DMG
AudioVBlank_EnableIrq: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_vblank.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-vblank.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:116

Notes de déclaration (texte source)
Enable the VBlank source in IE and execute EI, enabling CPU interrupts globally.
Install the correct interrupt vector and initialize driver state first.

kitaqgb/lib/audio_vblank_control.inc:122

c
void AudioVBlank_EnableIrq()
{
    AudioVBlank_IE = (u8)(AudioVBlank_IE | 0x01);
    __asm { EI }
}
AudioVBlank_Init

Initialise l’état musical VBlank, la file, les instruments et le hook. N’initialise pas l’APU et ne masque pas les interruptions.

Syntaxe

c
void AudioVBlank_Init();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

audio_vblank.c implémente __kq_vblank_vector ; n’installez pas un autre vecteur VBlank concurrent. L’exemple définit Audio_NoiseEffectActive, exclut le décodeur musical ordinaire et réserve Audio_Update aux effets et fondus. Masquez les interruptions lorsque vous modifiez les pointeurs de morceau ou l’état partagé.

Gardez les données musicales directes en ROM fixe ou dans une zone toujours visible par l’ISR. Un enregistrement contient cinq octets : delay, CH1, CH2, CH3, CH4. Dans les champs de note, 0xFF maintient la voix et 0xFD l’arrête. Dans delay, 0xFF termine la lecture et 0xFE boucle. Il s’agit de l’ordre des champs, pas des identifiants de canal. La file WRAM est un mode distinct ; fournissez des enregistrements complets de cinq octets avec AudioVBlank_QueueRefill.

Exemple d’utilisation

c
// Direct fixed-bank music with an actual VBlank ISR and a counting frame hook.
#define SOUND_VBLANK
#include "gb_sound_example.h"
__wram u8 hook_count;
__prg_rom u8 irq_song[]={30,33,0xFF,0xFF,0xFF,30,40,0xFF,0xFF,0xFF,0xFE};
void frame_hook() { hook_count++; }
void main() {
    u8 before;
    sound_begin("VBLANK MUSIC GATES");
    Audio_NoiseEffectActive=0;
    AudioVBlank_Init();
    sound_result[0]=AudioVBlank_MusicPlaying;
    AudioVBlank_Ch1Envelope=0xC0;
    Audio_SetMasterVolume(3,3);
    hook_count=0; AudioVBlank_FrameHook=frame_hook;
    AudioVBlank_SetMusic(irq_song);
    AudioVBlank_Play();
    AudioVBlank_EnableIrq();
    sound_wait(45);
    // Disable music processing while the hook and current note remain active.
    __asm { DI }
    AudioVBlank_SetEnabled(0); before=hook_count;
    __asm { EI }
    sound_wait(30);
    sound_result[1]=(u8)(hook_count!=before);
    __asm { DI }
    AudioVBlank_Stop();
    __asm { EI }
    sound_wait(30);
    __asm { DI }
    AudioVBlank_SetEnabled(1); AudioVBlank_PlayMusic(irq_song);
    __asm { EI }
    sound_wait(45);
    AudioVBlank_DisableIrq();
    before=hook_count;
    sound_wait(30);
    sound_result[2]=(u8)(hook_count==before);
    sound_result[3]=(u8)(AudioVBlank_IE&1);
    AudioVBlank_Stop(); sound_wait(30);
    sound_end();
}

Résultat attendu

L’ISR joue un morceau de deux notes. Comparez la suspension des mises à jour musicales, qui conserve le son, Stop, qui le coupe, et la désactivation IRQ après redémarrage, qui conserve aussi le son. La RAM vérifie que le hook tourne musique désactivée et s’arrête IRQ désactivée.

AudioVBlank_Init: DMG
DMG
AudioVBlank_Init: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_vblank.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-vblank.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:85

Notes de déclaration (texte source)
Reset software playback state, queue counters, instruments and the frame hook.
Call before enabling this ISR; the routine does not mask interrupts or
initialize the APU registers and cannot synchronize with an active handler.

kitaqgb/lib/audio_vblank_control.inc:6

c
void AudioVBlank_Init()
{
    AudioVBlank_MusicEnabled = 1;
    AudioVBlank_MusicPlaying = 0;
    AudioVBlank_MusicDelay = 0;
    AudioVBlank_MusicStart = 0;
    AudioVBlank_MusicPointer = 0;
    AudioVBlank_MusicLoopPoint = 0;
    AudioVBlank_Step = 0;
    AudioVBlank_Ch2Note = AUDIO_VBLANK_REST;
    AudioVBlank_Ch1Note = AUDIO_VBLANK_REST;
    AudioVBlank_Ch3Note = AUDIO_VBLANK_REST;
    AudioVBlank_Ch2LatchedNote = AUDIO_VBLANK_STOP;
    AudioVBlank_Ch1LatchedNote = AUDIO_VBLANK_STOP;
    AudioVBlank_Ch3LatchedNote = AUDIO_VBLANK_STOP;
    AudioVBlank_RestoreCh1Pending = 0;
    AudioVBlank_RestoreCh3Pending = 0;
    AudioVBlank_Ch4Param = AUDIO_VBLANK_REST;
    AudioVBlank_Ch1Envelope = 0xF1;
    AudioVBlank_Ch2Envelope = 0xF2;
    AudioVBlank_Ch4Envelope = 0xF1;
    AudioVBlank_Ch1Duty = 0x80;
    AudioVBlank_Ch2Duty = 0x80;
    AudioVBlank_Ch1Sweep = 0x00;
    AudioVBlank_Ch3Level = 0x20;
    AudioVBlank_ControlCommand = 0;
    AudioVBlank_ControlArg0 = 0;
    AudioVBlank_ControlArg1 = 0;
    AudioVBlank_ControlArg2 = 0;
    AudioVBlank_QueueMode = 0;
    AudioVBlank_QueueReadIndex = 0;
    AudioVBlank_QueueWriteIndex = 0;
    AudioVBlank_QueueCount = 0;
    AudioVBlank_QueueUnderruns = 0;
    AudioVBlank_FrameHook = 0;
}
AudioVBlank_Play

Redémarre le morceau choisi depuis le début et quitte le mode file. Un morceau NULL arrête la lecture.

Syntaxe

c
void AudioVBlank_Play();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

audio_vblank.c implémente __kq_vblank_vector ; n’installez pas un autre vecteur VBlank concurrent. L’exemple définit Audio_NoiseEffectActive, exclut le décodeur musical ordinaire et réserve Audio_Update aux effets et fondus. Masquez les interruptions lorsque vous modifiez les pointeurs de morceau ou l’état partagé.

Gardez les données musicales directes en ROM fixe ou dans une zone toujours visible par l’ISR. Un enregistrement contient cinq octets : delay, CH1, CH2, CH3, CH4. Dans les champs de note, 0xFF maintient la voix et 0xFD l’arrête. Dans delay, 0xFF termine la lecture et 0xFE boucle. Il s’agit de l’ordre des champs, pas des identifiants de canal. La file WRAM est un mode distinct ; fournissez des enregistrements complets de cinq octets avec AudioVBlank_QueueRefill.

Exemple d’utilisation

c
// Direct fixed-bank music with an actual VBlank ISR and a counting frame hook.
#define SOUND_VBLANK
#include "gb_sound_example.h"
__wram u8 hook_count;
__prg_rom u8 irq_song[]={30,33,0xFF,0xFF,0xFF,30,40,0xFF,0xFF,0xFF,0xFE};
void frame_hook() { hook_count++; }
void main() {
    u8 before;
    sound_begin("VBLANK MUSIC GATES");
    Audio_NoiseEffectActive=0;
    AudioVBlank_Init();
    sound_result[0]=AudioVBlank_MusicPlaying;
    AudioVBlank_Ch1Envelope=0xC0;
    Audio_SetMasterVolume(3,3);
    hook_count=0; AudioVBlank_FrameHook=frame_hook;
    AudioVBlank_SetMusic(irq_song);
    AudioVBlank_Play();
    AudioVBlank_EnableIrq();
    sound_wait(45);
    // Disable music processing while the hook and current note remain active.
    __asm { DI }
    AudioVBlank_SetEnabled(0); before=hook_count;
    __asm { EI }
    sound_wait(30);
    sound_result[1]=(u8)(hook_count!=before);
    __asm { DI }
    AudioVBlank_Stop();
    __asm { EI }
    sound_wait(30);
    __asm { DI }
    AudioVBlank_SetEnabled(1); AudioVBlank_PlayMusic(irq_song);
    __asm { EI }
    sound_wait(45);
    AudioVBlank_DisableIrq();
    before=hook_count;
    sound_wait(30);
    sound_result[2]=(u8)(hook_count==before);
    sound_result[3]=(u8)(AudioVBlank_IE&1);
    AudioVBlank_Stop(); sound_wait(30);
    sound_end();
}

Résultat attendu

L’ISR joue un morceau de deux notes. Comparez la suspension des mises à jour musicales, qui conserve le son, Stop, qui le coupe, et la désactivation IRQ après redémarrage, qui conserve aussi le son. La RAM vérifie que le hook tourne musique désactivée et s’arrête IRQ désactivée.

AudioVBlank_Play: DMG
DMG
AudioVBlank_Play: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_vblank.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-vblank.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:103

Notes de déclaration (texte source)
Restart the selected direct song at its beginning, leaving queue mode.
A null song invokes Stop; this does not enable the music or IRQ gates.

kitaqgb/lib/audio_vblank_control.inc:58

c
void AudioVBlank_Play()
{
    if (AudioVBlank_MusicStart == 0) {
        AudioVBlank_Stop();
        return;
    }
    AudioVBlank_MusicPointer = AudioVBlank_MusicStart;
    AudioVBlank_MusicLoopPoint = AudioVBlank_MusicStart;
    AudioVBlank_MusicDelay = 0;
    AudioVBlank_Step = 0;
    AudioVBlank_QueueMode = 0;
    AudioVBlank_MusicPlaying = 1;
}
AudioVBlank_PlayMusic

Sélectionne un morceau en lecture directe et prépare sa lecture depuis le début.

Syntaxe

c
void __stackcall AudioVBlank_PlayMusic(u8 *song);

Paramètres

song

Adresse de début du morceau. Le pilote emprunte le tableau, qui doit rester lisible pendant toute la lecture.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

audio_vblank.c implémente __kq_vblank_vector ; n’installez pas un autre vecteur VBlank concurrent. L’exemple définit Audio_NoiseEffectActive, exclut le décodeur musical ordinaire et réserve Audio_Update aux effets et fondus. Masquez les interruptions lorsque vous modifiez les pointeurs de morceau ou l’état partagé.

Gardez les données musicales directes en ROM fixe ou dans une zone toujours visible par l’ISR. Un enregistrement contient cinq octets : delay, CH1, CH2, CH3, CH4. Dans les champs de note, 0xFF maintient la voix et 0xFD l’arrête. Dans delay, 0xFF termine la lecture et 0xFE boucle. Il s’agit de l’ordre des champs, pas des identifiants de canal. La file WRAM est un mode distinct ; fournissez des enregistrements complets de cinq octets avec AudioVBlank_QueueRefill.

Exemple d’utilisation

c
// Direct fixed-bank music with an actual VBlank ISR and a counting frame hook.
#define SOUND_VBLANK
#include "gb_sound_example.h"
__wram u8 hook_count;
__prg_rom u8 irq_song[]={30,33,0xFF,0xFF,0xFF,30,40,0xFF,0xFF,0xFF,0xFE};
void frame_hook() { hook_count++; }
void main() {
    u8 before;
    sound_begin("VBLANK MUSIC GATES");
    Audio_NoiseEffectActive=0;
    AudioVBlank_Init();
    sound_result[0]=AudioVBlank_MusicPlaying;
    AudioVBlank_Ch1Envelope=0xC0;
    Audio_SetMasterVolume(3,3);
    hook_count=0; AudioVBlank_FrameHook=frame_hook;
    AudioVBlank_SetMusic(irq_song);
    AudioVBlank_Play();
    AudioVBlank_EnableIrq();
    sound_wait(45);
    // Disable music processing while the hook and current note remain active.
    __asm { DI }
    AudioVBlank_SetEnabled(0); before=hook_count;
    __asm { EI }
    sound_wait(30);
    sound_result[1]=(u8)(hook_count!=before);
    __asm { DI }
    AudioVBlank_Stop();
    __asm { EI }
    sound_wait(30);
    __asm { DI }
    AudioVBlank_SetEnabled(1); AudioVBlank_PlayMusic(irq_song);
    __asm { EI }
    sound_wait(45);
    AudioVBlank_DisableIrq();
    before=hook_count;
    sound_wait(30);
    sound_result[2]=(u8)(hook_count==before);
    sound_result[3]=(u8)(AudioVBlank_IE&1);
    AudioVBlank_Stop(); sound_wait(30);
    sound_end();
}

Résultat attendu

L’ISR joue un morceau de deux notes. Comparez la suspension des mises à jour musicales, qui conserve le son, Stop, qui le coupe, et la désactivation IRQ après redémarrage, qui conserve aussi le son. La RAM vérifie que le hook tourne musique désactivée et s’arrête IRQ désactivée.

AudioVBlank_PlayMusic: DMG
DMG
AudioVBlank_PlayMusic: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_vblank.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-vblank.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:105

Notes de déclaration (texte source)
Select and restart a directly addressed song. This is not the banked WRAM-queue path.

kitaqgb/lib/audio_vblank_control.inc:73

c
void __stackcall AudioVBlank_PlayMusic(u8 *song)
{
    AudioVBlank_SetMusic(song);
    AudioVBlank_Play();
}
AudioVBlank_QueuePlay

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Active la lecture si le mode file est actif et si au moins un enregistrement est disponible. Conserve les curseurs, le délai, l’activation de la musique et l’état de pause. Réinitialisez et préremplissez la file avant de lancer un nouveau flux.

Syntaxe

c
u8 AudioVBlank_QueuePlay();

Valeur renvoyée

Renvoie un si la demande est acceptée, ou zéro si la file est vide ou si le mode file est inactif. Pour consommer les enregistrements, l’interruption doit fonctionner, la musique doit être activée et le pilote ne doit pas être en pause.

Conditions et limites

Après AudioVBlank_Init, appelez QueueReset, QueueRefill puis QueuePlay, dans cet ordre. Compilez la version normale de audio_vblank.c : AUDIO_VBLANK_CORE_ONLY exclut les fonctions C qui alimentent la file. Le code principal remplit une file de seize enregistrements de cinq octets, consommés par la routine d’interruption VBlank.

Un seul producteur, dans le code principal, doit alimenter la file. Ne l’appelez ni récursivement, ni depuis une routine d’interruption ou FrameHook. Chaque brève étape rendant un enregistrement disponible sauvegarde IE et masque les sources d’interruption, puis restaure IE et SVBK. IME reste inchangé. Le code appelant doit sélectionner et maintenir la banque ROM/RAM source.

Les enregistrements temporisés contiennent delay, ch1_note, ch2_note, ch3_note et ch4_noise_param. Fournissez aussi END sous la forme d’un enregistrement complet de cinq octets. Le producteur doit développer LOOP en soumettant à nouveau les enregistrements nécessaires. Ne transmettez pas tel quel un flux de commandes de lecture directe à longueur variable.

Exemple d’utilisation

c
if(AudioVBlank_QueuePlay()==0) sound_result[0]++;
    AudioVBlank_EnableIrq();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple joue six fois une phrase originale de huit notes, puis s’arrête. Il fait passer 49 enregistrements — 48 notes et END — par la file de seize emplacements. Les vérifications portent sur l’acceptation des 49 enregistrements, l’absence de sous-alimentation, l’arrêt de la lecture, les cas file vide ou pleine, pointeur nul et nombre nul, la restauration de la banque WRAM sur CGB, la conservation d’IME, le son pendant la lecture et le silence après celle-ci.

AudioVBlank_QueuePlay: DMG
DMG
AudioVBlank_QueuePlay: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\audio_vblank_queue.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\audio_vblank_queue.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:96

Notes de déclaration (texte source)
Start/resume queued playback; return 1 on success, 0 for an empty/nonqueue mode.
Does not enable the interrupt, music gate or clear pause. Queue before starting.

kitaqgb/lib/audio_vblank_queue.inc:112

c
u8 AudioVBlank_QueuePlay()
{
    u8 saved_ie;
    u8 started;
    saved_ie = AudioVBlank_IE;
    AudioVBlank_IE = 0;
    started = 0;
    if (AudioVBlank_QueueMode != 0 && AudioVBlank_QueueCount != 0) {
        AudioVBlank_MusicPlaying = 1;
        started = 1;
    }
    AudioVBlank_IE = saved_ie;
    return started;
}
AudioVBlank_QueueRefill

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Copie des enregistrements complets de cinq octets dans les emplacements libres, puis ne rend chacun disponible qu’une fois sa copie terminée. Un appel accepte au plus seize enregistrements.

Syntaxe

c
u8 __stackcall AudioVBlank_QueueRefill(const u8 *records, u8 count);

Paramètres

records

Tableau d’enregistrements dans la banque actuellement lisible. Prévoyez cinq octets lisibles par enregistrement accepté. Un pointeur nul entraîne un retour de zéro.

count

Nombre d’enregistrements à proposer, et non nombre d’octets. Les valeurs supérieures à seize sont limitées à seize ; zéro ne fait rien.

Valeur renvoyée

Renvoie le nombre d’enregistrements effectivement acceptés, de 0 à 16. Renvoie zéro si la file est pleine, si le pointeur d’entrée est nul, si le nombre demandé est nul ou si le mode file est inactif. Avancez la source de cinq fois la valeur renvoyée. L’interruption peut libérer des emplacements pendant l’appel : ce résultat ne correspond donc pas forcément au nombre d’emplacements libres à l’entrée.

Conditions et limites

Après AudioVBlank_Init, appelez QueueReset, QueueRefill puis QueuePlay, dans cet ordre. Compilez la version normale de audio_vblank.c : AUDIO_VBLANK_CORE_ONLY exclut les fonctions C qui alimentent la file. Le code principal remplit une file de seize enregistrements de cinq octets, consommés par la routine d’interruption VBlank.

Un seul producteur, dans le code principal, doit alimenter la file. Ne l’appelez ni récursivement, ni depuis une routine d’interruption ou FrameHook. Chaque brève étape rendant un enregistrement disponible sauvegarde IE et masque les sources d’interruption, puis restaure IE et SVBK. IME reste inchangé. Le code appelant doit sélectionner et maintenir la banque ROM/RAM source.

Les enregistrements temporisés contiennent delay, ch1_note, ch2_note, ch3_note et ch4_noise_param. Fournissez aussi END sous la forme d’un enregistrement complet de cinq octets. Le producteur doit développer LOOP en soumettant à nouveau les enregistrements nécessaires. Ne transmettez pas tel quel un flux de commandes de lecture directe à longueur variable.

Exemple d’utilisation

c
next=AudioVBlank_QueueRefill(queue_song,16);
    // next counts records; each record occupies five source bytes.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple joue six fois une phrase originale de huit notes, puis s’arrête. Il fait passer 49 enregistrements — 48 notes et END — par la file de seize emplacements. Les vérifications portent sur l’acceptation des 49 enregistrements, l’absence de sous-alimentation, l’arrêt de la lecture, les cas file vide ou pleine, pointeur nul et nombre nul, la restauration de la banque WRAM sur CGB, la conservation d’IME, le son pendant la lecture et le silence après celle-ci.

AudioVBlank_QueueRefill: DMG
DMG
AudioVBlank_QueueRefill: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\audio_vblank_queue.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\audio_vblank_queue.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:93

Notes de déclaration (texte source)
Copy complete records from the currently mapped source; return records accepted.
Each call attempts at most 16 records and stops when full. Null/zero returns 0.
Supports ROM and RAM sources, restores SVBK and IE, and never changes IME.
Single foreground producer only: do not call from an ISR or frame hook.
LOOP must be expanded by the producer. END occupies a full five-byte record.

kitaqgb/lib/audio_vblank_queue.inc:93

c
u8 __stackcall AudioVBlank_QueueRefill(const u8 *records, u8 count)
{
    u8 accepted;
    u8 i;
    if (records == 0 || count == 0 || AudioVBlank_QueueMode == 0) return 0;
    if (count > AUDIO_VBLANK_QUEUE_RECORDS) count = AUDIO_VBLANK_QUEUE_RECORDS;
    accepted = 0;
    while (accepted < count) {
        if (AudioVBlank_QueueCount >= AUDIO_VBLANK_QUEUE_RECORDS) break;
        for (i = 0; i < 5; i++) AudioVBlank_QueueStaging[i] = records[i];
        if (AudioVBlank_QueuePublish() == 0) break;
        records += 5;
        accepted++;
    }
    return accepted;
}
AudioVBlank_QueueReset

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Arrête et coupe le son, sélectionne le mode file, puis remet à zéro les positions de lecture et d’écriture, le nombre d’enregistrements et le compteur de sous-alimentations. Les enregistrements en attente sont abandonnés pour préparer un nouveau flux.

Syntaxe

c
void AudioVBlank_QueueReset();

Valeur renvoyée

Aucune valeur de retour. Les réglages d’activation de la musique et de pause sont conservés.

Conditions et limites

Après AudioVBlank_Init, appelez QueueReset, QueueRefill puis QueuePlay, dans cet ordre. Compilez la version normale de audio_vblank.c : AUDIO_VBLANK_CORE_ONLY exclut les fonctions C qui alimentent la file. Le code principal remplit une file de seize enregistrements de cinq octets, consommés par la routine d’interruption VBlank.

Un seul producteur, dans le code principal, doit alimenter la file. Ne l’appelez ni récursivement, ni depuis une routine d’interruption ou FrameHook. Chaque brève étape rendant un enregistrement disponible sauvegarde IE et masque les sources d’interruption, puis restaure IE et SVBK. IME reste inchangé. Le code appelant doit sélectionner et maintenir la banque ROM/RAM source.

Les enregistrements temporisés contiennent delay, ch1_note, ch2_note, ch3_note et ch4_noise_param. Fournissez aussi END sous la forme d’un enregistrement complet de cinq octets. Le producteur doit développer LOOP en soumettant à nouveau les enregistrements nécessaires. Ne transmettez pas tel quel un flux de commandes de lecture directe à longueur variable.

Exemple d’utilisation

c
AudioVBlank_QueueReset(); // Silence playback and discard any queued records.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple joue six fois une phrase originale de huit notes, puis s’arrête. Il fait passer 49 enregistrements — 48 notes et END — par la file de seize emplacements. Les vérifications portent sur l’acceptation des 49 enregistrements, l’absence de sous-alimentation, l’arrêt de la lecture, les cas file vide ou pleine, pointeur nul et nombre nul, la restauration de la banque WRAM sur CGB, la conservation d’IME, le son pendant la lecture et le silence après celle-ci.

AudioVBlank_QueueReset: DMG
DMG
AudioVBlank_QueueReset: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\audio_vblank_queue.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\audio_vblank_queue.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:87

Notes de déclaration (texte source)
Stop music and select an empty WRAM queue; preserve IE, IME and enable/pause gates.

kitaqgb/lib/audio_vblank_queue.inc:76

c
void AudioVBlank_QueueReset()
{
    u8 saved_ie;
    saved_ie = AudioVBlank_IE;
    AudioVBlank_IE = 0;
    AudioVBlank_Stop();
    AudioVBlank_QueueMode = 1;
    AudioVBlank_QueueReadIndex = 0;
    AudioVBlank_QueueWriteIndex = 0;
    AudioVBlank_QueueCount = 0;
    AudioVBlank_QueueUnderruns = 0;
    AudioVBlank_IE = saved_ie;
}
AudioVBlank_RequestRestoreCh1

Pose la demande 2 de libération seule d’impulsion si rien n’est en attente, en préservant une demande de restauration 1 existante.

Syntaxe

c
void AudioVBlank_RequestRestoreCh1();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

audio_vblank.c implémente __kq_vblank_vector ; n’installez pas un autre vecteur VBlank concurrent. L’exemple définit Audio_NoiseEffectActive, exclut le décodeur musical ordinaire et réserve Audio_Update aux effets et fondus. Masquez les interruptions lorsque vous modifiez les pointeurs de morceau ou l’état partagé.

Pour une restauration directe, l’appelant vérifie que l’effet a libéré la voix, puis efface l’indicateur en attente. Les fonctions de demande seules n’écrivent pas les registres audio.

Exemple d’utilisation

c
// Exercise the recovery API with IRQ disabled and explicit effect ownership.
#define SOUND_VBLANK
#include "gb_sound_example.h"
void main() {
    sound_begin("EFFECT RECOVERY");
    Audio_NoiseEffectActive=0; AudioVBlank_Init();
    Audio_SetMasterVolume(3,3);
    AudioVBlank_MusicPlaying=1;
    AudioVBlank_Ch1Envelope=0xC0; AudioVBlank_Ch1LatchedNote=33;
    AudioVBlank_Ch3LatchedNote=33;
    // Value 1 represents a suppressed BGM event and survives a release request.
    AudioVBlank_RestoreCh1Pending=1;
    AudioVBlank_RequestRestoreCh1();
    sound_result[0]=AudioVBlank_RestoreCh1Pending;
    AudioVBlank_RestoreCh1(); AudioVBlank_RestoreCh1Pending=0;
    sound_wait(30);
    // Without a pending event, RequestRestore creates release-only value 2.
    AudioVBlank_RequestRestoreCh1();
    sound_result[1]=AudioVBlank_RestoreCh1Pending;
    AudioVBlank_RestoreCh1(); AudioVBlank_RestoreCh1Pending=0;
    sound_wait(30);
    AudioVBlank_RestoreCh3Pending=1;
    AudioVBlank_RequestRestoreCh3();
    sound_result[2]=AudioVBlank_RestoreCh3Pending;
    AudioVBlank_RestoreCh3(); AudioVBlank_RestoreCh3Pending=0;
    sound_wait(30);
    AudioVBlank_RequestRestoreCh3();
    sound_result[3]=AudioVBlank_RestoreCh3Pending;
    AudioVBlank_RestoreCh3(); AudioVBlank_RestoreCh3Pending=0;
    sound_wait(30);
    AudioVBlank_Stop();
    sound_end();
}

Résultat attendu

Écoutez la restauration d’impulsion, le silence, la restauration d’onde puis le silence, chacun pendant 30 images. Une demande de libération préserve la valeur en attente 1 ; sans événement en attente, elle produit la valeur 2, libération seule. Ici, IRQ est désactivé et l’appelant gère explicitement la propriété des canaux.

AudioVBlank_RequestRestoreCh1: DMG
DMG
AudioVBlank_RequestRestoreCh1: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_recovery.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-recovery.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:129

Notes de déclaration (texte source)
Request deferred pulse-channel release only when no recovery is pending.
Preserve value 1, which records a music event suppressed while an effect owned it.

kitaqgb/lib/audio_vblank.c:908

c
void AudioVBlank_RequestRestoreCh1()
{
    if (AudioVBlank_RestoreCh1Pending == 0)
        AudioVBlank_RestoreCh1Pending = 2;
}
AudioVBlank_RequestRestoreCh3

Pose la demande 2 de libération seule d’onde si rien n’est en attente, en préservant une demande de restauration 1 existante.

Syntaxe

c
void AudioVBlank_RequestRestoreCh3();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

audio_vblank.c implémente __kq_vblank_vector ; n’installez pas un autre vecteur VBlank concurrent. L’exemple définit Audio_NoiseEffectActive, exclut le décodeur musical ordinaire et réserve Audio_Update aux effets et fondus. Masquez les interruptions lorsque vous modifiez les pointeurs de morceau ou l’état partagé.

Pour une restauration directe, l’appelant vérifie que l’effet a libéré la voix, puis efface l’indicateur en attente. Les fonctions de demande seules n’écrivent pas les registres audio.

Exemple d’utilisation

c
// Exercise the recovery API with IRQ disabled and explicit effect ownership.
#define SOUND_VBLANK
#include "gb_sound_example.h"
void main() {
    sound_begin("EFFECT RECOVERY");
    Audio_NoiseEffectActive=0; AudioVBlank_Init();
    Audio_SetMasterVolume(3,3);
    AudioVBlank_MusicPlaying=1;
    AudioVBlank_Ch1Envelope=0xC0; AudioVBlank_Ch1LatchedNote=33;
    AudioVBlank_Ch3LatchedNote=33;
    // Value 1 represents a suppressed BGM event and survives a release request.
    AudioVBlank_RestoreCh1Pending=1;
    AudioVBlank_RequestRestoreCh1();
    sound_result[0]=AudioVBlank_RestoreCh1Pending;
    AudioVBlank_RestoreCh1(); AudioVBlank_RestoreCh1Pending=0;
    sound_wait(30);
    // Without a pending event, RequestRestore creates release-only value 2.
    AudioVBlank_RequestRestoreCh1();
    sound_result[1]=AudioVBlank_RestoreCh1Pending;
    AudioVBlank_RestoreCh1(); AudioVBlank_RestoreCh1Pending=0;
    sound_wait(30);
    AudioVBlank_RestoreCh3Pending=1;
    AudioVBlank_RequestRestoreCh3();
    sound_result[2]=AudioVBlank_RestoreCh3Pending;
    AudioVBlank_RestoreCh3(); AudioVBlank_RestoreCh3Pending=0;
    sound_wait(30);
    AudioVBlank_RequestRestoreCh3();
    sound_result[3]=AudioVBlank_RestoreCh3Pending;
    AudioVBlank_RestoreCh3(); AudioVBlank_RestoreCh3Pending=0;
    sound_wait(30);
    AudioVBlank_Stop();
    sound_end();
}

Résultat attendu

Écoutez la restauration d’impulsion, le silence, la restauration d’onde puis le silence, chacun pendant 30 images. Une demande de libération préserve la valeur en attente 1 ; sans événement en attente, elle produit la valeur 2, libération seule. Ici, IRQ est désactivé et l’appelant gère explicitement la propriété des canaux.

AudioVBlank_RequestRestoreCh3: DMG
DMG
AudioVBlank_RequestRestoreCh3: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_recovery.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-recovery.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:132

Notes de déclaration (texte source)
Request a deferred wave-channel release only if no recovery is pending.
Preserve value 1, which records a new music event suppressed by the effect.

kitaqgb/lib/audio_vblank.c:916

c
void AudioVBlank_RequestRestoreCh3()
{
    if (AudioVBlank_RestoreCh3Pending == 0)
        AudioVBlank_RestoreCh3Pending = 2;
}
AudioVBlank_RestoreCh1

Restaure une note musicale mémorisée sur la voix d’impulsion empruntée par un effet (CH1 ou CH2), ou la libère en silence.

Syntaxe

c
void AudioVBlank_RestoreCh1();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

audio_vblank.c implémente __kq_vblank_vector ; n’installez pas un autre vecteur VBlank concurrent. L’exemple définit Audio_NoiseEffectActive, exclut le décodeur musical ordinaire et réserve Audio_Update aux effets et fondus. Masquez les interruptions lorsque vous modifiez les pointeurs de morceau ou l’état partagé.

Pour une restauration directe, l’appelant vérifie que l’effet a libéré la voix, puis efface l’indicateur en attente. Les fonctions de demande seules n’écrivent pas les registres audio.

Exemple d’utilisation

c
// Exercise the recovery API with IRQ disabled and explicit effect ownership.
#define SOUND_VBLANK
#include "gb_sound_example.h"
void main() {
    sound_begin("EFFECT RECOVERY");
    Audio_NoiseEffectActive=0; AudioVBlank_Init();
    Audio_SetMasterVolume(3,3);
    AudioVBlank_MusicPlaying=1;
    AudioVBlank_Ch1Envelope=0xC0; AudioVBlank_Ch1LatchedNote=33;
    AudioVBlank_Ch3LatchedNote=33;
    // Value 1 represents a suppressed BGM event and survives a release request.
    AudioVBlank_RestoreCh1Pending=1;
    AudioVBlank_RequestRestoreCh1();
    sound_result[0]=AudioVBlank_RestoreCh1Pending;
    AudioVBlank_RestoreCh1(); AudioVBlank_RestoreCh1Pending=0;
    sound_wait(30);
    // Without a pending event, RequestRestore creates release-only value 2.
    AudioVBlank_RequestRestoreCh1();
    sound_result[1]=AudioVBlank_RestoreCh1Pending;
    AudioVBlank_RestoreCh1(); AudioVBlank_RestoreCh1Pending=0;
    sound_wait(30);
    AudioVBlank_RestoreCh3Pending=1;
    AudioVBlank_RequestRestoreCh3();
    sound_result[2]=AudioVBlank_RestoreCh3Pending;
    AudioVBlank_RestoreCh3(); AudioVBlank_RestoreCh3Pending=0;
    sound_wait(30);
    AudioVBlank_RequestRestoreCh3();
    sound_result[3]=AudioVBlank_RestoreCh3Pending;
    AudioVBlank_RestoreCh3(); AudioVBlank_RestoreCh3Pending=0;
    sound_wait(30);
    AudioVBlank_Stop();
    sound_end();
}

Résultat attendu

Écoutez la restauration d’impulsion, le silence, la restauration d’onde puis le silence, chacun pendant 30 images. Une demande de libération préserve la valeur en attente 1 ; sans événement en attente, elle produit la valeur 2, libération seule. Ici, IRQ est désactivé et l’appelant gère explicitement la propriété des canaux.

AudioVBlank_RestoreCh1: DMG
DMG
AudioVBlank_RestoreCh1: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_recovery.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-recovery.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:122

Notes de déclaration (texte source)
Recover the borrowed pulse channel (CH1 or CH2) from its latched music event.
Pending value 2, disabled music, or a non-note latch silences it instead.
The caller must first establish that the effect has released the channel.

kitaqgb/lib/audio_vblank.c:769

c
void AudioVBlank_RestoreCh1()
{
    __asm {
        LD_A_MEM Audio_EffectUsesCh2
        OR_A
        JR_NZ audiovb_restore_ch2
        LD_A_MEM AudioVBlank_RestoreCh1Pending
        CP_IMM 2
        JR_Z audiovb_restore_ch1_off
        LD_A_MEM AudioVBlank_MusicPlaying
        OR_A
        JR_Z audiovb_restore_ch1_off
        LD_A_MEM AudioVBlank_MusicEnabled
        OR_A
        JR_Z audiovb_restore_ch1_off
        LD_A_MEM Audio_MusicEnabled
        OR_A
        JR_Z audiovb_restore_ch1_off
        LD_A_MEM AudioVBlank_Ch1LatchedNote
        CP_IMM 0x44
        JR_NC audiovb_restore_ch1_off
        LD_C_A
        LD_A_MEM AudioVBlank_Ch1Sweep
        LDH_MEM_A 0x10
        LD_A_MEM AudioVBlank_Ch1Duty
        LDH_MEM_A 0x11
        LD_A_MEM AudioVBlank_Ch1Envelope
        LDH_MEM_A 0x12
        LD_A_C
        LD_E_A
        LD_D_IMM 0
        LD_HL_IMM AudioVBlank_FreqLo
        ADD_HL_DE
        LD_A_HL
        LDH_MEM_A 0x13
        LD_HL_IMM AudioVBlank_FreqHi
        ADD_HL_DE
        LD_A_HL
        OR_IMM 0x80
        LDH_MEM_A 0x14
        JR audiovb_restore_ch1_done
audiovb_restore_ch1_off:
        XOR_A
        LDH_MEM_A 0x12
audiovb_restore_ch1_done:
        JR audiovb_restore_square_done

audiovb_restore_ch2:
        LD_A_MEM AudioVBlank_RestoreCh1Pending
        CP_IMM 2
        JR_Z audiovb_restore_ch2_off
        LD_A_MEM AudioVBlank_MusicPlaying
        OR_A
        JR_Z audiovb_restore_ch2_off
        LD_A_MEM AudioVBlank_MusicEnabled
        OR_A
        JR_Z audiovb_restore_ch2_off
        LD_A_MEM Audio_MusicEnabled
        OR_A
        JR_Z audiovb_restore_ch2_off
        LD_A_MEM AudioVBlank_Ch2LatchedNote
        CP_IMM 0x44
        JR_NC audiovb_restore_ch2_off
        LD_C_A
        LD_A_MEM AudioVBlank_Ch2Duty
        LDH_MEM_A 0x16
        LD_A_MEM AudioVBlank_Ch2Envelope
        LDH_MEM_A 0x17
        LD_A_C
        LD_E_A
        LD_D_IMM 0
        LD_HL_IMM AudioVBlank_FreqLo
        ADD_HL_DE
        LD_A_HL
        LDH_MEM_A 0x18
        LD_HL_IMM AudioVBlank_FreqHi
        ADD_HL_DE
        LD_A_HL
        OR_IMM 0x80
        LDH_MEM_A 0x19
        JR audiovb_restore_square_done
audiovb_restore_ch2_off:
        XOR_A
        LDH_MEM_A 0x17
audiovb_restore_square_done:
    }
}
AudioVBlank_RestoreCh3

Restaure la note mémorisée de CH3 après libération de l’effet, ou désactive son DAC.

Syntaxe

c
void AudioVBlank_RestoreCh3();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

audio_vblank.c implémente __kq_vblank_vector ; n’installez pas un autre vecteur VBlank concurrent. L’exemple définit Audio_NoiseEffectActive, exclut le décodeur musical ordinaire et réserve Audio_Update aux effets et fondus. Masquez les interruptions lorsque vous modifiez les pointeurs de morceau ou l’état partagé.

Pour une restauration directe, l’appelant vérifie que l’effet a libéré la voix, puis efface l’indicateur en attente. Les fonctions de demande seules n’écrivent pas les registres audio.

Exemple d’utilisation

c
// Exercise the recovery API with IRQ disabled and explicit effect ownership.
#define SOUND_VBLANK
#include "gb_sound_example.h"
void main() {
    sound_begin("EFFECT RECOVERY");
    Audio_NoiseEffectActive=0; AudioVBlank_Init();
    Audio_SetMasterVolume(3,3);
    AudioVBlank_MusicPlaying=1;
    AudioVBlank_Ch1Envelope=0xC0; AudioVBlank_Ch1LatchedNote=33;
    AudioVBlank_Ch3LatchedNote=33;
    // Value 1 represents a suppressed BGM event and survives a release request.
    AudioVBlank_RestoreCh1Pending=1;
    AudioVBlank_RequestRestoreCh1();
    sound_result[0]=AudioVBlank_RestoreCh1Pending;
    AudioVBlank_RestoreCh1(); AudioVBlank_RestoreCh1Pending=0;
    sound_wait(30);
    // Without a pending event, RequestRestore creates release-only value 2.
    AudioVBlank_RequestRestoreCh1();
    sound_result[1]=AudioVBlank_RestoreCh1Pending;
    AudioVBlank_RestoreCh1(); AudioVBlank_RestoreCh1Pending=0;
    sound_wait(30);
    AudioVBlank_RestoreCh3Pending=1;
    AudioVBlank_RequestRestoreCh3();
    sound_result[2]=AudioVBlank_RestoreCh3Pending;
    AudioVBlank_RestoreCh3(); AudioVBlank_RestoreCh3Pending=0;
    sound_wait(30);
    AudioVBlank_RequestRestoreCh3();
    sound_result[3]=AudioVBlank_RestoreCh3Pending;
    AudioVBlank_RestoreCh3(); AudioVBlank_RestoreCh3Pending=0;
    sound_wait(30);
    AudioVBlank_Stop();
    sound_end();
}

Résultat attendu

Écoutez la restauration d’impulsion, le silence, la restauration d’onde puis le silence, chacun pendant 30 images. Une demande de libération préserve la valeur en attente 1 ; sans événement en attente, elle produit la valeur 2, libération seule. Ici, IRQ est désactivé et l’appelant gère explicitement la propriété des canaux.

AudioVBlank_RestoreCh3: DMG
DMG
AudioVBlank_RestoreCh3: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_recovery.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-recovery.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:126

Notes de déclaration (texte source)
Recover a latched wave-channel music event after effect release, or disable
the DAC for a release-only request, disabled music, or a non-note latch.
The caller owns effect arbitration and clearing the pending flag.

kitaqgb/lib/audio_vblank.c:860

c
void AudioVBlank_RestoreCh3()
{
    __asm {
        LD_A_MEM AudioVBlank_RestoreCh3Pending
        CP_IMM 2
        JR_Z audiovb_restore_ch3_off
        LD_A_MEM AudioVBlank_MusicPlaying
        OR_A
        JR_Z audiovb_restore_ch3_off
        LD_A_MEM AudioVBlank_MusicEnabled
        OR_A
        JR_Z audiovb_restore_ch3_off
        LD_A_MEM Audio_MusicEnabled
        OR_A
        JR_Z audiovb_restore_ch3_off
        LD_A_MEM AudioVBlank_Ch3LatchedNote
        CP_IMM 0x44
        JR_NC audiovb_restore_ch3_off
        LD_C_A
        LD_A_IMM 0x80
        LDH_MEM_A 0x1A
        XOR_A
        LDH_MEM_A 0x1B
        LD_A_MEM AudioVBlank_Ch3Level
        LDH_MEM_A 0x1C
        LD_A_C
        LD_E_A
        LD_D_IMM 0
        LD_HL_IMM AudioVBlank_FreqLo
        ADD_HL_DE
        LD_A_HL
        LDH_MEM_A 0x1D
        LD_HL_IMM AudioVBlank_FreqHi
        ADD_HL_DE
        LD_A_HL
        OR_IMM 0x80
        LDH_MEM_A 0x1E
        JR audiovb_restore_ch3_done
audiovb_restore_ch3_off:
        XOR_A
        LDH_MEM_A 0x1A
audiovb_restore_ch3_done:
    }
}
AudioVBlank_SetEnabled

Autorise ou bloque la musique VBlank et efface les demandes de restauration à la désactivation. Le son courant et IRQ restent inchangés.

Syntaxe

c
void __stackcall AudioVBlank_SetEnabled(u8 on);

Paramètres

on

Zéro désactive, non-zéro active. Consultez la description pour distinguer mise en sourdine et suspension des mises à jour.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

audio_vblank.c implémente __kq_vblank_vector ; n’installez pas un autre vecteur VBlank concurrent. L’exemple définit Audio_NoiseEffectActive, exclut le décodeur musical ordinaire et réserve Audio_Update aux effets et fondus. Masquez les interruptions lorsque vous modifiez les pointeurs de morceau ou l’état partagé.

Gardez les données musicales directes en ROM fixe ou dans une zone toujours visible par l’ISR. Un enregistrement contient cinq octets : delay, CH1, CH2, CH3, CH4. Dans les champs de note, 0xFF maintient la voix et 0xFD l’arrête. Dans delay, 0xFF termine la lecture et 0xFE boucle. Il s’agit de l’ordre des champs, pas des identifiants de canal. La file WRAM est un mode distinct ; fournissez des enregistrements complets de cinq octets avec AudioVBlank_QueueRefill.

Exemple d’utilisation

c
// Direct fixed-bank music with an actual VBlank ISR and a counting frame hook.
#define SOUND_VBLANK
#include "gb_sound_example.h"
__wram u8 hook_count;
__prg_rom u8 irq_song[]={30,33,0xFF,0xFF,0xFF,30,40,0xFF,0xFF,0xFF,0xFE};
void frame_hook() { hook_count++; }
void main() {
    u8 before;
    sound_begin("VBLANK MUSIC GATES");
    Audio_NoiseEffectActive=0;
    AudioVBlank_Init();
    sound_result[0]=AudioVBlank_MusicPlaying;
    AudioVBlank_Ch1Envelope=0xC0;
    Audio_SetMasterVolume(3,3);
    hook_count=0; AudioVBlank_FrameHook=frame_hook;
    AudioVBlank_SetMusic(irq_song);
    AudioVBlank_Play();
    AudioVBlank_EnableIrq();
    sound_wait(45);
    // Disable music processing while the hook and current note remain active.
    __asm { DI }
    AudioVBlank_SetEnabled(0); before=hook_count;
    __asm { EI }
    sound_wait(30);
    sound_result[1]=(u8)(hook_count!=before);
    __asm { DI }
    AudioVBlank_Stop();
    __asm { EI }
    sound_wait(30);
    __asm { DI }
    AudioVBlank_SetEnabled(1); AudioVBlank_PlayMusic(irq_song);
    __asm { EI }
    sound_wait(45);
    AudioVBlank_DisableIrq();
    before=hook_count;
    sound_wait(30);
    sound_result[2]=(u8)(hook_count==before);
    sound_result[3]=(u8)(AudioVBlank_IE&1);
    AudioVBlank_Stop(); sound_wait(30);
    sound_end();
}

Résultat attendu

L’ISR joue un morceau de deux notes. Comparez la suspension des mises à jour musicales, qui conserve le son, Stop, qui le coupe, et la désactivation IRQ après redémarrage, qui conserve aussi le son. La RAM vérifie que le hook tourne musique désactivée et s’arrête IRQ désactivée.

AudioVBlank_SetEnabled: DMG
DMG
AudioVBlank_SetEnabled: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_vblank.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-vblank.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:113

Notes de déclaration (texte source)
Gate music processing and clear pending CH1/CH3 recovery on disable.
No audio register is written here: disabling does not itself silence a note
already playing or disable the VBlank interrupt.

kitaqgb/lib/audio_vblank_control.inc:109

c
void __stackcall AudioVBlank_SetEnabled(u8 on)
{
    if (on != 0) AudioVBlank_MusicEnabled = 1;
    else {
        AudioVBlank_MusicEnabled = 0;
        // Do not carry a stale SFX-recovery request into a later song.
        AudioVBlank_RestoreCh1Pending = 0;
        AudioVBlank_RestoreCh3Pending = 0;
    }
}
AudioVBlank_SetMusic

Sélectionne un morceau en lecture directe et réinitialise ses curseurs sans changer l’indicateur de lecture.

Syntaxe

c
void __stackcall AudioVBlank_SetMusic(u8 *song);

Paramètres

song

Adresse de début du morceau. Le pilote emprunte le tableau, qui doit rester lisible pendant toute la lecture.

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

audio_vblank.c implémente __kq_vblank_vector ; n’installez pas un autre vecteur VBlank concurrent. L’exemple définit Audio_NoiseEffectActive, exclut le décodeur musical ordinaire et réserve Audio_Update aux effets et fondus. Masquez les interruptions lorsque vous modifiez les pointeurs de morceau ou l’état partagé.

Gardez les données musicales directes en ROM fixe ou dans une zone toujours visible par l’ISR. Un enregistrement contient cinq octets : delay, CH1, CH2, CH3, CH4. Dans les champs de note, 0xFF maintient la voix et 0xFD l’arrête. Dans delay, 0xFF termine la lecture et 0xFE boucle. Il s’agit de l’ordre des champs, pas des identifiants de canal. La file WRAM est un mode distinct ; fournissez des enregistrements complets de cinq octets avec AudioVBlank_QueueRefill.

Exemple d’utilisation

c
// Direct fixed-bank music with an actual VBlank ISR and a counting frame hook.
#define SOUND_VBLANK
#include "gb_sound_example.h"
__wram u8 hook_count;
__prg_rom u8 irq_song[]={30,33,0xFF,0xFF,0xFF,30,40,0xFF,0xFF,0xFF,0xFE};
void frame_hook() { hook_count++; }
void main() {
    u8 before;
    sound_begin("VBLANK MUSIC GATES");
    Audio_NoiseEffectActive=0;
    AudioVBlank_Init();
    sound_result[0]=AudioVBlank_MusicPlaying;
    AudioVBlank_Ch1Envelope=0xC0;
    Audio_SetMasterVolume(3,3);
    hook_count=0; AudioVBlank_FrameHook=frame_hook;
    AudioVBlank_SetMusic(irq_song);
    AudioVBlank_Play();
    AudioVBlank_EnableIrq();
    sound_wait(45);
    // Disable music processing while the hook and current note remain active.
    __asm { DI }
    AudioVBlank_SetEnabled(0); before=hook_count;
    __asm { EI }
    sound_wait(30);
    sound_result[1]=(u8)(hook_count!=before);
    __asm { DI }
    AudioVBlank_Stop();
    __asm { EI }
    sound_wait(30);
    __asm { DI }
    AudioVBlank_SetEnabled(1); AudioVBlank_PlayMusic(irq_song);
    __asm { EI }
    sound_wait(45);
    AudioVBlank_DisableIrq();
    before=hook_count;
    sound_wait(30);
    sound_result[2]=(u8)(hook_count==before);
    sound_result[3]=(u8)(AudioVBlank_IE&1);
    AudioVBlank_Stop(); sound_wait(30);
    sound_end();
}

Résultat attendu

L’ISR joue un morceau de deux notes. Comparez la suspension des mises à jour musicales, qui conserve le son, Stop, qui le coupe, et la désactivation IRQ après redémarrage, qui conserve aussi le son. La RAM vérifie que le hook tourne musique désactivée et s’arrête IRQ désactivée.

AudioVBlank_SetMusic: DMG
DMG
AudioVBlank_SetMusic: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_vblank.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-vblank.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:100

Notes de déclaration (texte source)
Select a directly addressed song and reset its cursors, leaving the playing
flag unchanged. Song storage must remain accessible to the fixed-bank ISR;
coordinate this multi-field update with interrupt execution.

kitaqgb/lib/audio_vblank_control.inc:46

c
void __stackcall AudioVBlank_SetMusic(u8 *song)
{
    AudioVBlank_MusicStart = song;
    AudioVBlank_MusicPointer = song;
    AudioVBlank_MusicLoopPoint = song;
    AudioVBlank_MusicDelay = 0;
    AudioVBlank_Step = 0;
    AudioVBlank_QueueMode = 0;
}
AudioVBlank_Stop

Efface les états de lecture, delay et restauration, puis coupe immédiatement impulsions, bruit et onde. IRQ reste activé.

Syntaxe

c
void AudioVBlank_Stop();

Valeur renvoyée

Aucune valeur de retour. Modifie les registres audio ou l’état du pilote.

Conditions et limites

audio_vblank.c implémente __kq_vblank_vector ; n’installez pas un autre vecteur VBlank concurrent. L’exemple définit Audio_NoiseEffectActive, exclut le décodeur musical ordinaire et réserve Audio_Update aux effets et fondus. Masquez les interruptions lorsque vous modifiez les pointeurs de morceau ou l’état partagé.

Gardez les données musicales directes en ROM fixe ou dans une zone toujours visible par l’ISR. Un enregistrement contient cinq octets : delay, CH1, CH2, CH3, CH4. Dans les champs de note, 0xFF maintient la voix et 0xFD l’arrête. Dans delay, 0xFF termine la lecture et 0xFE boucle. Il s’agit de l’ordre des champs, pas des identifiants de canal. La file WRAM est un mode distinct ; fournissez des enregistrements complets de cinq octets avec AudioVBlank_QueueRefill.

Exemple d’utilisation

c
// Direct fixed-bank music with an actual VBlank ISR and a counting frame hook.
#define SOUND_VBLANK
#include "gb_sound_example.h"
__wram u8 hook_count;
__prg_rom u8 irq_song[]={30,33,0xFF,0xFF,0xFF,30,40,0xFF,0xFF,0xFF,0xFE};
void frame_hook() { hook_count++; }
void main() {
    u8 before;
    sound_begin("VBLANK MUSIC GATES");
    Audio_NoiseEffectActive=0;
    AudioVBlank_Init();
    sound_result[0]=AudioVBlank_MusicPlaying;
    AudioVBlank_Ch1Envelope=0xC0;
    Audio_SetMasterVolume(3,3);
    hook_count=0; AudioVBlank_FrameHook=frame_hook;
    AudioVBlank_SetMusic(irq_song);
    AudioVBlank_Play();
    AudioVBlank_EnableIrq();
    sound_wait(45);
    // Disable music processing while the hook and current note remain active.
    __asm { DI }
    AudioVBlank_SetEnabled(0); before=hook_count;
    __asm { EI }
    sound_wait(30);
    sound_result[1]=(u8)(hook_count!=before);
    __asm { DI }
    AudioVBlank_Stop();
    __asm { EI }
    sound_wait(30);
    __asm { DI }
    AudioVBlank_SetEnabled(1); AudioVBlank_PlayMusic(irq_song);
    __asm { EI }
    sound_wait(45);
    AudioVBlank_DisableIrq();
    before=hook_count;
    sound_wait(30);
    sound_result[2]=(u8)(hook_count==before);
    sound_result[3]=(u8)(AudioVBlank_IE&1);
    AudioVBlank_Stop(); sound_wait(30);
    sound_end();
}

Résultat attendu

L’ISR joue un morceau de deux notes. Comparez la suspension des mises à jour musicales, qui conserve le son, Stop, qui le coupe, et la désactivation IRQ après redémarrage, qui conserve aussi le son. La RAM vérifie que le hook tourne musique désactivée et s’arrête IRQ désactivée.

AudioVBlank_Stop: DMG
DMG
AudioVBlank_Stop: CGB
CGB
DMG — Audio enregistré
CGB — Audio enregistré

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sound_vblank.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\gb-vblank.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/audio_vblank.h:109

Notes de déclaration (texte source)
Stop software playback and silence pulse/noise envelopes and the wave DAC.
Song pointers and the IRQ enable remain unchanged; the routine writes the
physical channels directly, so coordinate ownership with sound effects.

kitaqgb/lib/audio_vblank_control.inc:82

c
void AudioVBlank_Stop()
{
    AudioVBlank_MusicPlaying = 0;
    AudioVBlank_MusicDelay = 0;
    AudioVBlank_Step = 0;
    AudioVBlank_Ch2Note = AUDIO_VBLANK_REST;
    AudioVBlank_Ch1Note = AUDIO_VBLANK_REST;
    AudioVBlank_Ch3Note = AUDIO_VBLANK_REST;
    AudioVBlank_Ch2LatchedNote = AUDIO_VBLANK_STOP;
    AudioVBlank_Ch1LatchedNote = AUDIO_VBLANK_STOP;
    AudioVBlank_Ch3LatchedNote = AUDIO_VBLANK_STOP;
    AudioVBlank_RestoreCh1Pending = 0;
    AudioVBlank_RestoreCh3Pending = 0;
    AudioVBlank_Ch4Param = AUDIO_VBLANK_REST;
    __asm {
        XOR_A
        LDH_MEM_A 0x12
        LDH_MEM_A 0x17
        LDH_MEM_A 0x1C
        LDH_MEM_A 0x1A
        LDH_MEM_A 0x21
    }
}

bank.h — Accès au code et aux données tenant compte des banques

Une banque ROM est un bloc de stockage de la cartouche mappé dans l’espace d’adressage du CPU. Plusieurs banques peuvent apparaître à la même adresse : un pointeur de 16 bits ne suffit donc pas à identifier les données. BankPtr est un descripteur compact de trois octets : un numéro de banque sur un octet et un pointeur sur deux octets. Créez-le avec farptr_make, puis accédez aux données avec farptr_read8, farptr_read16 ou farptr_read.

L’exemple GB utilise une cartouche MBC5 : le code de la banque fixe 0 reste accessible en $0000–$3FFF, tandis que les banques 1, 2 et 3 sont sélectionnées en $4000–$7FFF. Placez bank_switch et le code exécuté après son retour en ROM fixe. Initialisez l’état de la bibliothèque avec bank_switch avant de le consulter. Sur GB, far_call accepte un pointeur de rappel ; __farcall exige un nom de fonction.

bank_get_current

Renvoie le dernier numéro de banque enregistré par bank_switch. Il s’agit d’un état logiciel, pas d’une lecture des registres de la cartouche.

Syntaxe

c
u8 bank_get_current();

Valeur renvoyée

La valeur u8 enregistrée par le dernier bank_switch ; zéro avant l’initialisation.

Conditions et limites

L’état de la bibliothèque commence à zéro et ne détecte pas le mappage initial de la cartouche. Initialisez-le avec bank_switch. Les intrinsèques et écritures directes dans le mapper n’actualisent pas cet état distinct ; bank_get_current ne vérifie donc pas le mappage matériel réel.

Exemple d’utilisation

c
starting_bank=bank_get_current(); // Last value recorded by bank_switch.
bank_expect(starting_bank==2,1);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

bank_switch(2) enregistre et sélectionne d’abord la banque 2. Une commutation directe sélectionne ensuite la banque 1 et lit A1 dans home1, tandis que bank_get_current indique toujours 2 ; après restauration, home2 donne à nouveau B2.

Le programme complet montre comment identifier des données par une banque et une adresse proche, appeler des rappels entre banques et distinguer l’état de la bibliothèque du mappage réel. Tous les nombres sont hexadécimaux. BANK IN et BANK OUT doivent valoir 02 ; BYTE HEX, D3 ; WORD HEX, 5C7A ; FAILED CHECKS et FIRST FAILURE, 00. Le texte est bleu sur CGB et FC, noir sur DMG.

CALL COUNT vaut 03 : far_call, __farcall et __farcall_ptr invoquent chacun le rappel une fois.

bank_get_current: DMG
DMG
bank_get_current: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\banked_data_calls.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\banked_data_calls.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/bank.h:21

Notes de déclaration (texte source)
Return the last bank recorded by bank_switch; this does not read cartridge hardware.

kitaqgb/lib/bank.c:15

c
u8 bank_get_current()
{
    return kq_bank_current;
}
bank_switch

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Sélectionne la banque ROM et enregistre son numéro dans la bibliothèque bank et dans l’état du compilateur. Les lectures et appels distants utilisent ce dernier pour rétablir la banque précédente.

Syntaxe

c
void bank_switch(u8 bank);

Paramètres

bank

Numéro de banque ROM non signé sur 8 bits. Pour un appel, il doit correspondre au placement de la fonction ; pour une lecture, il sélectionne la source. Respectez la plage du type de cartouche.

Valeur renvoyée

Aucune (void).

Conditions et limites

Un changement persistant de banque ne doit pas rendre inaccessibles le code exécuté ou son adresse de retour. Placez cet appel, bank_switch elle-même si elle est utilisée, et le code qui suit dans la banque commune ou fixe 0, comme dans l’exemple.

L’état de la bibliothèque commence à zéro et ne détecte pas le mappage initial de la cartouche. Initialisez-le avec bank_switch. Les intrinsèques et écritures directes dans le mapper n’actualisent pas cet état distinct ; bank_get_current ne vérifie donc pas le mappage matériel réel.

Ces interfaces GB transportent huit bits de banque et ne règlent pas le neuvième bit MBC5. Les règles de la cartouche restent applicables, notamment pour la banque zéro. L’exemple utilise explicitement les banques MBC5 1–3 ; ne mélangez pas cet état avec des écritures directes non suivies dans le mapper.

Exemple d’utilisation

c
bank_switch(2); // Select the payload window and update library bookkeeping.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

bank_switch(2) enregistre et sélectionne d’abord la banque 2. Une commutation directe sélectionne ensuite la banque 1 et lit A1 dans home1, tandis que bank_get_current indique toujours 2 ; après restauration, home2 donne à nouveau B2.

Le programme complet montre comment identifier des données par une banque et une adresse proche, appeler des rappels entre banques et distinguer l’état de la bibliothèque du mappage réel. Tous les nombres sont hexadécimaux. BANK IN et BANK OUT doivent valoir 02 ; BYTE HEX, D3 ; WORD HEX, 5C7A ; FAILED CHECKS et FIRST FAILURE, 00. Le texte est bleu sur CGB et FC, noir sur DMG.

CALL COUNT vaut 03 : far_call, __farcall et __farcall_ptr invoquent chacun le rappel une fois.

bank_switch: DMG
DMG
bank_switch: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\banked_data_calls.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\banked_data_calls.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/bank.h:19

Notes de déclaration (texte source)
Update both the library bank record and the compiler shadow used by far
reads and calls. Invoke this permanent bank change from fixed-bank code.

kitaqgb/lib/bank.c:8

c
void bank_switch(u8 bank)
{
    kq_bank_current = bank;
    __bankswitch(bank);
}
far_call

Transmet un numéro de banque et un pointeur de rappel à __farcall_ptr. Cette fonction de bibliothèque exécute le rappel sans argument et revient après avoir restauré la banque de l’appelant.

Syntaxe

c
void far_call(u8 bank, const void* func);

Paramètres

bank

Numéro de banque ROM non signé sur 8 bits. Pour un appel, il doit correspondre au placement de la fonction ; pour une lecture, il sélectionne la source. Respectez la plage du type de cartouche.

func

Adresse exécutable valide d’un rappel sans paramètre, fournie par un nom de fonction ou un pointeur d’exécution. Les pointeurs nuls et les associations banque/adresse incorrectes ne sont pas vérifiés à l’exécution.

Valeur renvoyée

Aucune (void).

Conditions et limites

Ces appels ne transmettent pas d’arguments utilisateur et ne rendent pas le rappel réentrant face aux interruptions. Gérez correctement ses données, sa pile et ses interruptions. La restauration des banques est testée avec des appels imbriqués et répétés ; l’exemple ne couvre ni le matériel physique ni tous les entrelacements d’interruptions.

Ces interfaces GB transportent huit bits de banque et ne règlent pas le neuvième bit MBC5. Les règles de la cartouche restent applicables, notamment pour la banque zéro. L’exemple utilise explicitement les banques MBC5 1–3 ; ne mélangez pas cet état avec des écritures directes non suivies dans le mapper.

Exemple d’utilisation

c
far_call(3,callback); // No arguments; callback reads payload[0] in bank 3.
bank_expect(callback_count==1 && callback_byte==0xD3,15);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À ce stade du programme complet, far_call porte callback_count à 1. Le rappel lit D3 dans la banque 3. Une lecture proche ultérieure de B2 dans home2 confirme le retour avec la banque 2 sélectionnée.

Le programme complet montre comment identifier des données par une banque et une adresse proche, appeler des rappels entre banques et distinguer l’état de la bibliothèque du mappage réel. Tous les nombres sont hexadécimaux. BANK IN et BANK OUT doivent valoir 02 ; BYTE HEX, D3 ; WORD HEX, 5C7A ; FAILED CHECKS et FIRST FAILURE, 00. Le texte est bleu sur CGB et FC, noir sur DMG.

CALL COUNT vaut 03 : far_call, __farcall et __farcall_ptr invoquent chacun le rappel une fois.

far_call: DMG
DMG
far_call: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\banked_data_calls.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\banked_data_calls.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/bank.h:30

Notes de déclaration (texte source)
Invoke a no-argument callback in its ROM bank, then restore the caller
bank. The pointer must identify executable code; no arguments are forwarded.

kitaqgb/lib/bank.c:40

c
void far_call(u8 bank, const void* func)
{
    __farcall_ptr(bank, func);
}
far_data_read

Copie len octets de la banque ROM indiquée vers la RAM fournie par l’appelant via l’intrinsèque de copie distante. Rétablit la banque précédente avant le retour.

Syntaxe

c
void far_data_read(u8 bank, const void* addr, void* dst, u16 len);

Paramètres

bank

Numéro de banque ROM non signé sur 8 bits. Pour un appel, il doit correspondre au placement de la fonction ; pour une lecture, il sélectionne la source. Respectez la plage du type de cartouche.

addr

Pointeur proche vers des octets lisibles dans la banque ROM choisie. Il ne contient pas de numéro de banque.

dst

Destination en mémoire accessible en écriture, assez grande pour tous les octets copiés. Hors transfert de zéro octet, les adresses nulles ou invalides ne sont pas vérifiées.

len

Nombre d’octets, de 0 à 65535. Avec zéro, aucune mémoire n’est copiée, mais la sélection et le rétablissement de la banque ont bien lieu.

Valeur renvoyée

Aucune (void).

Conditions et limites

Toute la source doit être lisible dans le mappage ROM prévu, et toute la destination accessible en écriture. La copie ne passe pas automatiquement à la banque suivante, ne gère pas les chevauchements comme memmove et ne synchronise pas les écritures VRAM. Utilisez les API graphiques pour la VRAM.

Les lectures et copies distantes sont synchrones et utilisent un espace de travail partagé du compilateur. Une interruption ne doit pas y exécuter un autre transfert pendant son utilisation. Sur GB, la copie utilise aussi un emplacement HRAM partagé pour la banque sauvegardée. L’exemple exécute ces opérations depuis du code fixe, sans gestionnaire de transfert concurrent.

Ces interfaces GB transportent huit bits de banque et ne règlent pas le neuvième bit MBC5. Les règles de la cartouche restent applicables, notamment pour la banque zéro. L’exemple utilise explicitement les banques MBC5 1–3 ; ne mélangez pas cet état avec des écritures directes non suivies dans le mapper.

Exemple d’utilisation

c
far_data_read(3,payload,buffer,4); // Copy into four writable RAM bytes.
bank_expect(buffer[0]==0xD3 && buffer[1]==0x7A && buffer[2]==0x5C && buffer[3]==0x96,7);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet extrait copie 4 octets via far_data_read et compare le tampon à D3 7A 5C 96. Le descripteur ou pointeur source de l’appelant est conservé ; le programme complet vérifie séparément une copie de longueur nulle et la restauration de la banque.

Le programme complet montre comment identifier des données par une banque et une adresse proche, appeler des rappels entre banques et distinguer l’état de la bibliothèque du mappage réel. Tous les nombres sont hexadécimaux. BANK IN et BANK OUT doivent valoir 02 ; BYTE HEX, D3 ; WORD HEX, 5C7A ; FAILED CHECKS et FIRST FAILURE, 00. Le texte est bleu sur CGB et FC, noir sur DMG.

CALL COUNT vaut 03 : far_call, __farcall et __farcall_ptr invoquent chacun le rappel une fois.

far_data_read: DMG
DMG
far_data_read: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\banked_data_calls.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\banked_data_calls.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/bank.h:27

Notes de déclaration (texte source)
Copy len bytes from banked ROM into caller-owned writable storage.

kitaqgb/lib/bank.c:33

c
void far_data_read(u8 bank, const void* addr, void* dst, u16 len)
{
    __farmemcpy(dst, bank, addr, len);
}
far_data_read16

Lit deux octets consécutifs via __farpeek16 et les assemble en un mot little-endian. Le premier octet fournit les huit bits de poids faible.

Syntaxe

c
u16 far_data_read16(u8 bank, const void* addr);

Paramètres

bank

Numéro de banque ROM non signé sur 8 bits. Pour un appel, il doit correspondre au placement de la fonction ; pour une lecture, il sélectionne la source. Respectez la plage du type de cartouche.

addr

Pointeur proche vers des octets lisibles dans la banque ROM choisie. Il ne contient pas de numéro de banque.

Valeur renvoyée

Le mot little-endian lu, sous forme de u16 (0–65535).

Conditions et limites

L’octet ou le mot entier doit être lisible dans le mappage CPU sélectionné. Ces lectures ne valident pas les pointeurs, ne bornent pas les adresses et ne passent pas automatiquement à une autre banque à la limite d’une fenêtre. Un mot exige deux octets consécutifs valides.

Les lectures et copies distantes sont synchrones et utilisent un espace de travail partagé du compilateur. Une interruption ne doit pas y exécuter un autre transfert pendant son utilisation. Sur GB, la copie utilise aussi un emplacement HRAM partagé pour la banque sauvegardée. L’exemple exécute ces opérations depuis du code fixe, sans gestionnaire de transfert concurrent.

Ces interfaces GB transportent huit bits de banque et ne règlent pas le neuvième bit MBC5. Les règles de la cartouche restent applicables, notamment pour la banque zéro. L’exemple utilise explicitement les banques MBC5 1–3 ; ne mélangez pas cet état avec des écritures directes non suivies dans le mapper.

Exemple d’utilisation

c
word_value=far_data_read16(3,payload+1); // Little-endian 7A 5C -> 0x5C7A.
bank_expect(word_value==0x5C7A,6);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet extrait utilise far_data_read16 pour lire payload+1 dans la banque 3 et vérifie 5C7A. Le programme complet lit aussi home2 avec un pointeur proche pour confirmer la restauration de la banque 2.

Le programme complet montre comment identifier des données par une banque et une adresse proche, appeler des rappels entre banques et distinguer l’état de la bibliothèque du mappage réel. Tous les nombres sont hexadécimaux. BANK IN et BANK OUT doivent valoir 02 ; BYTE HEX, D3 ; WORD HEX, 5C7A ; FAILED CHECKS et FIRST FAILURE, 00. Le texte est bleu sur CGB et FC, noir sur DMG.

CALL COUNT vaut 03 : far_call, __farcall et __farcall_ptr invoquent chacun le rappel une fois.

far_data_read16: DMG
DMG
far_data_read16: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\banked_data_calls.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\banked_data_calls.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/bank.h:25

Notes de déclaration (texte source)
Read a 16-bit value from the supplied bank and address through the far-read intrinsic.

kitaqgb/lib/bank.c:27

c
u16 far_data_read16(u8 bank, const void* addr)
{
    return __farpeek16(bank, addr);
}
far_data_read8

Lit un octet dans la banque ROM à l’adresse indiquée via __farpeek8, rétablit la banque précédente et renvoie la valeur.

Syntaxe

c
u8 far_data_read8(u8 bank, const void* addr);

Paramètres

bank

Numéro de banque ROM non signé sur 8 bits. Pour un appel, il doit correspondre au placement de la fonction ; pour une lecture, il sélectionne la source. Respectez la plage du type de cartouche.

addr

Pointeur proche vers des octets lisibles dans la banque ROM choisie. Il ne contient pas de numéro de banque.

Valeur renvoyée

L’octet lu, sous forme de u8 (0–255).

Conditions et limites

L’octet ou le mot entier doit être lisible dans le mappage CPU sélectionné. Ces lectures ne valident pas les pointeurs, ne bornent pas les adresses et ne passent pas automatiquement à une autre banque à la limite d’une fenêtre. Un mot exige deux octets consécutifs valides.

Les lectures et copies distantes sont synchrones et utilisent un espace de travail partagé du compilateur. Une interruption ne doit pas y exécuter un autre transfert pendant son utilisation. Sur GB, la copie utilise aussi un emplacement HRAM partagé pour la banque sauvegardée. L’exemple exécute ces opérations depuis du code fixe, sans gestionnaire de transfert concurrent.

Ces interfaces GB transportent huit bits de banque et ne règlent pas le neuvième bit MBC5. Les règles de la cartouche restent applicables, notamment pour la banque zéro. L’exemple utilise explicitement les banques MBC5 1–3 ; ne mélangez pas cet état avec des écritures directes non suivies dans le mapper.

Exemple d’utilisation

c
byte_value=far_data_read8(3,payload); // One byte: 0xD3.
bank_expect(byte_value==0xD3,5);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet extrait utilise far_data_read8 pour lire payload dans la banque 3 et vérifie D3. Le programme complet lit aussi home2 avec un pointeur proche pour confirmer la restauration de la banque 2.

Le programme complet montre comment identifier des données par une banque et une adresse proche, appeler des rappels entre banques et distinguer l’état de la bibliothèque du mappage réel. Tous les nombres sont hexadécimaux. BANK IN et BANK OUT doivent valoir 02 ; BYTE HEX, D3 ; WORD HEX, 5C7A ; FAILED CHECKS et FIRST FAILURE, 00. Le texte est bleu sur CGB et FC, noir sur DMG.

CALL COUNT vaut 03 : far_call, __farcall et __farcall_ptr invoquent chacun le rappel une fois.

far_data_read8: DMG
DMG
far_data_read8: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\banked_data_calls.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\banked_data_calls.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/bank.h:23

Notes de déclaration (texte source)
Read one byte through the compiler intrinsic that accepts an explicit ROM bank.

kitaqgb/lib/bank.c:21

c
u8 far_data_read8(u8 bank, const void* addr)
{
    return __farpeek8(bank, addr);
}
farptr_make

Enregistre un octet de banque et un pointeur visible par le CPU dans le BankPtr de l’appelant. Construit un descripteur, sans changer de banque ni lire les données pointées.

Syntaxe

c
void farptr_make(BankPtr* out, u8 bank, const u8* ptr);

Paramètres

out

Pointeur vers un espace accessible en écriture pour un BankPtr de trois octets. Si out est nul, aucune écriture n’a lieu.

bank

Numéro de banque ROM non signé sur 8 bits. Pour un appel, il doit correspondre au placement de la fonction ; pour une lecture, il sélectionne la source. Respectez la plage du type de cartouche.

ptr

Adresse de 16 bits visible par le CPU à stocker dans le descripteur. Elle est copiée telle quelle, sans vérifier sa validité dans la banque choisie.

Valeur renvoyée

Aucune (void).

Exemple d’utilisation

c
farptr_make(&pointer,3,payload+1); // Store a bank and address; do not read ROM.
bank_expect(pointer.bank==3 && pointer.ptr==payload+1,8);
farptr_make(0,1,home1); // A null destination is ignored.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le descripteur est réglé sur la banque 3 et payload+1. Ses lectures donnent 7A, 5C7A et les trois octets 7A 5C 96. L’appel avec une sortie nulle ne doit modifier aucun état.

Le programme complet montre comment identifier des données par une banque et une adresse proche, appeler des rappels entre banques et distinguer l’état de la bibliothèque du mappage réel. Tous les nombres sont hexadécimaux. BANK IN et BANK OUT doivent valoir 02 ; BYTE HEX, D3 ; WORD HEX, 5C7A ; FAILED CHECKS et FIRST FAILURE, 00. Le texte est bleu sur CGB et FC, noir sur DMG.

CALL COUNT vaut 03 : far_call, __farcall et __farcall_ptr invoquent chacun le rappel une fois.

farptr_make: DMG
DMG
farptr_make: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\banked_data_calls.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\banked_data_calls.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/bank.h:32

Notes de déclaration (texte source)
Store a bank/address pair without accessing ROM; a null output pointer is ignored.

kitaqgb/lib/bank.c:46

c
void farptr_make(BankPtr* out, u8 bank, const u8* ptr)
{
    if (out == 0) return;
    out->bank = bank;
    out->ptr = ptr;
}
farptr_read

Copie len octets depuis un BankPtr vers une RAM accessible en écriture. Le descripteur étant passé par valeur, le pointeur de l’appelant reste au début de la source.

Syntaxe

c
void farptr_read(BankPtr ptr, void* dst, u16 len);

Paramètres

ptr

Une valeur BankPtr contenant bank et ptr. Passez le descripteur lui-même, pas son adresse. Le descripteur de l’appelant n’est pas modifié.

dst

Destination en mémoire accessible en écriture, assez grande pour tous les octets copiés. Hors transfert de zéro octet, les adresses nulles ou invalides ne sont pas vérifiées.

len

Nombre d’octets, de 0 à 65535. Avec zéro, aucune mémoire n’est copiée, mais la sélection et le rétablissement de la banque ont bien lieu.

Valeur renvoyée

Aucune (void).

Conditions et limites

Toute la source doit être lisible dans le mappage ROM prévu, et toute la destination accessible en écriture. La copie ne passe pas automatiquement à la banque suivante, ne gère pas les chevauchements comme memmove et ne synchronise pas les écritures VRAM. Utilisez les API graphiques pour la VRAM.

Les lectures et copies distantes sont synchrones et utilisent un espace de travail partagé du compilateur. Une interruption ne doit pas y exécuter un autre transfert pendant son utilisation. Sur GB, la copie utilise aussi un emplacement HRAM partagé pour la banque sauvegardée. L’exemple exécute ces opérations depuis du code fixe, sans gestionnaire de transfert concurrent.

Ces interfaces GB transportent huit bits de banque et ne règlent pas le neuvième bit MBC5. Les règles de la cartouche restent applicables, notamment pour la banque zéro. L’exemple utilise explicitement les banques MBC5 1–3 ; ne mélangez pas cet état avec des écritures directes non suivies dans le mapper.

Exemple d’utilisation

c
farptr_read(pointer,buffer,3);
bank_expect(buffer[0]==0x7A && buffer[1]==0x5C && buffer[2]==0x96,11);
bank_expect(pointer.bank==3 && pointer.ptr==payload+1,23);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet extrait copie 3 octets via farptr_read et compare le tampon à 7A 5C 96. Le descripteur ou pointeur source de l’appelant est conservé ; le programme complet vérifie séparément une copie de longueur nulle et la restauration de la banque.

Le programme complet montre comment identifier des données par une banque et une adresse proche, appeler des rappels entre banques et distinguer l’état de la bibliothèque du mappage réel. Tous les nombres sont hexadécimaux. BANK IN et BANK OUT doivent valoir 02 ; BYTE HEX, D3 ; WORD HEX, 5C7A ; FAILED CHECKS et FIRST FAILURE, 00. Le texte est bleu sur CGB et FC, noir sur DMG.

CALL COUNT vaut 03 : far_call, __farcall et __farcall_ptr invoquent chacun le rappel une fois.

farptr_read: DMG
DMG
farptr_read: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\banked_data_calls.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\banked_data_calls.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/bank.h:38

Notes de déclaration (texte source)
Copy len bytes from a bank-qualified pointer; dst must have room for the full copy.

kitaqgb/lib/bank.c:66

c
void farptr_read(BankPtr ptr, void* dst, u16 len)
{
    __farmemcpy(dst, ptr.bank, ptr.ptr, len);
}
farptr_read16

Lit un mot little-endian dans la banque à l’adresse contenues dans un BankPtr. Le descripteur est passé par valeur et son pointeur n’avance pas.

Syntaxe

c
u16 farptr_read16(BankPtr ptr);

Paramètres

ptr

Une valeur BankPtr contenant bank et ptr. Passez le descripteur lui-même, pas son adresse. Le descripteur de l’appelant n’est pas modifié.

Valeur renvoyée

Le mot little-endian lu, sous forme de u16 (0–65535).

Conditions et limites

L’octet ou le mot entier doit être lisible dans le mappage CPU sélectionné. Ces lectures ne valident pas les pointeurs, ne bornent pas les adresses et ne passent pas automatiquement à une autre banque à la limite d’une fenêtre. Un mot exige deux octets consécutifs valides.

Les lectures et copies distantes sont synchrones et utilisent un espace de travail partagé du compilateur. Une interruption ne doit pas y exécuter un autre transfert pendant son utilisation. Sur GB, la copie utilise aussi un emplacement HRAM partagé pour la banque sauvegardée. L’exemple exécute ces opérations depuis du code fixe, sans gestionnaire de transfert concurrent.

Ces interfaces GB transportent huit bits de banque et ne règlent pas le neuvième bit MBC5. Les règles de la cartouche restent applicables, notamment pour la banque zéro. L’exemple utilise explicitement les banques MBC5 1–3 ; ne mélangez pas cet état avec des écritures directes non suivies dans le mapper.

Exemple d’utilisation

c
bank_expect(farptr_read16(pointer)==0x5C7A,10);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet extrait utilise farptr_read16 pour lire pointer.ptr dans la banque 3 et vérifie 5C7A. Le programme complet lit aussi home2 avec un pointeur proche pour confirmer la restauration de la banque 2.

Le programme complet montre comment identifier des données par une banque et une adresse proche, appeler des rappels entre banques et distinguer l’état de la bibliothèque du mappage réel. Tous les nombres sont hexadécimaux. BANK IN et BANK OUT doivent valoir 02 ; BYTE HEX, D3 ; WORD HEX, 5C7A ; FAILED CHECKS et FIRST FAILURE, 00. Le texte est bleu sur CGB et FC, noir sur DMG.

CALL COUNT vaut 03 : far_call, __farcall et __farcall_ptr invoquent chacun le rappel une fois.

farptr_read16: DMG
DMG
farptr_read16: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\banked_data_calls.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\banked_data_calls.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/bank.h:36

Notes de déclaration (texte source)
Read a 16-bit value using both components of the bank-qualified pointer.

kitaqgb/lib/bank.c:60

c
u16 farptr_read16(BankPtr ptr)
{
    return __farpeek16(ptr.bank, ptr.ptr);
}
farptr_read8

Lit un octet à partir des deux champs d’un BankPtr passé par valeur. Le descripteur fournit la banque absente d’un pointeur proche ordinaire.

Syntaxe

c
u8 farptr_read8(BankPtr ptr);

Paramètres

ptr

Une valeur BankPtr contenant bank et ptr. Passez le descripteur lui-même, pas son adresse. Le descripteur de l’appelant n’est pas modifié.

Valeur renvoyée

L’octet lu, sous forme de u8 (0–255).

Conditions et limites

L’octet ou le mot entier doit être lisible dans le mappage CPU sélectionné. Ces lectures ne valident pas les pointeurs, ne bornent pas les adresses et ne passent pas automatiquement à une autre banque à la limite d’une fenêtre. Un mot exige deux octets consécutifs valides.

Les lectures et copies distantes sont synchrones et utilisent un espace de travail partagé du compilateur. Une interruption ne doit pas y exécuter un autre transfert pendant son utilisation. Sur GB, la copie utilise aussi un emplacement HRAM partagé pour la banque sauvegardée. L’exemple exécute ces opérations depuis du code fixe, sans gestionnaire de transfert concurrent.

Ces interfaces GB transportent huit bits de banque et ne règlent pas le neuvième bit MBC5. Les règles de la cartouche restent applicables, notamment pour la banque zéro. L’exemple utilise explicitement les banques MBC5 1–3 ; ne mélangez pas cet état avec des écritures directes non suivies dans le mapper.

Exemple d’utilisation

c
bank_expect(farptr_read8(pointer)==0x7A,9);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet extrait utilise farptr_read8 pour lire pointer.ptr dans la banque 3 et vérifie 7A. Le programme complet lit aussi home2 avec un pointeur proche pour confirmer la restauration de la banque 2.

Le programme complet montre comment identifier des données par une banque et une adresse proche, appeler des rappels entre banques et distinguer l’état de la bibliothèque du mappage réel. Tous les nombres sont hexadécimaux. BANK IN et BANK OUT doivent valoir 02 ; BYTE HEX, D3 ; WORD HEX, 5C7A ; FAILED CHECKS et FIRST FAILURE, 00. Le texte est bleu sur CGB et FC, noir sur DMG.

CALL COUNT vaut 03 : far_call, __farcall et __farcall_ptr invoquent chacun le rappel une fois.

farptr_read8: DMG
DMG
farptr_read8: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\banked_data_calls.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\banked_data_calls.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/bank.h:34

Notes de déclaration (texte source)
Read one byte using both components of the bank-qualified pointer.

kitaqgb/lib/bank.c:54

c
u8 farptr_read8(BankPtr ptr)
{
    return __farpeek8(ptr.bank, ptr.ptr);
}

camera.h — Coordonnées du monde et zones visibles

Gère les positions, cibles et limites de caméra Q8.8 et convertit les coordonnées monde/écran. Choisissez des objets Camera8_8 détenus par l’appelant ou l’API en minuscules pour une caméra partagée.

Camera_Add

Ajoute les déplacements Q8.8 à la position courante, puis applique les limites activées.

Syntaxe

c
void Camera_Add(Camera8_8* cam, s16 dfx, s16 dfy);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

dfx

Déplacement Q8.8 signé ; 256 correspond à un pixel.

dfy

Déplacement Q8.8 signé ; 256 correspond à un pixel.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon.

Exemple d’utilisation

c
Camera_Add(&cam,256,512);result[13]=cam.fx;result[14]=cam.fy;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_Add: DMG
DMG
Camera_Add: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_Add: DMG
DMG
Camera_Add: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:34

Notes de déclaration (texte source)
Add Q8.8 deltas and clamp afterward. Keep the intermediate sums within s16;
clamping cannot repair arithmetic that already overflowed.

kitaqgb/lib/camera.c:79

c
void Camera_Add(Camera8_8* cam, s16 dfx, s16 dfy)
{
    cam->fx += dfx;
    cam->fy += dfy;
    Camera_ApplyBounds(cam);
}
camera_apply

Applique immédiatement la position courante de la caméra partagée au défilement du fond.

Syntaxe

c
void camera_apply();

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Aucune attente VBlank n’est effectuée ; synchronisez l’appel si vous ne voulez pas de modification en cours de trame. Les fractions négatives sont arrondies vers le bas : −1/256 devient −1 pixel, soit la valeur 255 dans le registre.

Exemple d’utilisation

c
camera_apply();result[31]=M_SCX;result[32]=M_SCY;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

camera_apply: DMG
DMG
camera_apply: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

camera_apply: DMG
DMG
camera_apply: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:64

Notes de déclaration (texte source)
Write the shared camera's current integer position to background scroll registers.

kitaqgb/lib/camera.c:179

c
void camera_apply()
{
    Camera_ApplyBg(&camera_default);
}
Camera_ApplyBg

Arrondit la position de la caméra vers le bas en pixels entiers et écrit immédiatement ses huit bits de poids faible dans le défilement du fond.

Syntaxe

c
void Camera_ApplyBg(const Camera8_8* cam);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Aucune attente VBlank n’est effectuée ; synchronisez l’appel si vous ne voulez pas de modification en cours de trame. Les fractions négatives sont arrondies vers le bas : −1/256 devient −1 pixel, soit la valeur 255 dans le registre.

Exemple d’utilisation

c
Camera_ApplyBg(&cam);result[21]=M_SCX;result[22]=M_SCY;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_ApplyBg: DMG
DMG
Camera_ApplyBg: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_ApplyBg: DMG
DMG
Camera_ApplyBg: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:40

Notes de déclaration (texte source)
Discard fractional bits and write the low eight integer bits to background scroll registers.

kitaqgb/lib/camera.c:109

c
void Camera_ApplyBg(const Camera8_8* cam)
{
    __scroll_bg_set((u8)(cam->fx >> 8), (u8)(cam->fy >> 8));
}
Camera_ApplyBgBuffered

Arrondit la position de la caméra vers le bas en pixels entiers et la prépare comme prochaine valeur de défilement du fond.

Syntaxe

c
void Camera_ApplyBgBuffered(const Camera8_8* cam);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Le matériel et les valeurs courantes suivies restent inchangés jusqu’à Scroll_Flush ou __scroll_flush. Cet appel n’attend pas VBlank.

Exemple d’utilisation

c
Camera_Set(&cam,2048,4096);Camera_ApplyBgBuffered(&cam);result[23]=M_SCX;Scroll_Flush();result[24]=M_SCX;result[25]=M_SCY;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_ApplyBgBuffered: DMG
DMG
Camera_ApplyBgBuffered: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_ApplyBgBuffered: DMG
DMG
Camera_ApplyBgBuffered: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:42

Notes de déclaration (texte source)
Convert the Q8.8 position to byte scroll values and stage them for a later flush.

kitaqgb/lib/camera.c:115

c
void Camera_ApplyBgBuffered(const Camera8_8* cam)
{
    __scroll_bg_set_buffered((u8)(cam->fx >> 8), (u8)(cam->fy >> 8));
}
camera_clamp

Applique à la caméra partagée les limites calculées par la différence entre monde et écran.

Syntaxe

c
void camera_clamp(u16 world_w_px, u16 world_h_px, u8 screen_w_px, u8 screen_h_px);

Paramètres

world_w_px

Dimension du monde en pixels entiers ; l’excédent positif sur l’écran doit rester entre 0 et 127.

world_h_px

Dimension du monde en pixels entiers ; l’excédent positif sur l’écran doit rester entre 0 et 127.

screen_w_px

Dimension de la zone visible en pixels entiers ; si elle est au moins égale à celle du monde, la course sur cet axe est nulle.

screen_h_px

Dimension de la zone visible en pixels entiers ; si elle est au moins égale à celle du monde, la course sur cet axe est nulle.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Un monde plus petit que la zone visible donne une course nulle. Un écart positif de 128 ou plus dépasse la plage Q8.8 signée lors de la conversion. Les paramètres u16 ne signifient pas que la caméra peut parcourir des mondes arbitrairement grands. Ces appels partagent une même caméra ; utilisez l’API commençant par une majuscule pour des objets caméra indépendants. Les positions converties de pixels entiers en Q8.8 doivent être comprises entre −128 et 127.

Exemple d’utilisation

c
camera_clamp(176,160,160,144);result[29]=camera_world_to_screen_x(100);result[30]=camera_world_to_screen_y(90);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

camera_clamp: DMG
DMG
camera_clamp: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

camera_clamp: DMG
DMG
camera_clamp: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:62

Notes de déclaration (texte source)
Derive and apply world/screen bounds to the shared convenience camera.

kitaqgb/lib/camera.c:173

c
void camera_clamp(u16 world_w_px, u16 world_h_px, u8 screen_w_px, u8 screen_h_px)
{
    Camera_ClampToSize(&camera_default, world_w_px, world_h_px, screen_w_px, screen_h_px);
}
Camera_ClampToSize

Soustrait les dimensions de l’écran à celles du monde et installe les limites de caméra non négatives obtenues.

Syntaxe

c
void Camera_ClampToSize(Camera8_8* cam, u16 world_w_px, u16 world_h_px, u8 screen_w_px, u8 screen_h_px);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

world_w_px

Dimension du monde en pixels entiers ; l’excédent positif sur l’écran doit rester entre 0 et 127.

world_h_px

Dimension du monde en pixels entiers ; l’excédent positif sur l’écran doit rester entre 0 et 127.

screen_w_px

Dimension de la zone visible en pixels entiers ; si elle est au moins égale à celle du monde, la course sur cet axe est nulle.

screen_h_px

Dimension de la zone visible en pixels entiers ; si elle est au moins égale à celle du monde, la course sur cet axe est nulle.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Un monde plus petit que la zone visible donne une course nulle. Un écart positif de 128 ou plus dépasse la plage Q8.8 signée lors de la conversion. Les paramètres u16 ne signifient pas que la caméra peut parcourir des mondes arbitrairement grands.

Exemple d’utilisation

c
Camera_ClampToSize(&cam,176,160,160,144);result[15]=cam.max_fx;result[16]=cam.max_fy;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_ClampToSize: DMG
DMG
Camera_ClampToSize: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_ClampToSize: DMG
DMG
Camera_ClampToSize: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:46

Notes de déclaration (texte source)
Derive nonnegative camera extents from world minus screen size, then convert
them to Q8.8 bounds. Extents must fit signed Q8.8; the u16 input type does
not imply support for arbitrary large worlds.

kitaqgb/lib/camera.c:123

c
void Camera_ClampToSize(Camera8_8* cam, u16 world_w_px, u16 world_h_px, u8 screen_w_px, u8 screen_h_px)
{
    s16 max_x = 0;
    s16 max_y = 0;

    if (world_w_px > screen_w_px) max_x = (s16)((u16)(world_w_px - screen_w_px) << 8);
    if (world_h_px > screen_h_px) max_y = (s16)((u16)(world_h_px - screen_h_px) << 8);
    Camera_SetBounds(cam, (s16)0, (s16)0, max_x, max_y);
}
Camera_ClearBounds

Désactive la limitation sans modifier la position, la cible ni les bornes enregistrées.

Syntaxe

c
void Camera_ClearBounds(Camera8_8* cam);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon.

Exemple d’utilisation

c
Camera_ClearBounds(&cam);result[12]=cam.use_bounds;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_ClearBounds: DMG
DMG
Camera_ClearBounds: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_ClearBounds: DMG
DMG
Camera_ClearBounds: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:31

Notes de déclaration (texte source)
Disable clamping while retaining the stored bounds and current position.

kitaqgb/lib/camera.c:72

c
void Camera_ClearBounds(Camera8_8* cam)
{
    cam->use_bounds = 0;
}
Camera_ClearTarget

Désactive le suivi en conservant la position courante et la cible enregistrée.

Syntaxe

c
void Camera_ClearTarget(Camera8_8* cam);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon.

Exemple d’utilisation

c
Camera_ClearTarget(&cam);result[8]=cam.use_target;result[9]=cam.target_fx;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_ClearTarget: DMG
DMG
Camera_ClearTarget: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_ClearTarget: DMG
DMG
Camera_ClearTarget: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:27

Notes de déclaration (texte source)
Disable target following without moving the camera or erasing the stored target.

kitaqgb/lib/camera.c:55

c
void Camera_ClearTarget(Camera8_8* cam)
{
    cam->use_target = 0;
}
camera_follow_xy

Déplace immédiatement la caméra partagée pour qu’un point du monde apparaisse au point d’ancrage demandé à l’écran.

Syntaxe

c
void camera_follow_xy(s16 x, s16 y, u8 screen_cx, u8 screen_cy);

Paramètres

x

Coordonnée X du monde en pixels entiers ; le résultat et la différence intermédiaire doivent tenir dans s16.

y

Coordonnée Y du monde en pixels entiers ; le résultat et la différence intermédiaire doivent tenir dans s16.

screen_cx

Coordonnée du point d’ancrage à l’écran en pixels entiers, de 0 à 255.

screen_cy

Coordonnée du point d’ancrage à l’écran en pixels entiers, de 0 à 255.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon. Ces appels partagent une même caméra ; utilisez l’API commençant par une majuscule pour des objets caméra indépendants. Les positions converties de pixels entiers en Q8.8 doivent être comprises entre −128 et 127.

Exemple d’utilisation

c
camera_follow_xy(100,90,80,72);result[27]=camera_world_to_screen_x(100);result[28]=camera_world_to_screen_y(90);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

camera_follow_xy: DMG
DMG
camera_follow_xy: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

camera_follow_xy: DMG
DMG
camera_follow_xy: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:60

Notes de déclaration (texte source)
Position the shared camera so the world point appears at the requested screen
anchor. This is an immediate move, not the smoothed target-following path.

kitaqgb/lib/camera.c:165

c
void camera_follow_xy(s16 x, s16 y, u8 screen_cx, u8 screen_cy)
{
    s16 cx = (s16)(x - screen_cx);
    s16 cy = (s16)(y - screen_cy);
    Camera_Set(&camera_default, (s16)(cx << 8), (s16)(cy << 8));
}
Camera_Init

Met la position, la cible et les limites à zéro, puis désactive le suivi et la limitation aux bornes.

Syntaxe

c
void Camera_Init(Camera8_8* cam);

Paramètres

cam

Camera8_8 accessible en écriture à initialiser ; ne doit pas être NULL.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon.

Exemple d’utilisation

c
Camera_Init(&cam);result[0]=cam.fx;result[1]=cam.use_target;result[2]=cam.use_bounds;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_Init: DMG
DMG
Camera_Init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_Init: DMG
DMG
Camera_Init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:21

Notes de déclaration (texte source)
Zero all position/target/bound fields and disable targeting and bounds.

kitaqgb/lib/camera.c:24

c
void Camera_Init(Camera8_8* cam)
{
    cam->fx = 0;
    cam->fy = 0;
    cam->target_fx = 0;
    cam->target_fy = 0;
    cam->min_fx = 0;
    cam->min_fy = 0;
    cam->max_fx = 0;
    cam->max_fy = 0;
    cam->use_target = 0;
    cam->use_bounds = 0;
}
Camera_ScreenToWorldX

Ajoute la composante entière X de la caméra au X entier de l’écran pour obtenir le X du monde.

Syntaxe

c
s16 Camera_ScreenToWorldX(const Camera8_8* cam, s16 screen_x);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

screen_x

Coordonnée X de l’écran en pixels entiers ; le résultat et la différence intermédiaire doivent tenir dans s16.

Valeur renvoyée

Renvoie la coordonnée convertie en pixels entiers sous forme de s16 ; ne teste pas sa visibilité et ne la tronque pas aux limites de l’écran.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon.

Exemple d’utilisation

c
result[19]=Camera_ScreenToWorldX(&cam,27);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_ScreenToWorldX: DMG
DMG
Camera_ScreenToWorldX: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_ScreenToWorldX: DMG
DMG
Camera_ScreenToWorldX: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:52

Notes de déclaration (texte source)
Convert integer-pixel screen X back to world X using the camera's integer component.

kitaqgb/lib/camera.c:146

c
s16 Camera_ScreenToWorldX(const Camera8_8* cam, s16 screen_x)
{
    return (s16)(screen_x + (cam->fx >> 8));
}
Camera_ScreenToWorldY

Ajoute la composante entière Y de la caméra au Y entier de l’écran pour obtenir le Y du monde.

Syntaxe

c
s16 Camera_ScreenToWorldY(const Camera8_8* cam, s16 screen_y);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

screen_y

Coordonnée Y de l’écran en pixels entiers ; le résultat et la différence intermédiaire doivent tenir dans s16.

Valeur renvoyée

Renvoie la coordonnée convertie en pixels entiers sous forme de s16 ; ne teste pas sa visibilité et ne la tronque pas aux limites de l’écran.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon.

Exemple d’utilisation

c
result[20]=Camera_ScreenToWorldY(&cam,24);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_ScreenToWorldY: DMG
DMG
Camera_ScreenToWorldY: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_ScreenToWorldY: DMG
DMG
Camera_ScreenToWorldY: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:54

Notes de déclaration (texte source)
Convert integer-pixel screen Y back to world Y using the camera's integer component.

kitaqgb/lib/camera.c:152

c
s16 Camera_ScreenToWorldY(const Camera8_8* cam, s16 screen_y)
{
    return (s16)(screen_y + (cam->fy >> 8));
}
Camera_Set

Remplace la position courante de la caméra et la ramène immédiatement dans les limites si elles sont activées.

Syntaxe

c
void Camera_Set(Camera8_8* cam, s16 fx, s16 fy);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

fx

Coordonnée X. Coordonnée Q8.8 signée : 256 correspond à un pixel ; la plage va de −128 à 127+255/256 pixels.

fy

Coordonnée Y. Coordonnée Q8.8 signée : 256 correspond à un pixel ; la plage va de −128 à 127+255/256 pixels.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon.

Exemple d’utilisation

c
Camera_Set(&cam,2560,5120);result[3]=cam.fx;result[4]=cam.fy;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_Set: DMG
DMG
Camera_Set: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_Set: DMG
DMG
Camera_Set: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:23

Notes de déclaration (texte source)
Replace the current Q8.8 position and immediately apply enabled bounds.

kitaqgb/lib/camera.c:39

c
void Camera_Set(Camera8_8* cam, s16 fx, s16 fy)
{
    cam->fx = fx;
    cam->fy = fy;
    Camera_ApplyBounds(cam);
}
camera_set

Déplace la caméra partagée en coordonnées de pixels entiers et applique ses limites activées.

Syntaxe

c
void camera_set(s16 x, s16 y);

Paramètres

x

Coordonnée X du monde en pixels entiers ; le résultat et la différence intermédiaire doivent tenir dans s16.

y

Coordonnée Y du monde en pixels entiers ; le résultat et la différence intermédiaire doivent tenir dans s16.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon. Ces appels partagent une même caméra ; utilisez l’API commençant par une majuscule pour des objets caméra indépendants. Les positions converties de pixels entiers en Q8.8 doivent être comprises entre −128 et 127.

Exemple d’utilisation

c
camera_set(5,6);result[26]=camera_world_to_screen_x(20);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

camera_set: DMG
DMG
camera_set: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

camera_set: DMG
DMG
camera_set: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:57

Notes de déclaration (texte source)
Set the shared camera from integer pixels, converting to the representable Q8.8 range.

kitaqgb/lib/camera.c:158

c
void camera_set(s16 x, s16 y)
{
    Camera_Set(&camera_default, (s16)(x << 8), (s16)(y << 8));
}
Camera_SetBounds

Installe les coordonnées minimales et maximales, active la limitation et l’applique immédiatement à la position courante.

Syntaxe

c
void Camera_SetBounds(Camera8_8* cam, s16 min_fx, s16 min_fy, s16 max_fx, s16 max_fy);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

min_fx

Coordonnée X minimale. Coordonnée Q8.8 signée : 256 correspond à un pixel ; la plage va de −128 à 127+255/256 pixels.

min_fy

Coordonnée Y minimale. Coordonnée Q8.8 signée : 256 correspond à un pixel ; la plage va de −128 à 127+255/256 pixels.

max_fx

Coordonnée X maximale. Coordonnée Q8.8 signée : 256 correspond à un pixel ; la plage va de −128 à 127+255/256 pixels.

max_fy

Coordonnée Y maximale. Coordonnée Q8.8 signée : 256 correspond à un pixel ; la plage va de −128 à 127+255/256 pixels.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Fournissez un minimum ≤ maximum sur chaque axe ; les bornes ne sont pas réordonnées. La cible enregistrée n’est pas ramenée dans ces limites.

Exemple d’utilisation

c
Camera_SetBounds(&cam,0,0,3072,3584);result[10]=cam.fx;result[11]=cam.fy;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_SetBounds: DMG
DMG
Camera_SetBounds: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_SetBounds: DMG
DMG
Camera_SetBounds: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:29

Notes de déclaration (texte source)
Install ordered Q8.8 bounds, enable them and clamp the current position immediately.

kitaqgb/lib/camera.c:61

c
void Camera_SetBounds(Camera8_8* cam, s16 min_fx, s16 min_fy, s16 max_fx, s16 max_fy)
{
    cam->min_fx = min_fx;
    cam->min_fy = min_fy;
    cam->max_fx = max_fx;
    cam->max_fy = max_fy;
    cam->use_bounds = 1;
    Camera_ApplyBounds(cam);
}
Camera_SetTarget

Enregistre une cible et active le suivi sans déplacer la position courante.

Syntaxe

c
void Camera_SetTarget(Camera8_8* cam, s16 fx, s16 fy);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

fx

Coordonnée X. Coordonnée Q8.8 signée : 256 correspond à un pixel ; la plage va de −128 à 127+255/256 pixels.

fy

Coordonnée Y. Coordonnée Q8.8 signée : 256 correspond à un pixel ; la plage va de −128 à 127+255/256 pixels.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon.

Exemple d’utilisation

c
Camera_SetTarget(&cam,4608,3072);result[5]=cam.use_target;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_SetTarget: DMG
DMG
Camera_SetTarget: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_SetTarget: DMG
DMG
Camera_SetTarget: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:25

Notes de déclaration (texte source)
Store a Q8.8 target and enable subsequent step-toward-target updates.

kitaqgb/lib/camera.c:47

c
void Camera_SetTarget(Camera8_8* cam, s16 fx, s16 fy)
{
    cam->target_fx = fx;
    cam->target_fy = fy;
    cam->use_target = 1;
}
Camera_StepTowardTarget

Se rapproche de la cible d’une fraction de la distance restante, obtenue par décalage à droite ; ne fait rien si le suivi est désactivé.

Syntaxe

c
void Camera_StepTowardTarget(Camera8_8* cam, u8 shift);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

shift

Exposant de la puissance de deux qui divise l’écart : 0 utilise l’écart entier, 1 sa moitié. Les valeurs supérieures à 7 sont ramenées à 7.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Un petit écart positif peut être tronqué à zéro ; un décalage arithmétique à droite peut transformer un petit écart négatif en −1. L’égalité avec la cible est testée avant la limitation. Une cible hors limites peut donc maintenir le suivi actif, ou le désactiver alors que la position finale limitée diffère de la cible.

Exemple d’utilisation

c
Camera_StepTowardTarget(&cam,1);result[6]=cam.fx;result[7]=cam.fy;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_StepTowardTarget: DMG
DMG
Camera_StepTowardTarget: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_StepTowardTarget: DMG
DMG
Camera_StepTowardTarget: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:38

Notes de déclaration (texte source)
Move by the signed target delta shifted by 0..7 bits, then apply bounds.
Quantization can make a small delta produce no movement; only exact equality
clears targeting, and a target outside the bounds may remain active indefinitely.

kitaqgb/lib/camera.c:89

c
void Camera_StepTowardTarget(Camera8_8* cam, u8 shift)
{
    s16 dx;
    s16 dy;

    if (cam->use_target == 0) return;
    if (shift > 7) shift = 7;

    // Keep target-minus-position differences within s16 as well as the individual positions.
    dx = cam->target_fx - cam->fx;
    dy = cam->target_fy - cam->fy;

    if (dx != 0) cam->fx += (dx >> shift);
    if (dy != 0) cam->fy += (dy >> shift);

    if (cam->fx == cam->target_fx && cam->fy == cam->target_fy) cam->use_target = 0;
    Camera_ApplyBounds(cam);
}
camera_world_to_screen_x

Convertit le X du monde en X de l’écran en soustrayant la composante entière X de la caméra partagée.

Syntaxe

c
s16 camera_world_to_screen_x(s16 world_x);

Paramètres

world_x

Coordonnée X du monde en pixels entiers ; le résultat et la différence intermédiaire doivent tenir dans s16.

Valeur renvoyée

Renvoie la coordonnée convertie en pixels entiers sous forme de s16 ; ne teste pas sa visibilité et ne la tronque pas aux limites de l’écran.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon. Ces appels partagent une même caméra ; utilisez l’API commençant par une majuscule pour des objets caméra indépendants. Les positions converties de pixels entiers en Q8.8 doivent être comprises entre −128 et 127.

Exemple d’utilisation

c
result[33]=camera_world_to_screen_x(20);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

camera_world_to_screen_x: DMG
DMG
camera_world_to_screen_x: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

camera_world_to_screen_x: DMG
DMG
camera_world_to_screen_x: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:66

Notes de déclaration (texte source)
Convert integer-pixel world X using the shared convenience camera.

kitaqgb/lib/camera.c:185

c
s16 camera_world_to_screen_x(s16 world_x)
{
    return Camera_WorldToScreenX(&camera_default, world_x);
}
camera_world_to_screen_y

Convertit le Y du monde en Y de l’écran en soustrayant la composante entière Y de la caméra partagée.

Syntaxe

c
s16 camera_world_to_screen_y(s16 world_y);

Paramètres

world_y

Coordonnée Y du monde en pixels entiers ; le résultat et la différence intermédiaire doivent tenir dans s16.

Valeur renvoyée

Renvoie la coordonnée convertie en pixels entiers sous forme de s16 ; ne teste pas sa visibilité et ne la tronque pas aux limites de l’écran.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon. Ces appels partagent une même caméra ; utilisez l’API commençant par une majuscule pour des objets caméra indépendants. Les positions converties de pixels entiers en Q8.8 doivent être comprises entre −128 et 127.

Exemple d’utilisation

c
result[34]=camera_world_to_screen_y(20);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

camera_world_to_screen_y: DMG
DMG
camera_world_to_screen_y: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

camera_world_to_screen_y: DMG
DMG
camera_world_to_screen_y: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:68

Notes de déclaration (texte source)
Convert integer-pixel world Y using the shared convenience camera.

kitaqgb/lib/camera.c:191

c
s16 camera_world_to_screen_y(s16 world_y)
{
    return Camera_WorldToScreenY(&camera_default, world_y);
}
Camera_WorldToScreenX

Soustrait la composante entière X de la caméra à une coordonnée X entière du monde pour obtenir le X à l’écran.

Syntaxe

c
s16 Camera_WorldToScreenX(const Camera8_8* cam, s16 world_x);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

world_x

Coordonnée X du monde en pixels entiers ; le résultat et la différence intermédiaire doivent tenir dans s16.

Valeur renvoyée

Renvoie la coordonnée convertie en pixels entiers sous forme de s16 ; ne teste pas sa visibilité et ne la tronque pas aux limites de l’écran.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon.

Exemple d’utilisation

c
result[17]=Camera_WorldToScreenX(&cam,40);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_WorldToScreenX: DMG
DMG
Camera_WorldToScreenX: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_WorldToScreenX: DMG
DMG
Camera_WorldToScreenX: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:48

Notes de déclaration (texte source)
Convert an integer-pixel world X by subtracting the camera's integer X component.

kitaqgb/lib/camera.c:134

c
s16 Camera_WorldToScreenX(const Camera8_8* cam, s16 world_x)
{
    return (s16)(world_x - (cam->fx >> 8));
}
Camera_WorldToScreenY

Soustrait la composante entière Y de la caméra à une coordonnée Y entière du monde pour obtenir le Y à l’écran.

Syntaxe

c
s16 Camera_WorldToScreenY(const Camera8_8* cam, s16 world_y);

Paramètres

cam

Pointeur valide vers un Camera8_8 initialisé et détenu par l’appelant.

world_y

Coordonnée Y du monde en pixels entiers ; le résultat et la différence intermédiaire doivent tenir dans s16.

Valeur renvoyée

Renvoie la coordonnée convertie en pixels entiers sous forme de s16 ; ne teste pas sa visibilité et ne la tronque pas aux limites de l’écran.

Conditions et limites

Les coordonnées ont huit bits fractionnaires. Gardez les positions, les cibles et les sommes ou différences intermédiaires dans la plage de s16. Mettez l’affichage à jour séparément avec Camera_ApplyBg ou en appliquant les valeurs mises en tampon.

Exemple d’utilisation

c
result[18]=Camera_WorldToScreenY(&cam,40);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente le suivi Q8.8, les limites et la conversion de coordonnées. Le suivi donne X/Y=3584/4096 ; les limites ramènent ces valeurs à 3072/3584. BG X reste à 13 tant que la valeur est en attente, puis passe à 8 après application. L’image supplémentaire montre une caméra en (8,16) déplaçant un rectangle de 32×24 du monde (32,32) vers l’écran (24,16).

Camera_WorldToScreenY: DMG
DMG
Camera_WorldToScreenY: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Camera_WorldToScreenY: DMG
DMG
Camera_WorldToScreenY: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/camera.h:50

Notes de déclaration (texte source)
Convert an integer-pixel world Y by subtracting the camera's integer Y component.

kitaqgb/lib/camera.c:140

c
s16 Camera_WorldToScreenY(const Camera8_8* cam, s16 world_y)
{
    return (s16)(world_y - (cam->fy >> 8));
}

cgb_palette.h — Palettes BG et OBJ de la CGB

cgb_palette.h et cgb_palette.c proposent le compactage RGB15 et la mise à jour immédiate des palettes CGB. Utilisez BG pour fond/fenêtre et OBJ pour sprites. Les fonctions de couleur ou de composantes modifient une couleur ; les plages écrivent des mots consécutifs ; une palette entière écrit quatre mots. Les plages raw utilisent des emplacements de couleur absolus, les intrinsèques de registre des positions d'octet. Attribuez la palette par la carte ou l'OAM. Incluez l'implémentation une seule fois, comme dans l'exemple complet.

Les écritures de palette et de registres protégés n'écrivent rien en mode DMG. Safe désigne ici le contrôle du mode CGB, pas une attente d'accès PPU ni une section critique. Configurez avec le LCD éteint ou effectuez une mise à jour assez courte pendant une phase accessible. Aucune attente VBlank ni protection contre les interruptions n'est ajoutée.

Les palettes BG/fenêtre et OBJ sont stockées séparément. Les écritures de la bibliothèque activent l'incrément et laissent le registre d'indice modifié. La couleur OBJ zéro reste transparente au rendu des sprites, même si ses octets peuvent être écrits et lus.

cgb_bg_color

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Écrit immédiatement une couleur RGB15 compactée dans les palettes de fond/fenêtre. Les indices de palette et de couleur désignent l'un des 32 emplacements ; ni les motifs ni la palette attribuée à une tuile ne changent.

Syntaxe

c
void cgb_bg_color(u8 palette_index, u8 color_index, u16 rgb15);

Paramètres

palette_index

Numéro de palette, 0–7 ; seuls les trois bits faibles sont utilisés (& 7).

color_index

Indice de couleur dans la palette, 0–3 ; seuls les deux bits faibles sont utilisés (& 3).

rgb15

Couleur RGB sur 15 bits compactée, normalement 0–32767. Les deux octets du u16 sont écrits, faible puis fort ; la bibliothèque n'efface pas explicitement le bit 15. Utilisez CGB_RGB15 ou cgb_rgb15 pour la construire.

Valeur renvoyée

Aucune (void).

Conditions et limites

Les écritures de palette et de registres protégés n'écrivent rien en mode DMG. Safe désigne ici le contrôle du mode CGB, pas une attente d'accès PPU ni une section critique. Configurez avec le LCD éteint ou effectuez une mise à jour assez courte pendant une phase accessible. Aucune attente VBlank ni protection contre les interruptions n'est ajoutée.

Les palettes BG/fenêtre et OBJ sont stockées séparément. Les écritures de la bibliothèque activent l'incrément et laissent le registre d'indice modifié. La couleur OBJ zéro reste transparente au rendu des sprites, même si ses octets peuvent être écrits et lus.

Exemple d’utilisation

c
cgb_bg_color(1,3,31); // Red background color 3 of palette 1.
expect_color(0,7,31);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

cgb_bg_color: --cgb=cgb / DMG
--cgb=cgb / DMG
cgb_bg_color: --cgb=cgb / CGB
--cgb=cgb / CGB
cgb_bg_color: --cgb=dmg / DMG
--cgb=dmg / DMG
cgb_bg_color: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_palette.h:22

Notes de déclaration (texte source)
Set one background color through the indexed palette wrapper.

kitaqgb/lib/cgb_palette.c:110

c
void cgb_bg_color(u8 palette_index, u8 color_index, u16 rgb15)
{
    cgb__write_color_bg_raw(cgb__palette_color_slot(palette_index, color_index), rgb15);
}
cgb_bg_colors

Écrit des mots RGB15 consécutifs dans les palettes de fond/fenêtre, à partir des indices indiqués. La plage peut franchir une limite de palette de quatre couleurs, mais s'arrête à la fin des 32 emplacements.

Syntaxe

c
void cgb_bg_colors(u8 palette_index, u8 start_color_index, const u16* colors, u8 color_count);

Paramètres

palette_index

Numéro de palette, 0–7 ; seuls les trois bits faibles sont utilisés (& 7).

start_color_index

Indice de couleur dans la palette, 0–3 ; seuls les deux bits faibles sont utilisés (& 3).

colors

const u16* lisible contenant les mots de couleur nécessaires. Les données sont lues pendant l'appel, sans mise en file. Gardez la source et sa banque ROM accessibles ; aucun changement de banque n'est automatique. Un pointeur nul n'entraîne aucune écriture.

color_count

Nombre de mots de couleur, et non d'octets, en u8 (0–255). Zéro ne fait rien. La quantité est limitée à 32 - emplacement_initial_normalisé ; seuls ces mots source sont lus.

Valeur renvoyée

Aucune (void).

Conditions et limites

Les écritures de palette et de registres protégés n'écrivent rien en mode DMG. Safe désigne ici le contrôle du mode CGB, pas une attente d'accès PPU ni une section critique. Configurez avec le LCD éteint ou effectuez une mise à jour assez courte pendant une phase accessible. Aucune attente VBlank ni protection contre les interruptions n'est ajoutée.

Les palettes BG/fenêtre et OBJ sont stockées séparément. Les écritures de la bibliothèque activent l'incrément et laissent le registre d'indice modifié. La couleur OBJ zéro reste transparente au rendu des sprites, même si ses octets peuvent être écrits et lus.

Exemple d’utilisation

c
cgb_bg_colors(3,2,tail_green,2); // Two color words; color 3 becomes green.
expect_color(0,14,0); expect_color(0,15,992);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

cgb_bg_colors: --cgb=cgb / DMG
--cgb=cgb / DMG
cgb_bg_colors: --cgb=cgb / CGB
--cgb=cgb / CGB
cgb_bg_colors: --cgb=dmg / DMG
--cgb=dmg / DMG
cgb_bg_colors: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_palette.h:32

Notes de déclaration (texte source)
Write background colors starting at the indexed slot. The range may cross
palette boundaries and is clamped only at the end of all 32 slots.

kitaqgb/lib/cgb_palette.c:135

c
void cgb_bg_colors(u8 palette_index, u8 start_color_index, const u16* colors, u8 color_count)
{
    cgb__write_colors_bg_raw(cgb__palette_color_slot(palette_index, start_color_index), colors, color_count);
}
cgb_bg_colors_raw

Écrit des mots RGB15 consécutifs dans les palettes de fond/fenêtre à partir d'un emplacement absolu. Le départ est un seul indice de 0 à 31, et non une paire palette/couleur. Les données sont des mots de couleur, pas des octets de motifs.

Syntaxe

c
void cgb_bg_colors_raw(u8 start_color_slot, const u16* colors, u8 color_count);

Paramètres

start_color_slot

Emplacement absolu de couleur, 0–31, normalisé par & 31 avant limitation de la longueur. Emplacement = palette × 4 + couleur ; ce n'est pas un décalage en octets.

colors

const u16* lisible contenant les mots de couleur nécessaires. Les données sont lues pendant l'appel, sans mise en file. Gardez la source et sa banque ROM accessibles ; aucun changement de banque n'est automatique. Un pointeur nul n'entraîne aucune écriture.

color_count

Nombre de mots de couleur, et non d'octets, en u8 (0–255). Zéro ne fait rien. La quantité est limitée à 32 - emplacement_initial_normalisé ; seuls ces mots source sont lus.

Valeur renvoyée

Aucune (void).

Conditions et limites

Les écritures de palette et de registres protégés n'écrivent rien en mode DMG. Safe désigne ici le contrôle du mode CGB, pas une attente d'accès PPU ni une section critique. Configurez avec le LCD éteint ou effectuez une mise à jour assez courte pendant une phase accessible. Aucune attente VBlank ni protection contre les interruptions n'est ajoutée.

Les palettes BG/fenêtre et OBJ sont stockées séparément. Les écritures de la bibliothèque activent l'incrément et laissent le registre d'indice modifié. La couleur OBJ zéro reste transparente au rendu des sprites, même si ses octets peuvent être écrits et lus.

Exemple d’utilisation

c
cgb_bg_colors_raw(23,blue_word,1); // Absolute slot 23 = palette 5, color 3.
expect_color(0,23,31744);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

cgb_bg_colors_raw: --cgb=cgb / DMG
--cgb=cgb / DMG
cgb_bg_colors_raw: --cgb=cgb / CGB
--cgb=cgb / CGB
cgb_bg_colors_raw: --cgb=dmg / DMG
--cgb=dmg / DMG
cgb_bg_colors_raw: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_palette.h:42

Notes de déclaration (texte source)
Expose sequential background writes using an absolute color-slot index.

kitaqgb/lib/cgb_palette.c:159

c
void cgb_bg_colors_raw(u8 start_color_slot, const u16* colors, u8 color_count)
{
    cgb__write_colors_bg_raw(start_color_slot, colors, color_count);
}
cgb_bg_palette

Remplace les quatre couleurs d'une palette de fond/fenêtre par quatre mots RGB15. Cela revient à écrire une plage débutant à la couleur zéro, de longueur quatre ; aucune tuile ni aucun sprite ne reçoit automatiquement cette palette.

Syntaxe

c
void cgb_bg_palette(u8 palette_index, const u16* colors);

Paramètres

palette_index

Numéro de palette, 0–7 ; seuls les trois bits faibles sont utilisés (& 7).

colors

const u16* lisible contenant les mots de couleur nécessaires. Les données sont lues pendant l'appel, sans mise en file. Gardez la source et sa banque ROM accessibles ; aucun changement de banque n'est automatique. Un pointeur nul n'entraîne aucune écriture.

Valeur renvoyée

Aucune (void).

Conditions et limites

Les écritures de palette et de registres protégés n'écrivent rien en mode DMG. Safe désigne ici le contrôle du mode CGB, pas une attente d'accès PPU ni une section critique. Configurez avec le LCD éteint ou effectuez une mise à jour assez courte pendant une phase accessible. Aucune attente VBlank ni protection contre les interruptions n'est ajoutée.

Les palettes BG/fenêtre et OBJ sont stockées séparément. Les écritures de la bibliothèque activent l'incrément et laissent le registre d'indice modifié. La couleur OBJ zéro reste transparente au rendu des sprites, même si ses octets peuvent être écrits et lus.

Exemple d’utilisation

c
cgb_bg_palette(4,red_palette); // Exactly four color words for BG palette 4.
expect_color(0,16,32767); expect_color(0,19,31);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

cgb_bg_palette: --cgb=cgb / DMG
--cgb=cgb / DMG
cgb_bg_palette: --cgb=cgb / CGB
--cgb=cgb / CGB
cgb_bg_palette: --cgb=dmg / DMG
--cgb=dmg / DMG
cgb_bg_palette: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_palette.h:37

Notes de déclaration (texte source)
Write four consecutive colors for one background palette.

kitaqgb/lib/cgb_palette.c:147

c
void cgb_bg_palette(u8 palette_index, const u16* colors)
{
    cgb_bg_colors(palette_index, 0, colors, 4);
}
cgb_bg_rgb

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Regroupe les composantes rouge, verte et bleue avec cgb_rgb15, puis écrit une couleur dans les palettes de fond/fenêtre. Convient aux composantes fournies séparément plutôt qu'à une valeur déjà compactée.

Syntaxe

c
void cgb_bg_rgb(u8 palette_index, u8 color_index, u8 r5, u8 g5, u8 b5);

Paramètres

palette_index

Numéro de palette, 0–7 ; seuls les trois bits faibles sont utilisés (& 7).

color_index

Indice de couleur dans la palette, 0–3 ; seuls les deux bits faibles sont utilisés (& 3).

r5, g5, b5

Composantes rouge, verte et bleue, normalement 0–31 chacune. Elles sont masquées, sans saturation ; chaque argument apparaît une seule fois dans le développement de la macro.

Valeur renvoyée

Aucune (void).

Conditions et limites

Les écritures de palette et de registres protégés n'écrivent rien en mode DMG. Safe désigne ici le contrôle du mode CGB, pas une attente d'accès PPU ni une section critique. Configurez avec le LCD éteint ou effectuez une mise à jour assez courte pendant une phase accessible. Aucune attente VBlank ni protection contre les interruptions n'est ajoutée.

Les palettes BG/fenêtre et OBJ sont stockées séparément. Les écritures de la bibliothèque activent l'incrément et laissent le registre d'indice modifié. La couleur OBJ zéro reste transparente au rendu des sprites, même si ses octets peuvent être écrits et lus.

Exemple d’utilisation

c
cgb_bg_rgb(2,3,0,0,31); // Blue, supplied as three five-bit components.
expect_color(0,11,31744);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

cgb_bg_rgb: --cgb=cgb / DMG
--cgb=cgb / DMG
cgb_bg_rgb: --cgb=cgb / CGB
--cgb=cgb / CGB
cgb_bg_rgb: --cgb=dmg / DMG
--cgb=dmg / DMG
cgb_bg_rgb: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_palette.h:26

Notes de déclaration (texte source)
Pack component values and write one background color.

kitaqgb/lib/cgb_palette.c:122

c
void cgb_bg_rgb(u8 palette_index, u8 color_index, u8 r5, u8 g5, u8 b5)
{
    cgb_bg_color(palette_index, color_index, cgb_rgb15(r5, g5, b5));
}
cgb_obj_color

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Écrit immédiatement une couleur RGB15 compactée dans les palettes de sprites (OBJ). Les indices de palette et de couleur désignent l'un des 32 emplacements ; ni les motifs ni la palette attribuée à une tuile ne changent.

Syntaxe

c
void cgb_obj_color(u8 palette_index, u8 color_index, u16 rgb15);

Paramètres

palette_index

Numéro de palette, 0–7 ; seuls les trois bits faibles sont utilisés (& 7).

color_index

Indice de couleur dans la palette, 0–3 ; seuls les deux bits faibles sont utilisés (& 3).

rgb15

Couleur RGB sur 15 bits compactée, normalement 0–32767. Les deux octets du u16 sont écrits, faible puis fort ; la bibliothèque n'efface pas explicitement le bit 15. Utilisez CGB_RGB15 ou cgb_rgb15 pour la construire.

Valeur renvoyée

Aucune (void).

Conditions et limites

Les écritures de palette et de registres protégés n'écrivent rien en mode DMG. Safe désigne ici le contrôle du mode CGB, pas une attente d'accès PPU ni une section critique. Configurez avec le LCD éteint ou effectuez une mise à jour assez courte pendant une phase accessible. Aucune attente VBlank ni protection contre les interruptions n'est ajoutée.

Les palettes BG/fenêtre et OBJ sont stockées séparément. Les écritures de la bibliothèque activent l'incrément et laissent le registre d'indice modifié. La couleur OBJ zéro reste transparente au rendu des sprites, même si ses octets peuvent être écrits et lus.

Exemple d’utilisation

c
cgb_obj_color(1,3,31744); // Blue sprite color at the same palette/color indices.
expect_color(1,7,31744);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

cgb_obj_color: --cgb=cgb / DMG
--cgb=cgb / DMG
cgb_obj_color: --cgb=cgb / CGB
--cgb=cgb / CGB
cgb_obj_color: --cgb=dmg / DMG
--cgb=dmg / DMG
cgb_obj_color: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_palette.h:24

Notes de déclaration (texte source)
Set one object color through the indexed palette wrapper.

kitaqgb/lib/cgb_palette.c:116

c
void cgb_obj_color(u8 palette_index, u8 color_index, u16 rgb15)
{
    cgb__write_color_obj_raw(cgb__palette_color_slot(palette_index, color_index), rgb15);
}
cgb_obj_colors

Écrit des mots RGB15 consécutifs dans les palettes de sprites (OBJ), à partir des indices indiqués. La plage peut franchir une limite de palette de quatre couleurs, mais s'arrête à la fin des 32 emplacements.

Syntaxe

c
void cgb_obj_colors(u8 palette_index, u8 start_color_index, const u16* colors, u8 color_count);

Paramètres

palette_index

Numéro de palette, 0–7 ; seuls les trois bits faibles sont utilisés (& 7).

start_color_index

Indice de couleur dans la palette, 0–3 ; seuls les deux bits faibles sont utilisés (& 3).

colors

const u16* lisible contenant les mots de couleur nécessaires. Les données sont lues pendant l'appel, sans mise en file. Gardez la source et sa banque ROM accessibles ; aucun changement de banque n'est automatique. Un pointeur nul n'entraîne aucune écriture.

color_count

Nombre de mots de couleur, et non d'octets, en u8 (0–255). Zéro ne fait rien. La quantité est limitée à 32 - emplacement_initial_normalisé ; seuls ces mots source sont lus.

Valeur renvoyée

Aucune (void).

Conditions et limites

Les écritures de palette et de registres protégés n'écrivent rien en mode DMG. Safe désigne ici le contrôle du mode CGB, pas une attente d'accès PPU ni une section critique. Configurez avec le LCD éteint ou effectuez une mise à jour assez courte pendant une phase accessible. Aucune attente VBlank ni protection contre les interruptions n'est ajoutée.

Les palettes BG/fenêtre et OBJ sont stockées séparément. Les écritures de la bibliothèque activent l'incrément et laissent le registre d'indice modifié. La couleur OBJ zéro reste transparente au rendu des sprites, même si ses octets peuvent être écrits et lus.

Exemple d’utilisation

c
cgb_obj_colors(3,2,tail_red,2); // Sprite color 3 becomes red.
expect_color(1,14,0); expect_color(1,15,31);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

cgb_obj_colors: --cgb=cgb / DMG
--cgb=cgb / DMG
cgb_obj_colors: --cgb=cgb / CGB
--cgb=cgb / CGB
cgb_obj_colors: --cgb=dmg / DMG
--cgb=dmg / DMG
cgb_obj_colors: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_palette.h:34

Notes de déclaration (texte source)
Write object colors from the indexed slot, potentially crossing into later palettes.

kitaqgb/lib/cgb_palette.c:141

c
void cgb_obj_colors(u8 palette_index, u8 start_color_index, const u16* colors, u8 color_count)
{
    cgb__write_colors_obj_raw(cgb__palette_color_slot(palette_index, start_color_index), colors, color_count);
}
cgb_obj_colors_raw

Écrit des mots RGB15 consécutifs dans les palettes de sprites (OBJ) à partir d'un emplacement absolu. Le départ est un seul indice de 0 à 31, et non une paire palette/couleur. Les données sont des mots de couleur, pas des octets de motifs.

Syntaxe

c
void cgb_obj_colors_raw(u8 start_color_slot, const u16* colors, u8 color_count);

Paramètres

start_color_slot

Emplacement absolu de couleur, 0–31, normalisé par & 31 avant limitation de la longueur. Emplacement = palette × 4 + couleur ; ce n'est pas un décalage en octets.

colors

const u16* lisible contenant les mots de couleur nécessaires. Les données sont lues pendant l'appel, sans mise en file. Gardez la source et sa banque ROM accessibles ; aucun changement de banque n'est automatique. Un pointeur nul n'entraîne aucune écriture.

color_count

Nombre de mots de couleur, et non d'octets, en u8 (0–255). Zéro ne fait rien. La quantité est limitée à 32 - emplacement_initial_normalisé ; seuls ces mots source sont lus.

Valeur renvoyée

Aucune (void).

Conditions et limites

Les écritures de palette et de registres protégés n'écrivent rien en mode DMG. Safe désigne ici le contrôle du mode CGB, pas une attente d'accès PPU ni une section critique. Configurez avec le LCD éteint ou effectuez une mise à jour assez courte pendant une phase accessible. Aucune attente VBlank ni protection contre les interruptions n'est ajoutée.

Les palettes BG/fenêtre et OBJ sont stockées séparément. Les écritures de la bibliothèque activent l'incrément et laissent le registre d'indice modifié. La couleur OBJ zéro reste transparente au rendu des sprites, même si ses octets peuvent être écrits et lus.

Exemple d’utilisation

c
cgb_obj_colors_raw(23,green_word,1); // Same absolute slot in the separate OBJ store.
expect_color(1,23,992);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

cgb_obj_colors_raw: --cgb=cgb / DMG
--cgb=cgb / DMG
cgb_obj_colors_raw: --cgb=cgb / CGB
--cgb=cgb / CGB
cgb_obj_colors_raw: --cgb=dmg / DMG
--cgb=dmg / DMG
cgb_obj_colors_raw: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_palette.h:44

Notes de déclaration (texte source)
Expose sequential object writes using an absolute color-slot index.

kitaqgb/lib/cgb_palette.c:165

c
void cgb_obj_colors_raw(u8 start_color_slot, const u16* colors, u8 color_count)
{
    cgb__write_colors_obj_raw(start_color_slot, colors, color_count);
}
cgb_obj_palette

Remplace les quatre couleurs d'une palette de sprites (OBJ) par quatre mots RGB15. Cela revient à écrire une plage débutant à la couleur zéro, de longueur quatre ; aucune tuile ni aucun sprite ne reçoit automatiquement cette palette.

Syntaxe

c
void cgb_obj_palette(u8 palette_index, const u16* colors);

Paramètres

palette_index

Numéro de palette, 0–7 ; seuls les trois bits faibles sont utilisés (& 7).

colors

const u16* lisible contenant les mots de couleur nécessaires. Les données sont lues pendant l'appel, sans mise en file. Gardez la source et sa banque ROM accessibles ; aucun changement de banque n'est automatique. Un pointeur nul n'entraîne aucune écriture.

Valeur renvoyée

Aucune (void).

Conditions et limites

Les écritures de palette et de registres protégés n'écrivent rien en mode DMG. Safe désigne ici le contrôle du mode CGB, pas une attente d'accès PPU ni une section critique. Configurez avec le LCD éteint ou effectuez une mise à jour assez courte pendant une phase accessible. Aucune attente VBlank ni protection contre les interruptions n'est ajoutée.

Les palettes BG/fenêtre et OBJ sont stockées séparément. Les écritures de la bibliothèque activent l'incrément et laissent le registre d'indice modifié. La couleur OBJ zéro reste transparente au rendu des sprites, même si ses octets peuvent être écrits et lus.

Exemple d’utilisation

c
cgb_obj_palette(4,blue_palette); // Exactly four words; OBJ color zero is transparent on screen.
expect_color(1,16,32767); expect_color(1,19,31744);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

cgb_obj_palette: --cgb=cgb / DMG
--cgb=cgb / DMG
cgb_obj_palette: --cgb=cgb / CGB
--cgb=cgb / CGB
cgb_obj_palette: --cgb=dmg / DMG
--cgb=dmg / DMG
cgb_obj_palette: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_palette.h:39

Notes de déclaration (texte source)
Write four consecutive colors for one object palette.

kitaqgb/lib/cgb_palette.c:153

c
void cgb_obj_palette(u8 palette_index, const u16* colors)
{
    cgb_obj_colors(palette_index, 0, colors, 4);
}
cgb_obj_rgb

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Regroupe les composantes rouge, verte et bleue avec cgb_rgb15, puis écrit une couleur dans les palettes de sprites (OBJ). Convient aux composantes fournies séparément plutôt qu'à une valeur déjà compactée.

Syntaxe

c
void cgb_obj_rgb(u8 palette_index, u8 color_index, u8 r5, u8 g5, u8 b5);

Paramètres

palette_index

Numéro de palette, 0–7 ; seuls les trois bits faibles sont utilisés (& 7).

color_index

Indice de couleur dans la palette, 0–3 ; seuls les deux bits faibles sont utilisés (& 3).

r5, g5, b5

Composantes rouge, verte et bleue, normalement 0–31 chacune. Elles sont masquées, sans saturation ; chaque argument apparaît une seule fois dans le développement de la macro.

Valeur renvoyée

Aucune (void).

Conditions et limites

Les écritures de palette et de registres protégés n'écrivent rien en mode DMG. Safe désigne ici le contrôle du mode CGB, pas une attente d'accès PPU ni une section critique. Configurez avec le LCD éteint ou effectuez une mise à jour assez courte pendant une phase accessible. Aucune attente VBlank ni protection contre les interruptions n'est ajoutée.

Les palettes BG/fenêtre et OBJ sont stockées séparément. Les écritures de la bibliothèque activent l'incrément et laissent le registre d'indice modifié. La couleur OBJ zéro reste transparente au rendu des sprites, même si ses octets peuvent être écrits et lus.

Exemple d’utilisation

c
cgb_obj_rgb(2,3,0,31,0); // Green sprite color.
expect_color(1,11,992);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

cgb_obj_rgb: --cgb=cgb / DMG
--cgb=cgb / DMG
cgb_obj_rgb: --cgb=cgb / CGB
--cgb=cgb / CGB
cgb_obj_rgb: --cgb=dmg / DMG
--cgb=dmg / DMG
cgb_obj_rgb: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_palette.h:28

Notes de déclaration (texte source)
Pack component values and write one object color.

kitaqgb/lib/cgb_palette.c:128

c
void cgb_obj_rgb(u8 palette_index, u8 color_index, u8 r5, u8 g5, u8 b5)
{
    cgb_obj_color(palette_index, color_index, cgb_rgb15(r5, g5, b5));
}
CGB_RGB15

Regroupe RGB dans un u16 : rouge aux bits 0–4, vert aux bits 5–9, bleu aux bits 10–14 ; le bit 15 vaut zéro. Le masque 31 conserve les cinq bits faibles de chaque composante, sans saturation. Calcule uniquement une valeur, sur DMG comme sur CGB, sans écriture matérielle.

Syntaxe

c
#define CGB_RGB15(r5, g5, b5) ((u16)((u16)((r5) & 31) | ((u16)((g5) & 31) << 5) | ((u16)((b5) & 31) << 10)))

Paramètres

r5, g5, b5

Composantes rouge, verte et bleue, normalement 0–31 chacune. Elles sont masquées, sans saturation ; chaque argument apparaît une seule fois dans le développement de la macro.

Valeur renvoyée

Valeur RGB15 compactée en u16, de 0 à 32767.

Exemple d’utilisation

c
if (CGB_RGB15(component,64,95)!=31775) failures++; // (31,0,31), not saturation.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

CGB_RGB15: --cgb=cgb / DMG
--cgb=cgb / DMG
CGB_RGB15: --cgb=cgb / CGB
--cgb=cgb / CGB
CGB_RGB15: --cgb=dmg / DMG
--cgb=dmg / DMG
CGB_RGB15: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_palette.h:16

cgb_rgb15

Regroupe RGB dans un u16 : rouge aux bits 0–4, vert aux bits 5–9, bleu aux bits 10–14 ; le bit 15 vaut zéro. Le masque 31 conserve les cinq bits faibles de chaque composante, sans saturation. Calcule uniquement une valeur, sur DMG comme sur CGB, sans écriture matérielle.

Syntaxe

c
u16 cgb_rgb15(u8 r5, u8 g5, u8 b5);

Paramètres

r5, g5, b5

Composantes rouge, verte et bleue, normalement 0–31 chacune. Elles sont masquées, sans saturation ; chaque argument apparaît une seule fois dans le développement de la macro.

Valeur renvoyée

Valeur RGB15 compactée en u16, de 0 à 32767.

Exemple d’utilisation

c
if (cgb_rgb15(component,64,95)!=31775) failures++; // Same packed value through a function.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

cgb_rgb15: --cgb=cgb / DMG
--cgb=cgb / DMG
cgb_rgb15: --cgb=cgb / CGB
--cgb=cgb / CGB
cgb_rgb15: --cgb=dmg / DMG
--cgb=dmg / DMG
cgb_rgb15: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_palette.h:19

Notes de déclaration (texte source)
Pack the red, green and blue components using the public RGB15 macro.

kitaqgb/lib/cgb_palette.c:104

c
u16 cgb_rgb15(u8 r5, u8 g5, u8 b5)
{
    return CGB_RGB15(r5, g5, b5);
}

cgb_tile.h — Numéros et attributs de tuiles CGB

cgb_tile.h regroupe les déclarations des fonctions intrinsèques de carte de tuiles et les macros de construction des attributs CGB. Le numéro de tuile choisit un motif ; son attribut choisit palette, banque VRAM du motif, retournements et priorité du fond. Modifier les attributs ne change pas les pixels du motif.

La famille __settile vise la carte 0x9800 ; __settileat utilise une base explicite ; __settilebg, la carte de fond choisie par LCDC ; __settilewin, sa carte de fenêtre. Les formes attr n’écrivent que les attributs, les formes cgb écrivent numéros et attributs. Les formes bulk transfèrent des octets consécutifs à l’adresse fournie. Choisissez selon la destination et les données à écrire.

Utilisez des macros comme KQ_CGB_ATTR_PAL pour les bits individuels, ou KQ_CGB_ATTR pour combiner les champs. Le champ bank choisit la banque VRAM du motif, pas une banque ROM. Les écritures ordinaires de numéros utilisent la banque VRAM courante : sélectionnez la banque zéro avant les opérations combinées tuile/attribut. Sur DMG, les opérations d’attribut seul sont sans effet ; les opérations combinées écrivent toujours les numéros.

Le compilateur génère l’implémentation des fonctions intrinsèques __ ; il n’est pas nécessaire de lier cgb_tile.c. Les chemins d’écriture ordinaires attendent l’accès VRAM, mais certains changent aussi l’activation des interruptions. Les formes _unsafe et _fast omettent ces attentes : utilisez-les seulement si l’appelant garantit une VRAM accessible en écriture, par exemple LCD éteint. Vérifiez les conditions d’interruption, de banque et de longueur de chaque entrée.

KQ_CGB_ATTR

Construit l'octet complet d'attribut de carte CGB : palette, banque de motifs, réflexion horizontale, réflexion verticale et priorité BG. La palette occupe les bits 0–2 ; les quatre booléens règlent les bits 3, 5, 6 et 7. Le bit 4 reste nul.

Syntaxe

c
#define KQ_CGB_ATTR(palette, bank, xflip, yflip, priority) ((u8)(((palette) & KQ_CGB_ATTR_PAL_MASK) | ((bank) ? KQ_CGB_ATTR_BANK1 : 0) | ((xflip) ? KQ_CGB_ATTR_XFLIP : 0) | ((yflip) ? KQ_CGB_ATTR_YFLIP : 0) | ((priority) ? KQ_CGB_ATTR_PRIORITY : 0)))

Paramètres

palette

Numéro de palette, 0–7 ; seuls les trois bits faibles sont utilisés (& 7).

bank, xflip, yflip, priority

Zéro désactive le champ ; toute valeur non nulle l'active. Le 2 l'active aussi : le test porte sur la non-nullité, pas sur le bit faible.

Valeur renvoyée

Champ d'attribut ou octet combiné en u8, selon la disposition de bits décrite.

Conditions et limites

Ces macros calculent uniquement des valeurs u8, sans écrire en VRAM ni dans les registres. Chaque argument apparaît une fois. Appliquez le résultat par une API d'attributs CGB ou une écriture explicite dans la carte de banque 1. DMG n'affiche pas les attributs CGB.

Construit le bit 3 d'un attribut de carte CGB : 0x08 si bank est non nul, sinon 0. Choisit la banque VRAM du motif affiché, sans écrire VBK ni changer la banque de la CPU.

Construit le drapeau de réflexion horizontale : 0x20 si enabled est non nul, sinon 0. Dans un attribut de carte CGB, inverse l'affichage des huit pixels de chaque ligne sans modifier le motif stocké.

Construit le drapeau de réflexion verticale : 0x40 si enabled est non nul, sinon 0. Dans la carte CGB, affiche les huit lignes dans l'ordre inverse sans modifier le motif stocké.

Construit la priorité BG sur OBJ : 0x80 si enabled est non nul, sinon 0. Quand la priorité générale CGB est active (bit 0 de LCDC), les indices de couleur BG non nuls masquent les sprites. L'indice zéro les laisse passer ; le drapeau ne rend pas toute la tuile opaque.

Exemple d’utilisation

c
attr=KQ_CGB_ATTR(10,0,2,2,0); // Palette 2, bank 0, both reflections: 0x62.
if (attr!=98 || KQ_CGB_ATTR(10,2,3,4,5)!=234) failures++;
cell(10,11,1,attr);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

KQ_CGB_ATTR: --cgb=cgb / DMG
--cgb=cgb / DMG
KQ_CGB_ATTR: --cgb=cgb / CGB
--cgb=cgb / CGB
KQ_CGB_ATTR: --cgb=dmg / DMG
--cgb=dmg / DMG
KQ_CGB_ATTR: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_tile.h:23

KQ_CGB_ATTR_BANK

Construit le bit 3 d'un attribut de carte CGB : 0x08 si bank est non nul, sinon 0. Choisit la banque VRAM du motif affiché, sans écrire VBK ni changer la banque de la CPU.

Syntaxe

c
#define KQ_CGB_ATTR_BANK(bank) ((u8)((bank) ? KQ_CGB_ATTR_BANK1 : 0))

Paramètres

bank

Zéro désactive le champ ; toute valeur non nulle l'active. Le 2 l'active aussi : le test porte sur la non-nullité, pas sur le bit faible.

Valeur renvoyée

Champ d'attribut ou octet combiné en u8, selon la disposition de bits décrite.

Conditions et limites

Ces macros calculent uniquement des valeurs u8, sans écrire en VRAM ni dans les registres. Chaque argument apparaît une fois. Appliquez le résultat par une API d'attributs CGB ou une écriture explicite dans la carte de banque 1. DMG n'affiche pas les attributs CGB.

Exemple d’utilisation

c
attr=(u8)(2|KQ_CGB_ATTR_BANK(enabled)); // Any nonzero value selects tile-data bank 1.
if (attr!=10) failures++;
cell(4,11,1,attr); // Blue hollow square, unlike the bank-0 triangle.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

KQ_CGB_ATTR_BANK: --cgb=cgb / DMG
--cgb=cgb / DMG
KQ_CGB_ATTR_BANK: --cgb=cgb / CGB
--cgb=cgb / CGB
KQ_CGB_ATTR_BANK: --cgb=dmg / DMG
--cgb=dmg / DMG
KQ_CGB_ATTR_BANK: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_tile.h:19

KQ_CGB_ATTR_PAL

Construit le champ de palette d'un attribut de carte CGB : n & 7, en u8. Combinez-le avec les autres drapeaux par OU binaire.

Syntaxe

c
#define KQ_CGB_ATTR_PAL(n) ((u8)((n) & KQ_CGB_ATTR_PAL_MASK))

Paramètres

n

Numéro de palette, 0–7 ; seuls les trois bits faibles sont utilisés (& 7).

Valeur renvoyée

Champ d'attribut ou octet combiné en u8, selon la disposition de bits décrite.

Conditions et limites

Ces macros calculent uniquement des valeurs u8, sans écrire en VRAM ni dans les registres. Chaque argument apparaît une fois. Appliquez le résultat par une API d'attributs CGB ou une écriture explicite dans la carte de banque 1. DMG n'affiche pas les attributs CGB.

Exemple d’utilisation

c
attr=KQ_CGB_ATTR_PAL(9); // 9 & 7 = palette 1, red in this BG example.
if (attr!=1) failures++;
cell(2,11,1,attr);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

KQ_CGB_ATTR_PAL: --cgb=cgb / DMG
--cgb=cgb / DMG
KQ_CGB_ATTR_PAL: --cgb=cgb / CGB
--cgb=cgb / CGB
KQ_CGB_ATTR_PAL: --cgb=dmg / DMG
--cgb=dmg / DMG
KQ_CGB_ATTR_PAL: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_tile.h:18

KQ_CGB_ATTR_PRIORITY_IF

Construit la priorité BG sur OBJ : 0x80 si enabled est non nul, sinon 0. Quand la priorité générale CGB est active (bit 0 de LCDC), les indices de couleur BG non nuls masquent les sprites. L'indice zéro les laisse passer ; le drapeau ne rend pas toute la tuile opaque.

Syntaxe

c
#define KQ_CGB_ATTR_PRIORITY_IF(enabled) ((u8)((enabled) ? KQ_CGB_ATTR_PRIORITY : 0))

Paramètres

enabled

Zéro désactive le champ ; toute valeur non nulle l'active. Le 2 l'active aussi : le test porte sur la non-nullité, pas sur le bit faible.

Valeur renvoyée

Champ d'attribut ou octet combiné en u8, selon la disposition de bits décrite.

Conditions et limites

Ces macros calculent uniquement des valeurs u8, sans écrire en VRAM ni dans les registres. Chaque argument apparaît une fois. Appliquez le résultat par une API d'attributs CGB ou une écriture explicite dans la carte de banque 1. DMG n'affiche pas les attributs CGB.

Exemple d’utilisation

c
attr=(u8)(3|KQ_CGB_ATTR_PRIORITY_IF(enabled)); // Keep nonzero BG pixels in front of sprites.
if (attr!=131) failures++;
cell(12,11,1,attr);
sprite(7,96,88,2,3); // Red full tile behind the green priority triangle.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

KQ_CGB_ATTR_PRIORITY_IF: --cgb=cgb / DMG
--cgb=cgb / DMG
KQ_CGB_ATTR_PRIORITY_IF: --cgb=cgb / CGB
--cgb=cgb / CGB
KQ_CGB_ATTR_PRIORITY_IF: --cgb=dmg / DMG
--cgb=dmg / DMG
KQ_CGB_ATTR_PRIORITY_IF: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_tile.h:22

KQ_CGB_ATTR_XFLIP_IF

Construit le drapeau de réflexion horizontale : 0x20 si enabled est non nul, sinon 0. Dans un attribut de carte CGB, inverse l'affichage des huit pixels de chaque ligne sans modifier le motif stocké.

Syntaxe

c
#define KQ_CGB_ATTR_XFLIP_IF(enabled) ((u8)((enabled) ? KQ_CGB_ATTR_XFLIP : 0))

Paramètres

enabled

Zéro désactive le champ ; toute valeur non nulle l'active. Le 2 l'active aussi : le test porte sur la non-nullité, pas sur le bit faible.

Valeur renvoyée

Champ d'attribut ou octet combiné en u8, selon la disposition de bits décrite.

Conditions et limites

Ces macros calculent uniquement des valeurs u8, sans écrire en VRAM ni dans les registres. Chaque argument apparaît une fois. Appliquez le résultat par une API d'attributs CGB ou une écriture explicite dans la carte de banque 1. DMG n'affiche pas les attributs CGB.

Exemple d’utilisation

c
attr=(u8)(3|KQ_CGB_ATTR_XFLIP_IF(enabled));
if (attr!=35) failures++;
cell(6,11,1,attr); // Green triangle reflected horizontally.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

KQ_CGB_ATTR_XFLIP_IF: --cgb=cgb / DMG
--cgb=cgb / DMG
KQ_CGB_ATTR_XFLIP_IF: --cgb=cgb / CGB
--cgb=cgb / CGB
KQ_CGB_ATTR_XFLIP_IF: --cgb=dmg / DMG
--cgb=dmg / DMG
KQ_CGB_ATTR_XFLIP_IF: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_tile.h:20

KQ_CGB_ATTR_YFLIP_IF

Construit le drapeau de réflexion verticale : 0x40 si enabled est non nul, sinon 0. Dans la carte CGB, affiche les huit lignes dans l'ordre inverse sans modifier le motif stocké.

Syntaxe

c
#define KQ_CGB_ATTR_YFLIP_IF(enabled) ((u8)((enabled) ? KQ_CGB_ATTR_YFLIP : 0))

Paramètres

enabled

Zéro désactive le champ ; toute valeur non nulle l'active. Le 2 l'active aussi : le test porte sur la non-nullité, pas sur le bit faible.

Valeur renvoyée

Champ d'attribut ou octet combiné en u8, selon la disposition de bits décrite.

Conditions et limites

Ces macros calculent uniquement des valeurs u8, sans écrire en VRAM ni dans les registres. Chaque argument apparaît une fois. Appliquez le résultat par une API d'attributs CGB ou une écriture explicite dans la carte de banque 1. DMG n'affiche pas les attributs CGB.

Exemple d’utilisation

c
attr=(u8)(1|KQ_CGB_ATTR_YFLIP_IF(enabled));
if (attr!=65) failures++;
cell(8,11,1,attr); // Red triangle reflected vertically.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme montre comment les palettes BG et OBJ colorent indépendamment un même motif. Chaque triangle occupe 8 × 8 pixels, d'un seul pixel à gauche en haut jusqu'à une ligne complète en bas. Aux abscisses 16, 32, 48, 64, 80, 96, 112, la ligne BG à y = 24 est rouge, bleue, verte, rouge, bleue, verte, rouge ; la ligne OBJ à y = 64 est bleue, verte, rouge, bleue, verte, rouge, bleue. Les colonnes utilisent respectivement une couleur, les composantes, une plage indexée, une palette entière, une plage absolue, un registre canonique et son alias.

À y = 88, sept cases de 8 × 8 montrent : triangle rouge (x = 16), contour carré bleu d'un pixel provenant de la banque 1 (32), triangle vert réfléchi horizontalement (48), rouge réfléchi verticalement (64), bleu réfléchi sur les deux axes (80), triangle vert devant un sprite rouge visible dans les pixels de couleur zéro (96), puis sprite rouge plein devant le triangle BG, témoin sans priorité (112). Les coordonnées sont en pixels depuis le coin supérieur gauche. Le fond reste blanc et le texte noir.

FAILED CHECKS 000 confirme les masques RGB, les booléens (dont 2), la normalisation des indices, le franchissement de palettes, l'arrêt à l'emplacement 31, l'absence d'écriture pour pointeur nul ou longueur nulle et la relecture des couleurs LCD éteint. Quatre combinaisons sont testées : ROM mixte sur DMG/CGB, ROM DMG seule sur DMG, ROM CGB seule sur CGB. Sur DMG, CGB MODE vaut 0, les triangles sont noirs, banque et réflexions n'affectent pas l'image et les deux dernières cases du bas sont des carrés noirs. Sur CGB, CGB MODE vaut 1. Le matériel réel et les conflits d'accès LCD allumé ne sont pas testés.

KQ_CGB_ATTR_YFLIP_IF: --cgb=cgb / DMG
--cgb=cgb / DMG
KQ_CGB_ATTR_YFLIP_IF: --cgb=cgb / CGB
--cgb=cgb / CGB
KQ_CGB_ATTR_YFLIP_IF: --cgb=dmg / DMG
--cgb=dmg / DMG
KQ_CGB_ATTR_YFLIP_IF: --cgb=cgb_only / CGB
--cgb=cgb_only / CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\cgb_palette_attributes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\cgb_palette_attributes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/cgb_tile.h:21

chain.h — Tampons circulaires pour l'historique des positions

Utilisez ChainBody pour les serpents ou cordes articulés, et Chain pour conserver un historique de positions. Chaque articulation stocke sa position courante et l’une des 16 orientations ; les courbures se propagent vers l’arrière d’une articulation par mise à jour. Les opérations sur le corps gèrent les terrains à rebouclage, l’allongement par duplication de la queue et les corrections de deux pixels au plus par axe.

chain_wrap_delta

Calcule le plus court déplacement signé de la position courante vers une cible sur un axe dont les extrémités se rejoignent. Utilisez-le pour le suivi ou la comparaison de distances à travers un bord du terrain.

Syntaxe

c
s16 chain_wrap_delta(u8 target, u8 current, u16 size);

Paramètres

target

Coordonnée cible, de 0 à size−1.

current

Coordonnée courante, de 0 à size−1.

size

Longueur de l’axe à rebouclage, de 1 à 256 : largeur pour X, hauteur pour Y. L’argument est sur 16 bits pour représenter 256.

Valeur renvoyée

Renvoie le plus court déplacement en s16 : positif vers les coordonnées croissantes, négatif vers les décroissantes, zéro à la même position. Les entrées valides donnent −128..+128. À l’écran, droite et bas sont positifs.

Conditions et limites

Incluez chain.h et compilez chain.c exactement une fois. Aucune initialisation de Chain ou ChainBody n’est nécessaire. La fonction calcule seulement un déplacement, sans modifier tableaux de coordonnées, nombre d’articulations ni écran.

La fonction ne valide ni ne normalise les entrées. Ne passez pas size=0, size>256 ou des coordonnées supérieures ou égales à size. Ramenez les coordonnées d’un système plus grand dans 0..size−1 par rebouclage avant l’appel.

Si les deux chemins ont la même longueur, conserve le signe du déplacement direct target−current. Avec size=160, 0→80 renvoie +80 et 80→0 renvoie −80. Avec size=1, zéro est la seule coordonnée valide et le résultat vaut zéro.

Exemple d’utilisation

c
distances[0]=chain_wrap_delta(1,159,160);   // +2: cross the right edge.
    distances[1]=chain_wrap_delta(159,1,160);   // -2: cross the left edge.
    distances[2]=chain_wrap_delta(80,0,160);    // +80: keep the direct sign.
    distances[3]=chain_wrap_delta(0,80,160);    // -80: same-length routes.
    distances[4]=chain_wrap_delta(0,0,1);       // 0: the only valid position.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple présente les coordonnées à rebouclage. Chaque flèche va de la position courante à la cible. Il affiche +02/−02 pour traverser un bord de largeur 160, +80/−80 pour un demi-terrain et +00 pour la largeur 1. Le zéro initial est un remplissage décimal. L’exemple ne dessine ni ne déplace d’objet.

chain_wrap_delta: DMG
DMG
chain_wrap_delta: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\chain_wrap.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\chain_wrap.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/chain.h:35

Notes de déclaration (texte source)
Return target minus current along the shortest wrapped route.
Supply size 1..256 and coordinates in 0..size-1; inputs are not normalized.
Exactly half a field retains the direct displacement sign.

kitaqgb/lib/chain.c:98

c
s16 chain_wrap_delta(u8 target, u8 current, u16 size)
{
    s16 delta;
    s16 half;
    delta = (s16)((s16)target - (s16)current);
    half = (s16)(size >> 1);
    // At exactly half a field, retain the sign of the direct displacement.
    if (delta > half) delta = (s16)(delta - (s16)size);
    else if (delta < (s16)(0 - half)) delta = (s16)(delta + (s16)size);
    return delta;
}
chain_body_init

Associe trois tableaux d’articulations fournis par l’appelant et met leur nombre à zéro, sans allouer de mémoire.

Syntaxe

c
u8 chain_body_init(ChainBody* body, u8* x, u8* y, u8* heading, u8 capacity, u16 width, u16 height);

Paramètres

body

ChainBody cible ; null est ignoré. Sauf pour l’initialisation, passez un état déjà initialisé.

x

Tableau des coordonnées X des articulations.

y

Tableau des coordonnées Y des articulations.

heading

Tableau des orientations des articulations.

capacity

Longueur allouée du tableau, de 1 à 255.

width

Largeur du terrain à rebouclage, de 1 à 256.

height

Hauteur du terrain à rebouclage, de 1 à 256.

Valeur renvoyée

Renvoie 1 en cas de succès, 0 pour des arguments invalides. Un échec avec un corps non nul met capacity et count à zéro, désactivant les mises à jour.

Conditions et limites

Incluez chain.h et compilez chain.c exactement une fois. ChainBody contient la position et l’orientation courantes de chaque articulation. Ce type d’état est distinct de l’historique circulaire de positions Chain.

Fournissez trois tableaux distincts accessibles en écriture, x, y et heading, de capacity octets chacun. Conservez-les pendant l’utilisation du corps. L’indice zéro est la tête, comprise dans count. Ne modifiez pas les pointeurs, la capacité ou les dimensions du terrain après l’initialisation.

Les orientations suivent 16 secteurs horaires : 0=droite, 4=bas, 8=gauche, 12=haut. Seuls les quatre bits de poids faible sont utilisés. Les coordonnées d’écran augmentent vers la droite et le bas ; chaque dimension va de 1 à 256 pixels.

Exemple d’utilisation

c
chain_body_init(&body,joint_x,joint_y,joint_heading,8,160,144);
    // Eight caller-owned slots, including the head, on a wrapped 160x144 field.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.

chain_body_init: DMG — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
DMG — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
chain_body_init: CGB — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
CGB — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\chain_body.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\chain_body.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/chain.h:53

Notes de déclaration (texte source)
Attach three non-overlapping capacity-byte arrays. Return 1 on success.
Invalid storage, zero capacity or dimensions outside 1..256 disable the body.

kitaqgb/lib/chain.c:119

c
u8 chain_body_init(ChainBody* body, u8* x, u8* y, u8* heading, u8 capacity, u16 width, u16 height)
{
    if (body == 0) return 0;
    body->x = x;
    body->y = y;
    body->heading = heading;
    body->count = 0;
    body->capacity = 0;
    body->width = width;
    body->height = height;
    if (x == 0 || y == 0 || heading == 0 || capacity == 0) return 0;
    if (width == 0 || width > 256 || height == 0 || height > 256) return 0;
    body->capacity = capacity;
    return 1;
}
chain_body_reset

Construit une pose initiale droite en plaçant les articulations derrière la tête indiquée.

Syntaxe

c
u8 chain_body_reset(ChainBody* body, u8 count, u8 head_x, u8 head_y, u8 heading);

Paramètres

body

ChainBody cible ; null est ignoré. Sauf pour l’initialisation, passez un état déjà initialisé.

count

Nombre d’articulations, tête comprise, de 1 à capacity.

head_x

Coordonnée X de la tête, ramenée par rebouclage à la largeur du terrain.

head_y

Coordonnée Y de la tête, ramenée par rebouclage à la hauteur du terrain.

heading

Orientation de la tête dans le système à 16 secteurs.

Valeur renvoyée

Renvoie 1 en cas de succès. Un nombre nul ou excessif, ou un corps nul, renvoie 0 sans modifier la pose.

Conditions et limites

Incluez chain.h et compilez chain.c exactement une fois. ChainBody contient la position et l’orientation courantes de chaque articulation. Ce type d’état est distinct de l’historique circulaire de positions Chain.

Fournissez trois tableaux distincts accessibles en écriture, x, y et heading, de capacity octets chacun. Conservez-les pendant l’utilisation du corps. L’indice zéro est la tête, comprise dans count. Ne modifiez pas les pointeurs, la capacité ou les dimensions du terrain après l’initialisation.

Les orientations suivent 16 secteurs horaires : 0=droite, 4=bas, 8=gauche, 12=haut. Seuls les quatre bits de poids faible sont utilisés. Les coordonnées d’écran augmentent vers la droite et le bas ; chaque dimension va de 1 à 256 pixels.

L’espacement cardinal est de quatre pixels. Les orientations intermédiaires utilisent des vecteurs entiers comme (4,1), (3,3) et (1,4) ; la distance euclidienne n’est donc pas exactement quatre pixels. La pose initiale peut franchir un bord du terrain.

Exemple d’utilisation

c
chain_body_reset(&body,7,48,16,0); // Seven joints, facing right.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.

chain_body_reset: DMG — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
DMG — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
chain_body_reset: CGB — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
CGB — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\chain_body.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\chain_body.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/chain.h:57

Notes de déclaration (texte source)
Seed count joints in a straight pose behind the head; count includes the head.
Return 0 without changing the pose if count is zero or exceeds capacity.
Coordinates wrap to the playfield and headings are masked to 0..15.

kitaqgb/lib/chain.c:135

c
u8 chain_body_reset(ChainBody* body, u8 count, u8 head_x, u8 head_y, u8 heading)
{
    u8 i;
    u8 x;
    u8 y;
    s16 ox;
    s16 oy;
    if (body == 0) return 0;
    if (count == 0 || count > body->capacity) return 0;
    heading = (u8)(heading & 15);
    x = chain_body_wrap((s16)head_x, body->width);
    y = chain_body_wrap((s16)head_y, body->height);
    ox = chain_body_offset_x(heading);
    oy = chain_body_offset_y(heading);
    i = 0;
    while (i < count) {
        body->x[(__safe_index u8)i] = x;
        body->y[(__safe_index u8)i] = y;
        body->heading[(__safe_index u8)i] = heading;
        x = chain_body_wrap((s16)((s16)x - ox), body->width);
        y = chain_body_wrap((s16)((s16)y - oy), body->height);
        i = (u8)(i + 1);
    }
    body->count = count;
    return 1;
}
chain_body_step

Définit la pose de la tête et attire progressivement chaque articulation vers un point d’attache derrière la précédente. Les changements d’orientation se propagent d’une articulation par mise à jour.

Syntaxe

c
void chain_body_step(ChainBody* body, u8 head_x, u8 head_y, u8 heading);

Paramètres

body

ChainBody cible ; null est ignoré. Sauf pour l’initialisation, passez un état déjà initialisé.

head_x

Coordonnée X de la tête, ramenée par rebouclage à la largeur du terrain.

head_y

Coordonnée Y de la tête, ramenée par rebouclage à la hauteur du terrain.

heading

Orientation de la tête dans le système à 16 secteurs.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Incluez chain.h et compilez chain.c exactement une fois. ChainBody contient la position et l’orientation courantes de chaque articulation. Ce type d’état est distinct de l’historique circulaire de positions Chain.

Fournissez trois tableaux distincts accessibles en écriture, x, y et heading, de capacity octets chacun. Conservez-les pendant l’utilisation du corps. L’indice zéro est la tête, comprise dans count. Ne modifiez pas les pointeurs, la capacité ou les dimensions du terrain après l’initialisation.

Les orientations suivent 16 secteurs horaires : 0=droite, 4=bas, 8=gauche, 12=haut. Seuls les quatre bits de poids faible sont utilisés. Les coordonnées d’écran augmentent vers la droite et le bas ; chaque dimension va de 1 à 256 pixels.

Utilise la position mise à jour du prédécesseur pour trouver le point d’attache cible, puis calcule le plus court déplacement avec rebouclage sur chaque axe. Un déplacement nul ne bouge pas ; une amplitude de 1 à 4 avance d’un pixel, 5 ou plus de deux. À exactement un demi-terrain, conserve le signe initial.

Transmet à l’articulation suivante l’orientation sauvegardée avant la mise à jour de chacune, pour propager la courbure dans le corps. Un corps vide reste inchangé.

L’appelant gère vitesse et accélération de la tête, collisions, dessin et attente. Mettez normalement la tête à jour d’abord, puis appelez chain_body_step une fois par pas de simulation. Il s’agit de suivi d’articulations, pas d’un solveur de corps rigides ou de contraintes de longueur exactes.

Exemple d’utilisation

c
chain_body_step(&body,48,20,4); // The head turns down; only joint 1 receives 4.
    show_pose(8,34);
    for(step=1;step<4;step++) {
        chain_body_step(&body,48,(u8)(20+step),4);
    }
    // After four ticks, the new heading has reached joints 1 through 4.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.

chain_body_step: DMG — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
DMG — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
chain_body_step: CGB — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
CGB — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\chain_body.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\chain_body.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/chain.h:62

Notes de déclaration (texte source)
Install the caller's head pose, then pull joints from front to rear.
Each joint aims four pixels behind its updated predecessor and receives that
predecessor's OLD heading. Each axis moves 1 pixel, or 2 when error exceeds 4.
Call once per simulation tick; this does not advance head physics or render.

kitaqgb/lib/chain.c:162

c
void chain_body_step(ChainBody* body, u8 head_x, u8 head_y, u8 heading)
{
    u8 i;
    u8 previous;
    u8 pull;
    u8 old;
    u8 x;
    u8 y;
    u8 tx;
    u8 ty;
    s16 sx;
    s16 sy;
    if (body == 0) return;
    if (body->count == 0) return;
    heading = (u8)(heading & 15);
    body->x[0] = chain_body_wrap((s16)head_x, body->width);
    body->y[0] = chain_body_wrap((s16)head_y, body->height);
    body->heading[0] = heading;
    pull = heading;
    i = 1;
    while (i < body->count) {
        previous = (u8)(i - 1);
        old = body->heading[(__safe_index u8)i];
        x = body->x[(__safe_index u8)i];
        y = body->y[(__safe_index u8)i];
        tx = chain_body_wrap((s16)((s16)body->x[(__safe_index u8)previous] - chain_body_offset_x(pull)), body->width);
        ty = chain_body_wrap((s16)((s16)body->y[(__safe_index u8)previous] - chain_body_offset_y(pull)), body->height);
        sx = chain_body_correction(chain_wrap_delta(tx, x, body->width));
        sy = chain_body_correction(chain_wrap_delta(ty, y, body->height));
        body->heading[(__safe_index u8)i] = pull;
        body->x[(__safe_index u8)i] = chain_body_wrap((s16)((s16)x + sx), body->width);
        body->y[(__safe_index u8)i] = chain_body_wrap((s16)((s16)y + sy), body->height);
        // Save before overwriting: a bend advances by one joint per update.
        pull = old;
        i = (u8)(i + 1);
    }
}
chain_body_grow

Copie la position et l’orientation actuelles de la queue dans le prochain emplacement libre et augmente le nombre d’un.

Syntaxe

c
u8 chain_body_grow(ChainBody* body);

Paramètres

body

ChainBody cible ; null est ignoré. Sauf pour l’initialisation, passez un état déjà initialisé.

Valeur renvoyée

Renvoie 1 si une articulation a été ajoutée ; 0 pour un corps vide, plein, désactivé ou nul.

Conditions et limites

Incluez chain.h et compilez chain.c exactement une fois. ChainBody contient la position et l’orientation courantes de chaque articulation. Ce type d’état est distinct de l’historique circulaire de positions Chain.

Fournissez trois tableaux distincts accessibles en écriture, x, y et heading, de capacity octets chacun. Conservez-les pendant l’utilisation du corps. L’indice zéro est la tête, comprise dans count. Ne modifiez pas les pointeurs, la capacité ou les dimensions du terrain après l’initialisation.

Les orientations suivent 16 secteurs horaires : 0=droite, 4=bas, 8=gauche, 12=haut. Seuls les quatre bits de poids faible sont utilisés. Les coordonnées d’écran augmentent vers la droite et le bas ; chaque dimension va de 1 à 256 pixels.

La nouvelle queue chevauche d’abord l’ancienne, puis s’en sépare lors des appels suivants à chain_body_step. La croissance seule ne déplace ni la tête ni les autres articulations.

Exemple d’utilisation

c
chain_body_grow(&body); // Copy the tail pose into the eighth slot.
    chain_body_step(&body,48,16,0);
    chain_body_step(&body,48,16,0);
    chain_body_step(&body,48,16,0);
    chain_body_step(&body,48,16,0); // Allow the duplicated tail to separate.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.

chain_body_grow: DMG — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
DMG — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
chain_body_grow: CGB — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
CGB — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\chain_body.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\chain_body.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/chain.h:65

Notes de déclaration (texte source)
Append a copy of the current tail; later steps separate the new joint.
Return 1 on growth, or 0 for an empty, disabled or full body.

kitaqgb/lib/chain.c:200

c
u8 chain_body_grow(ChainBody* body)
{
    u8 tail;
    u8 next;
    if (body == 0) return 0;
    next = body->count;
    if (next == 0 || next >= body->capacity) return 0;
    tail = (u8)(next - 1);
    body->x[(__safe_index u8)next] = body->x[(__safe_index u8)tail];
    body->y[(__safe_index u8)next] = body->y[(__safe_index u8)tail];
    body->heading[(__safe_index u8)next] = body->heading[(__safe_index u8)tail];
    body->count = (u8)(next + 1);
    return 1;
}
chain_body_clear

Met le nombre d’articulations à zéro en conservant les tableaux et les réglages du terrain.

Syntaxe

c
void chain_body_clear(ChainBody* body);

Paramètres

body

ChainBody cible ; null est ignoré. Sauf pour l’initialisation, passez un état déjà initialisé.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Incluez chain.h et compilez chain.c exactement une fois. ChainBody contient la position et l’orientation courantes de chaque articulation. Ce type d’état est distinct de l’historique circulaire de positions Chain.

Fournissez trois tableaux distincts accessibles en écriture, x, y et heading, de capacity octets chacun. Conservez-les pendant l’utilisation du corps. L’indice zéro est la tête, comprise dans count. Ne modifiez pas les pointeurs, la capacité ou les dimensions du terrain après l’initialisation.

Les orientations suivent 16 secteurs horaires : 0=droite, 4=bas, 8=gauche, 12=haut. Seuls les quatre bits de poids faible sont utilisés. Les coordonnées d’écran augmentent vers la droite et le bas ; chaque dimension va de 1 à 256 pixels.

Les octets des tableaux ne sont pas effacés. Utilisez chain_body_reset pour recommencer ; appeler chain_body_grow juste après le vidage n’ajoute pas d’articulation.

Exemple d’utilisation

c
chain_body_clear(&body); // Forget the pose; the three arrays remain owned by us.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.

chain_body_clear: DMG — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
DMG — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
chain_body_clear: CGB — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.
CGB — L’image montre en haut un corps droit, au milieu une mise à jour après un virage vers le bas et en bas quatre mises à jour après ce virage. Les coordonnées sont dessinées au double de leur taille logique. La courbure se propage depuis la tête à droite vers l’arrière. CGB et FC utilisent rouge pour la tête, bleu pour le corps et vert pour la queue ; DMG utilise noir. Quatre mises à jour de stabilisation séparent la queue dupliquée après croissance. Ce sont trois vues des mêmes huit articulations, pas un corps de 24 articulations.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\chain_body.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\chain_body.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/chain.h:67

Notes de déclaration (texte source)
Remove all joints while retaining caller-owned storage and playfield settings.

kitaqgb/lib/chain.c:215

c
void chain_body_clear(ChainBody* body)
{
    if (body == 0) return;
    body->count = 0;
}
chain_clear

Oublie l’historique enregistré pour réutiliser le même tableau de stockage.

Syntaxe

c
void chain_clear(Chain* chain);

Paramètres

chain

Pointeur vers le Chain initialisé.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Remet le nombre d’éléments et head à zéro sans effacer ni libérer le tableau. L’appelant possède Chain et son tableau de points et doit les maintenir valides. Limitez la capacité à 128 pour éviter un débordement de l’addition des indices sur huit bits lors de la lecture.

La version GB exige un pointeur chain valide.

Exemple d’utilisation

c
chain_clear(&trail);result[11]=chain_get_count(&trail);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple vide un historique de quatre points et vérifie que son nombre d’éléments devient nul.

chain_clear: DMG
DMG
chain_clear: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_chain.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_chain.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/chain.h:21

Notes de déclaration (texte source)
Forget the recorded points without clearing or freeing the backing storage.

kitaqgb/lib/chain.c:14

c
void chain_clear(Chain* chain)
{
    chain->count = 0;
    chain->head = 0;
}
chain_get_count

Lit le nombre de positions actuellement disponibles dans l’historique.

Syntaxe

c
u8 chain_get_count(const Chain* chain);

Paramètres

chain

Pointeur vers le Chain initialisé.

Valeur renvoyée

Renvoie un nombre compris entre zéro et la capacité, ou zéro si la chaîne est nulle.

Conditions et limites

L’appelant possède à la fois Chain et son tableau de points, et doit les maintenir valides. Limitez la capacité à 128 pour éviter un débordement lors de l’addition des indices sur huit bits dans la fonction de lecture.

Exemple d’utilisation

c
result[4]=chain_get_count(&trail);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Après cinq insertions dans quatre emplacements, le nombre reste quatre. Il passe à zéro après effacement et reste nul pour un historique de capacité nulle.

chain_get_count: DMG
DMG
chain_get_count: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_chain.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_chain.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/chain.h:30

Notes de déclaration (texte source)
Return the number of stored points, or zero for a null chain.

kitaqgb/lib/chain.c:63

c
u8 chain_get_count(const Chain* chain)
{
    if (chain == 0) return 0;
    return chain->count;
}
chain_get_segment

Lit une position stockée en indiquant son ancienneté dans l’historique.

Syntaxe

c
u8 chain_get_segment(const Chain* chain, u8 index, ChainPoint* out);

Paramètres

chain

Pointeur vers le Chain initialisé.

index

Ancienneté du point : 0 désigne le plus récent et count - 1 le plus ancien conservé.

out

Objet ChainPoint modifiable et distinct pour recevoir le résultat ; un pointeur nul provoque un échec.

Valeur renvoyée

Renvoie 1 en cas de succès, ou 0 si la demande est invalide. Si out n’est pas nul, il est mis à (0,0) avant la validation.

Conditions et limites

out ne doit pas partager sa mémoire avec le tableau de stockage ou avec Chain : la remise à zéro de la sortie détruirait les données sources. L’appelant possède Chain et son tableau de points et doit les maintenir valides. Limitez la capacité à 128 pour éviter un débordement de l’addition des indices sur huit bits lors de la lecture.

Exemple d’utilisation

c
result[1]=chain_get_segment(&trail,0,&point);result[2]=point.x;result[3]=point.y;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’indice 0 lit le point le plus récent (40,24), l’indice 3 le plus ancien (16,8), et l’indice invalide 4 renvoie un échec avec une sortie (0,0).

chain_get_segment: DMG
DMG
chain_get_segment: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_chain.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_chain.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/chain.h:28

Notes de déclaration (texte source)
Read a point by age, with index zero denoting the newest point. Return zero
for an invalid request and clear a non-null output first. Keep head + index
within the 8-bit range: addition is narrowed before the capacity wrap.

kitaqgb/lib/chain.c:40

c
u8 chain_get_segment(const Chain* chain, u8 index, ChainPoint* out)
{
    u8 pos;
    if (out != 0) {
        out->x = 0;
        out->y = 0;
    }

    if (out == 0) return 0;
    if (chain == 0) return 0;
    if (chain->capacity == 0) return 0;
    if (index >= chain->count) return 0;

    pos = (u8)(chain->head + index);
    while (pos >= chain->capacity) {
        pos = (u8)(pos - chain->capacity);
    }
    out->x = chain->points[pos].x;
    out->y = chain->points[pos].y;
    return 1;
}
chain_init

Associe une zone de stockage à un historique circulaire de positions, initialement vide.

Syntaxe

c
void chain_init(Chain* chain, ChainPoint* storage, u8 capacity);

Paramètres

chain

Objet Chain modifiable à initialiser.

storage

Tableau pouvant contenir capacity éléments ChainPoint.

capacity

Nombre d’emplacements de points. Utilisez 1 à 128 pour un historique exploitable ; zéro désactive l’enregistrement.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

L’appelant possède à la fois Chain et son tableau de points, et doit les maintenir valides. Limitez la capacité à 128 pour éviter un débordement lors de l’addition des indices sur huit bits dans la fonction de lecture.

La version GB exige un pointeur chain valide.

Exemple d’utilisation

c
chain_init(&trail,storage,4);result[0]=chain_get_count(&trail);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple associe quatre emplacements de points et vérifie que le nombre initial est nul.

chain_init: DMG
DMG
chain_init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_chain.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_chain.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/chain.h:19

Notes de déclaration (texte source)
Attach caller-owned ring storage and start with no recorded points.
The storage must remain valid for the lifetime of the chain.
Use a valid chain pointer and capacity entries of caller-owned storage.
Capacity at most 128 keeps every head+age sum in the byte range used by the reader.

kitaqgb/lib/chain.c:5

c
void chain_init(Chain* chain, ChainPoint* storage, u8 capacity)
{
    chain->points = storage;
    chain->capacity = capacity;
    chain->count = 0;
    chain->head = 0;
}
chain_push_head

Ajoute la position la plus récente en tête de l’historique et remplace le point le plus ancien lorsque le tableau est plein.

Syntaxe

c
void chain_push_head(Chain* chain, s16 x, s16 y);

Paramètres

chain

Pointeur vers le Chain initialisé.

x

Coordonnée X signée du nouveau point.

y

Coordonnée Y signée du nouveau point.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Un pointeur de chaîne nul ou une capacité nulle ne produit aucun effet. L’appelant possède Chain et son tableau de points et doit les maintenir valides. Limitez la capacité à 128 pour éviter un débordement de l’addition des indices sur huit bits lors de la lecture.

Exemple d’utilisation

c
chain_push_head(&trail,8,8);chain_push_head(&trail,16,8);chain_push_head(&trail,24,16);chain_push_head(&trail,32,16);chain_push_head(&trail,40,24);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Après cinq insertions dans quatre emplacements, (40,24) est le point le plus récent et (16,8) le plus ancien conservé ; le point initial (8,8) a été remplacé.

chain_push_head: DMG
DMG
chain_push_head: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_chain.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_chain.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/chain.h:24

Notes de déclaration (texte source)
Move the ring head backward and store the newest point. Once full, each push
replaces the oldest point; zero capacity is a no-op.

kitaqgb/lib/chain.c:22

c
void chain_push_head(Chain* chain, s16 x, s16 y)
{
    if (chain == 0) return;
    if (chain->capacity == 0) return;

    if (chain->head == 0) chain->head = (u8)(chain->capacity - 1);
    else chain->head--;

    chain->points[chain->head].x = x;
    chain->points[chain->head].y = y;

    if (chain->count < chain->capacity) chain->count++;
}

danmaku.h — Réserves de projectiles, éventails, impacts et frôlements

Champ de projectiles sans allocation dynamique, jusqu’à 96 tirs sur 160×128 pixels. Offre déplacement au seizième de pixel, éventails à 32 directions, touches/frôlements et composition de tuiles à quatre quadrants. La simulation fonctionne sur GB ; le transfert present_now est réservé au CGB.

danmaku_clear

Désactive tous les projectiles et efface le nombre actif, les événements courants de touche/frôlement et le curseur d’allocation.

Syntaxe

c
void danmaku_clear();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Conserve les compteurs de pic et cumulés. Effacez puis transférez la carte RAM pour retirer les projectiles de l’écran.

Exemple d’utilisation

c
danmaku_clear();result[6]=dm_count;result[7]=dm_spawned;result[8]=dm_peak;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exemple de dessin réservé au CGB. Créez huit directions en (80,64), avancez huit fois et affichez huit points rouges de 3×3 disposés en étoile. Les projectiles cardinaux parcourent 32 pixels ; les diagonales utilisent une approximation entière. Vérifiez aussi le vidage du pool et la conservation des créations cumulées.

danmaku_clear: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_danmaku.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_danmaku.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/danmaku.h:35

Notes de déclaration (texte source)
Deactivate the pool while retaining peak/spawn/rejection counters and the RAM map.

kitaqgb/lib/danmaku.c:28

c
void danmaku_clear() {
    u8 i;
    for (i=0; i<DANMAKU_MAX; i++) dm_bullets[i].active=0;
    dm_count=0; dm_hit=0; dm_graze=0; dm_cursor=0;
}
danmaku_clear_map

Efface les 576 octets de la carte de tuiles RAM de 32×18.

Syntaxe

c
void danmaku_clear_map();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Laisse inchangés l’état des projectiles et la VRAM. À chaque trame, appelez clear_map, écrivez les décors, exécutez step puis transférez.

Exemple d’utilisation

c
danmaku_clear_map();result[11]=dm_map[0];

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exemple de dessin réservé au CGB. Créez huit directions en (80,64), avancez huit fois et affichez huit points rouges de 3×3 disposés en étoile. Les projectiles cardinaux parcourent 32 pixels ; les diagonales utilisent une approximation entière. Vérifiez aussi le vidage du pool et la conservation des créations cumulées.

danmaku_clear_map: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_danmaku.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_danmaku.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/danmaku.h:42

Notes de déclaration (texte source)
32 directions, 0=right, 8=down, 16=left, 24=up. speed in 1/16 px.
Clear the 32x18 RAM map before drawing the next frame; no transfer is performed.

kitaqgb/lib/danmaku.c:78

c
void danmaku_clear_map() {
    __asm {
        LD_HL_IMM dm_map
        LD_B_IMM 72
        XOR_A
    dm_clm_loop:
        LDI_HL_A
        LDI_HL_A
        LDI_HL_A
        LDI_HL_A
        LDI_HL_A
        LDI_HL_A
        LDI_HL_A
        LDI_HL_A
        DEC_B
        JR_NZ dm_clm_loop
        RET
    }
}
danmaku_fan

Génère un éventail à partir d’une table de vitesses à 32 directions et d’un pas angulaire fixe.

Syntaxe

c
void danmaku_fan(u8 x, u8 y, u8 direction, u8 step, u8 count, u8 speed);

Paramètres

x

X initial en pixels, de 0 à 159.

y

Y initial en pixels, de 0 à 127.

direction

Angle initial, masqué sur cinq bits : 0=droite, 8=bas, 16=gauche, 24=haut.

step

Incrément d’angle par projectile, avec rebouclage sur 32 directions.

count

Nombre de tentatives, limité à 96.

speed

Vitesse en seizièmes de pixel, limitée à 64, soit quatre pixels par mise à jour.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Continue les tentatives de création restantes même si le pool est plein. Les valeurs entières des tables sin/cos introduisent des arrondis dans le mouvement diagonal.

Exemple d’utilisation

c
danmaku_fan(80,64,0,4,8,64);result[9]=dm_count;result[10]=dm_spawned;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exemple de dessin réservé au CGB. Créez huit directions en (80,64), avancez huit fois et affichez huit points rouges de 3×3 disposés en étoile. Les projectiles cardinaux parcourent 32 pixels ; les diagonales utilisent une approximation entière. Vérifiez aussi le vidage du pool et la conservation des créations cumulées.

danmaku_fan: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_danmaku.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_danmaku.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/danmaku.h:39

Notes de déclaration (texte source)
Attempt a fan using wrapping 32-step angles; count is capped at 96 and speed at 64.

kitaqgb/lib/danmaku.c:62

c
void danmaku_fan(u8 x,u8 y,u8 direction,u8 step,u8 count,u8 speed) {
    u8 n;
    u8 a;
    s8 vx;
    s8 vy;
    if(count>DANMAKU_MAX) count=DANMAKU_MAX;
    if(speed>64) speed=64;
    a=direction&31;
    for(n=0;n<count;n++) {
        vx=(s8)(((s16)dm_cos[a]*(s16)speed)>>6);
        vy=(s8)(((s16)dm_sin[a]*(s16)speed)>>6);
        danmaku_spawn(x,y,vx,vy);
        a=(u8)((a+step)&31);
    }
}
danmaku_present_now

Transfère de manière synchrone les 576 octets de dm_map vers la carte de fond $9800 par GDMA CGB.

Syntaxe

c
void danmaku_present_now();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

CGB uniquement ; ne l’appelez pas sur DMG. Utilisez-la LCD éteint ou au début de VBlank. Sélectionne la banque VRAM zéro sans restaurer l’ancien VBK. L’application fournit les graphismes de projectiles dans les tuiles 0..15.

Exemple d’utilisation

c
// CGB general DMA; the LCD is stopped for this complete-map upload.
danmaku_present_now();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exemple de dessin réservé au CGB. Créez huit directions en (80,64), avancez huit fois et affichez huit points rouges de 3×3 disposés en étoile. Les projectiles cardinaux parcourent 32 pixels ; les diagonales utilisent une approximation entière. Vérifiez aussi le vidage du pool et la conservation des créations cumulées.

danmaku_present_now: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_danmaku.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_danmaku.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/danmaku.h:48

Notes de déclaration (texte source)
Requires CGB and LCD off or the beginning of VBlank. VBK restored to 0.
Transfers 18 rows (32-byte stride) to BG map 9800 with 36-block GDMA.

kitaqgb/lib/danmaku.c:301

c
void danmaku_present_now() {
    __asm {
        XOR_A
        LDH_MEM_A 0x4F
        LD_HL_IMM dm_map
        LD_A_H
        LDH_MEM_A 0x51
        LD_A_L
        LDH_MEM_A 0x52
        LD_A_IMM 0x18
        LDH_MEM_A 0x53
        XOR_A
        LDH_MEM_A 0x54
        LD_A_IMM 35
        LDH_MEM_A 0x55
        RET
    }
}
danmaku_reset

Vide le pool de 96 projectiles et réinitialise les compteurs de pic, de créations cumulées et de refus pour pool plein.

Syntaxe

c
void danmaku_reset();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Laisse inchangés les coordonnées du joueur, l’invulnérabilité et la carte de tuiles en RAM ; réglez-les séparément au début du jeu.

Exemple d’utilisation

c
danmaku_reset();result[0]=dm_count;result[1]=dm_peak;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exemple de dessin réservé au CGB. Créez huit directions en (80,64), avancez huit fois et affichez huit points rouges de 3×3 disposés en étoile. Les projectiles cardinaux parcourent 32 pixels ; les diagonales utilisent une approximation entière. Vérifiez aussi le vidage du pool et la conservation des créations cumulées.

danmaku_reset: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_danmaku.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_danmaku.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/danmaku.h:33

Notes de déclaration (texte source)
Reset pool, peak and lifetime counters; player fields and map contents remain caller-owned state.

kitaqgb/lib/danmaku.c:34

c
void danmaku_reset() {
    danmaku_clear(); dm_peak=0; dm_spawned=0; dm_rejected=0;
}
danmaku_spawn

Recherche cycliquement un emplacement libre et crée un projectile à la position et à la vitesse demandées.

Syntaxe

c
u8 danmaku_spawn(u8 x, u8 y, s8 vx, s8 vy);

Paramètres

x

X initial en pixels, de 0 à 159.

y

Y initial en pixels, de 0 à 127.

vx

Vitesse Q4.4 signée de −128 à 127 ; 16 déplace d’un pixel vers la droite par mise à jour.

vy

Vitesse Q4.4 signée ; une valeur positive déplace vers le bas.

Valeur renvoyée

Renvoie 1 après allocation, 0 pour des coordonnées extérieures ou un pool plein. Les demandes extérieures n’incrémentent pas dm_rejected.

Conditions et limites

Les positions sont stockées en seizièmes de pixel. Les totaux u16 de créations/refus rebouclent après 65535. Aucune allocation dynamique n’est utilisée.

Exemple d’utilisation

c
result[2]=danmaku_spawn(40,40,16,0);result[3]=danmaku_spawn(160,40,0,0);result[4]=dm_count;result[5]=dm_rejected;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exemple de dessin réservé au CGB. Créez huit directions en (80,64), avancez huit fois et affichez huit points rouges de 3×3 disposés en étoile. Les projectiles cardinaux parcourent 32 pixels ; les diagonales utilisent une approximation entière. Vérifiez aussi le vidage du pool et la conservation des créations cumulées.

danmaku_spawn: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_danmaku.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_danmaku.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/danmaku.h:37

Notes de déclaration (texte source)
Use pixel origins inside 160x128 and signed sixteenth-pixel velocities; return one if a slot was allocated.

kitaqgb/lib/danmaku.c:39

c
u8 danmaku_spawn(u8 x, u8 y, s8 vx, s8 vy) {
    u8 n;
    u8 i;
    if (x>=160 || y>=128) return 0;
    for(n=0;n<DANMAKU_MAX;n++) {
        i=dm_cursor;
        dm_cursor++;
        if(dm_cursor>=DANMAKU_MAX) dm_cursor=0;
        if(dm_bullets[i].active==0) {
            dm_bullets[i].x=(s16)((u16)x<<4);
            dm_bullets[i].y=(s16)((u16)y<<4);
            dm_bullets[i].vx=vx; dm_bullets[i].vy=vy;
            dm_bullets[i].active=1; dm_bullets[i].grazed=0;
            dm_count++; dm_spawned++;
            if(dm_count>dm_peak) dm_peak=dm_count;
            return 1;
        }
    }
    dm_rejected++;
    return 0;
}
danmaku_step

Avance chaque projectile une fois, retire ceux hors limites, compose les tuiles de projectiles et détecte touches et frôlements.

Syntaxe

c
void danmaku_step();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Les centres dessinés sont alignés sur une grille de quatre pixels. Des écarts d’au plus huit sur chaque axe donnent un premier frôlement ; d’au plus trois, une touche. L’invulnérabilité supprime seulement les touches. dm_hit/dm_graze sont remis à zéro à chaque appel ; chaque projectile ne frôle qu’une fois. Les ID de tuile 0..15 codent les quatre bits de quadrant ; les tuiles de décor occupées d’ID 16 ou plus sont remplacées.

Exemple d’utilisation

c
dm_player_x=0;dm_player_y=0;dm_invulnerable=0;for(i=0;i<8;i++){danmaku_clear_map();danmaku_step();}result[12]=dm_count;result[13]=dm_hit;result[14]=dm_graze;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exemple de dessin réservé au CGB. Créez huit directions en (80,64), avancez huit fois et affichez huit points rouges de 3×3 disposés en étoile. Les projectiles cardinaux parcourent 32 pixels ; les diagonales utilisent une approximation entière. Vérifiez aussi le vidage du pool et la conservation des créations cumulées.

danmaku_step: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_danmaku.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_danmaku.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/danmaku.h:45

Notes de déclaration (texte source)
Caller fills decoration after clear_map, then calls step to overlay bullets.
hit and graze are events for this step. Collision uses rendered centers.

kitaqgb/lib/danmaku.c:99

c
void danmaku_step() {
    // One linear pass. No per-bullet bank calls, multiplication or division.
    // The 8-byte packed public layout is x16,y16,vx8,vy8,active,graze.
    __asm {
        XOR_A
        LD_MEM_A dm_hit
        LD_MEM_A dm_graze
        LD_A_IMM 96
        LD_MEM_A dm_remaining
        LD_HL_IMM dm_bullets
    dm_tick_loop:
        PUSH_HL
        LD_BC_IMM 6
        ADD_HL_BC
        LD_A_HL
        OR_A
        JP_Z dm_tick_next
        DEC_HL
        LD_A_HL
        LD_MEM_A dm_vy
        DEC_HL
        LD_A_HL
        LD_C_A
        LD_B_IMM 0
        AND_IMM 128
        JR_Z dm_tick_xsign
        DEC_B
    // B:C is the sign-extended X velocity. Add to Q12.4 position; high byte >=10 also rejects negative X.
    dm_tick_xsign:
        POP_HL
        PUSH_HL
        LD_A_HL
        ADD_C
        LDI_HL_A
        LD_E_A
        LD_A_HL
        ADC_B
        LDI_HL_A
        CP_IMM 10
        JP_NC dm_tick_kill
        RRCA
        RRCA
        RRCA
        RRCA
        LD_D_A
        LD_A_E
        RRCA
        RRCA
        RRCA
        RRCA
        AND_IMM 15
        OR_D
        LD_MEM_A dm_px
        LD_A_MEM dm_vy
        LD_C_A
        LD_B_IMM 0
        AND_IMM 128
        JR_Z dm_tick_ysign
        DEC_B
    // Apply signed Y velocity similarly; high byte >=8 rejects negative Y and positions at or below 128 pixels.
    dm_tick_ysign:
        LD_A_HL
        ADD_C
        LDI_HL_A
        LD_E_A
        LD_A_HL
        ADC_B
        LDI_HL_A
        CP_IMM 8
        JP_NC dm_tick_kill
        RRCA
        RRCA
        RRCA
        RRCA
        LD_D_A
        LD_A_E
        RRCA
        RRCA
        RRCA
        RRCA
        AND_IMM 15
        OR_D
        LD_MEM_A dm_py
        // Signed differences shifted into 0..16 for a wrap-safe range test.
        // Rendered centers are (pixel & FC)+2. Test a square of radius eight around the player for graze eligibility.
        LD_A_MEM dm_player_x
        LD_C_A
        LD_A_MEM dm_px
        AND_IMM 252
        ADD_A_IMM 10
        SUB_C
        CP_IMM 17
        JR_NC dm_tick_plot
        LD_B_A
        LD_A_MEM dm_player_y
        LD_C_A
        LD_A_MEM dm_py
        AND_IMM 252
        ADD_A_IMM 10
        SUB_C
        CP_IMM 17
        JR_NC dm_tick_plot
        LD_C_A
        INC_HL
        INC_HL
        INC_HL
        LD_A_HL
        OR_A
        JR_NZ dm_tick_check_hit
        LD_A_IMM 1
        LD_HL_A
        LD_A_MEM dm_graze
        INC_A
        LD_MEM_A dm_graze
    // A bullet grazes at most once during its lifetime. Invulnerability suppresses hits, but not first-graze events.
    // The inner hit test uses a square of radius three around the same quantized center.
    dm_tick_check_hit:
        LD_A_MEM dm_invulnerable
        OR_A
        JR_NZ dm_tick_plot
        LD_A_B
        SUB_IMM 5
        CP_IMM 7
        JR_NC dm_tick_plot
        LD_A_C
        SUB_IMM 5
        CP_IMM 7
        JR_NC dm_tick_plot
        LD_A_IMM 1
        LD_MEM_A dm_hit
    // Select one of four quadrant bits from pixel bit 2, then address map[(y>>3)*32+(x>>3)].
    // Decoration IDs >=16 are replaced at occupied cells; bullet IDs 0..15 merge with OR.
    dm_tick_plot:
        LD_A_MEM dm_py
        AND_IMM 4
        AND_IMM 254
        RRCA
        LD_B_A
        LD_A_MEM dm_px
        AND_IMM 4
        AND_IMM 254
        RRCA
        AND_IMM 254
        RRCA
        OR_B
        LD_E_A
        LD_D_IMM 0
        LD_HL_IMM dm_bits
        ADD_HL_DE
        LD_A_HL
        LD_C_A
        LD_A_MEM dm_py
        AND_IMM 120
        LD_L_A
        LD_H_IMM 0
        ADD_HL_HL
        ADD_HL_HL
        LD_A_MEM dm_px
        AND_IMM 254
        RRCA
        AND_IMM 254
        RRCA
        AND_IMM 254
        RRCA
        LD_E_A
        LD_D_IMM 0
        ADD_HL_DE
        LD_DE_IMM dm_map
        ADD_HL_DE
        LD_A_HL
        CP_IMM 16
        JR_C dm_tick_merge
        XOR_A
    dm_tick_merge:
        OR_C
        LD_HL_A
        JR dm_tick_next
    // Restore the saved record base, clear active at offset six and decrement the live count exactly once.
    dm_tick_kill:
        POP_HL
        PUSH_HL
        LD_BC_IMM 6
        ADD_HL_BC
        XOR_A
        LD_HL_A
        LD_A_MEM dm_count
        DEC_A
        LD_MEM_A dm_count
    // Restore the saved base even for inactive or culled bullets, then advance by the fixed eight-byte record size.
    dm_tick_next:
        POP_HL
        LD_BC_IMM 8
        ADD_HL_BC
        LD_A_MEM dm_remaining
        DEC_A
        LD_MEM_A dm_remaining
        JP_NZ dm_tick_loop
        RET
    }
}

debug.h — Enregistrements en RAM et assertions

Enregistre des noms, des valeurs et des repères de trame dans un journal RAM de capacité fixe. Les assertions conservent les informations de diagnostic sans interrompre l’exécution.

debug_assert_fail

Conserve un code d’échec d’assertion et tente d’ajouter une entrée ASSERT.

Syntaxe

c
void debug_assert_fail(u16 code);

Paramètres

code

Identifiant d’erreur sur 16 bits à conserver.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

L’exécution continue. Le dernier code d’assertion est mis à jour même si le journal est plein. Le journal contient par défaut 32 entrées et abandonne les nouvelles lorsqu’il est plein. Si vous redéfinissez DEBUG_TRACE_MAX, utilisez partout la même valeur, entre 1 et 255, dans chaque unité de traduction. Les noms sont conservés sous forme de pointeurs, sans copie ; leur mémoire doit rester lisible jusqu’à la fin de l’inspection. Vous devez coordonner vous-même les écritures du code principal et des interruptions.

Exemple d’utilisation

c
debug_assert_fail(42);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple enregistre le code 42, remplit le journal, puis enregistre le code 999. Le nombre d’entrées reste 32, mais le dernier code devient 999.

debug_assert_fail: DMG
DMG
debug_assert_fail: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:33

Notes de déclaration (texte source)
Record the assertion code and attempt to append an ASSERT entry. This helper
does not halt execution, and the code is retained even if the log is full.

kitaqgb/lib/debug.c:56

c
void debug_assert_fail(u16 code)
{
    kq_debug_last_assert = code;
    debug_push((const u8*)"ASSERT", code);
}
debug_get_last_assert

Lit le dernier code d’assertion, indépendamment de la place disponible dans le journal.

Syntaxe

c
u16 debug_get_last_assert();

Valeur renvoyée

Renvoie le dernier code sur 16 bits ; sa valeur initiale après initialisation est zéro.

Conditions et limites

Zéro est aussi la valeur initiale : il ne permet pas de distinguer un échec enregistré avec le code zéro. La lecture n’efface pas le code.

Exemple d’utilisation

c
result[22]=debug_get_last_assert();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple vérifie 77 après la macro d’assertion, 999 une fois le journal plein et zéro après réinitialisation.

debug_get_last_assert: DMG
DMG
debug_get_last_assert: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:39

Notes de déclaration (texte source)
Read the last recorded assertion code, or the zero value installed by initialization.

kitaqgb/lib/debug.c:75

c
u16 debug_get_last_assert()
{
    return kq_debug_last_assert;
}
debug_get_trace_count

Lit le nombre d’entrées valides dans le tableau de trace.

Syntaxe

c
u8 debug_get_trace_count();

Valeur renvoyée

Renvoie un nombre compris entre zéro et DEBUG_TRACE_MAX.

Conditions et limites

Le journal contient par défaut 32 entrées et abandonne les nouvelles lorsqu’il est plein. Si vous redéfinissez DEBUG_TRACE_MAX, utilisez partout la même valeur, entre 1 et 255, dans chaque unité de traduction. Les noms sont conservés sous forme de pointeurs, sans copie ; leur mémoire doit rester lisible jusqu’à la fin de l’inspection. Vous devez coordonner vous-même les écritures du code principal et des interruptions.

Exemple d’utilisation

c
result[1]=debug_get_trace_count();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple vérifie les dix premières entrées, puis la limite de 32 après d’autres écritures. Le compteur ne revient pas à zéro lorsque le journal est plein.

debug_get_trace_count: DMG
DMG
debug_get_trace_count: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:35

Notes de déclaration (texte source)
Return the number of valid entries in the fixed trace buffer.

kitaqgb/lib/debug.c:63

c
u8 debug_get_trace_count()
{
    return kq_debug_trace_count;
}
debug_get_trace_log

Fournit une référence au tableau interne pour examiner les noms, valeurs et numéros de trame enregistrés.

Syntaxe

c
const DebugTraceEntry* debug_get_trace_log();

Valeur renvoyée

Renvoie un pointeur en lecture seule vers le tableau interne DebugTraceEntry.

Conditions et limites

Il ne s’agit pas d’une copie. Ne lisez que le nombre d’entrées indiqué par debug_get_trace_count(). Les anciens octets restants après initialisation ne sont pas des enregistrements valides. Le journal contient par défaut 32 entrées et abandonne les nouvelles lorsqu’il est plein. Si vous redéfinissez DEBUG_TRACE_MAX, utilisez partout la même valeur, entre 1 et 255, dans chaque unité de traduction. Les noms sont conservés sous forme de pointeurs, sans copie ; leur mémoire doit rester lisible jusqu’à la fin de l’inspection. Vous devez coordonner vous-même les écritures du code principal et des interruptions.

Exemple d’utilisation

c
entries=debug_get_trace_log();for(i=0;i<10;i++){result[2+i]=entries[i].value;result[12+i]=entries[i].frame;}

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple lit les dix champs de valeur et de trame, et vérifie le B initial du libellé BEGIN.

debug_get_trace_log: DMG
DMG
debug_get_trace_log: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:37

Notes de déclaration (texte source)
Expose the internal trace array for inspection; use the count to bound reads.

kitaqgb/lib/debug.c:69

c
const DebugTraceEntry* debug_get_trace_log()
{
    return kq_debug_trace_log;
}
debug_init

Initialise la longueur valide du journal, le numéro de trame associé et le dernier code d’assertion.

Syntaxe

c
void debug_init();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Les octets des entrées existantes ne sont pas effacés. Appelez cette fonction avant d’enregistrer la première entrée. Le journal contient par défaut 32 entrées et abandonne les nouvelles lorsqu’il est plein. Si vous redéfinissez DEBUG_TRACE_MAX, utilisez partout la même valeur, entre 1 et 255, dans chaque unité de traduction. Les noms sont conservés sous forme de pointeurs, sans copie ; leur mémoire doit rester lisible jusqu’à la fin de l’inspection. Vous devez coordonner vous-même les écritures du code principal et des interruptions.

Exemple d’utilisation

c
debug_init();result[0]=debug_get_trace_count();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple vérifie que le nombre initial est nul, puis réinitialise un journal rempli. Il contrôle que le nombre d’entrées et le code d’assertion sont effacés, alors que les anciennes valeurs du tableau subsistent.

debug_init: DMG
DMG
debug_init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:22

Notes de déclaration (texte source)
Reset log length, frame tag and last assertion code; existing entry bytes are not erased.

kitaqgb/lib/debug.c:10

c
void debug_init()
{
    kq_debug_trace_count = 0;
    kq_debug_frame = 0;
    kq_debug_last_assert = 0;
}
debug_mark_frame

Enregistre un marqueur de trame nommé pour repérer une étape du traitement.

Syntaxe

c
void debug_mark_frame(const u8* label);

Paramètres

label

Libellé terminé par zéro, dans une mémoire qui doit rester lisible jusqu’à l’inspection.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Le journal contient par défaut 32 entrées et abandonne les nouvelles lorsqu’il est plein. Si vous redéfinissez DEBUG_TRACE_MAX, utilisez partout la même valeur, entre 1 et 255, dans chaque unité de traduction. Les noms sont conservés sous forme de pointeurs, sans copie ; leur mémoire doit rester lisible jusqu’à la fin de l’inspection. Vous devez coordonner vous-même les écritures du code principal et des interruptions.

Exemple d’utilisation

c
debug_mark_frame("BEGIN");

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’ajout du marqueur BEGIN enregistre la valeur 65535 (0xFFFF) avec le numéro de trame 513.

debug_mark_frame: DMG
DMG
debug_mark_frame: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:26

Notes de déclaration (texte source)
Append a named frame marker using 0xFFFF as its value.

kitaqgb/lib/debug.c:37

c
void debug_mark_frame(const u8* label)
{
    debug_push(label, 0xFFFF);
}
debug_set_frame

Définit le numéro de trame qui sera copié dans les entrées suivantes du journal.

Syntaxe

c
void debug_set_frame(u16 frame);

Paramètres

frame

Numéro de trame sur 16 bits pour les entrées suivantes.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Cette fonction n’attend pas de trame et n’incrémente pas automatiquement le numéro. Passez explicitement le compteur de trames du jeu. Le journal contient par défaut 32 entrées et abandonne les nouvelles lorsqu’il est plein. Si vous redéfinissez DEBUG_TRACE_MAX, utilisez partout la même valeur, entre 1 et 255, dans chaque unité de traduction. Les noms sont conservés sous forme de pointeurs, sans copie ; leur mémoire doit rester lisible jusqu’à la fin de l’inspection. Vous devez coordonner vous-même les écritures du code principal et des interruptions.

Exemple d’utilisation

c
debug_set_frame(513);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple définit 513, écrit dix entrées, puis relit leurs dix champs de trame pour vérifier ce numéro.

debug_set_frame: DMG
DMG
debug_set_frame: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:24

Notes de déclaration (texte source)
Set the frame tag copied into subsequently recorded entries.

kitaqgb/lib/debug.c:18

c
void debug_set_frame(u16 frame)
{
    kq_debug_frame = frame;
}
debug_trace_u16

Enregistre un score ou un compteur sur 16 bits avec son nom.

Syntaxe

c
void debug_trace_u16(const u8* name, u16 value);

Paramètres

name

Libellé terminé par zéro, dans une mémoire qui doit rester lisible jusqu’à l’inspection.

value

Valeur de 0 à 65535 à enregistrer.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Le journal contient par défaut 32 entrées et abandonne les nouvelles lorsqu’il est plein. Si vous redéfinissez DEBUG_TRACE_MAX, utilisez partout la même valeur, entre 1 et 255, dans chaque unité de traduction. Les noms sont conservés sous forme de pointeurs, sans copie ; leur mémoire doit rester lisible jusqu’à la fin de l’inspection. Vous devez coordonner vous-même les écritures du code principal et des interruptions.

Exemple d’utilisation

c
debug_trace_u16("WORD",4660);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’entrée WORD stocke 4660 (0x1234), puis l’exemple la relit pour vérifier les deux octets.

debug_trace_u16: DMG
DMG
debug_trace_u16: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:30

Notes de déclaration (texte source)
Append a 16-bit value with the current frame tag.

kitaqgb/lib/debug.c:49

c
void debug_trace_u16(const u8* name, u16 value)
{
    debug_push(name, value);
}
debug_trace_u8

Enregistre une valeur d’état sur huit bits avec son nom et le numéro de trame courant.

Syntaxe

c
void debug_trace_u8(const u8* name, u8 value);

Paramètres

name

Libellé terminé par zéro, dans une mémoire qui doit rester lisible jusqu’à l’inspection.

value

Valeur de 0 à 255, étendue par des zéros dans le champ de 16 bits du journal.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Le journal contient par défaut 32 entrées et abandonne les nouvelles lorsqu’il est plein. Si vous redéfinissez DEBUG_TRACE_MAX, utilisez partout la même valeur, entre 1 et 255, dans chaque unité de traduction. Les noms sont conservés sous forme de pointeurs, sans copie ; leur mémoire doit rester lisible jusqu’à la fin de l’inspection. Vous devez coordonner vous-même les écritures du code principal et des interruptions.

Exemple d’utilisation

c
debug_trace_u8("BYTE",255);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’entrée BYTE enregistre 255 et vérifie que le champ de valeur sur 16 bits du journal contient bien 255.

debug_trace_u8: DMG
DMG
debug_trace_u8: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:28

Notes de déclaration (texte source)
Append an unsigned byte value, widened to the log's 16-bit value field.

kitaqgb/lib/debug.c:43

c
void debug_trace_u8(const u8* name, u8 value)
{
    debug_push(name, (u16)value);
}
KITAQGB_ASSERT

Macro utilisable comme une instruction, qui enregistre le code d’assertion 1 si sa condition est fausse.

Syntaxe

c
#define KITAQGB_ASSERT(cond) do { if (!(cond)) debug_assert_fail((u16)1); } while (0)

Paramètres

cond

Condition qui doit être vraie ; zéro signifie un échec.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

La condition est évaluée une seule fois. Si elle est vraie, rien n’est enregistré ; sinon, l’échec est consigné sans arrêter l’exécution. La forme do…while (0) permet d’utiliser la macro comme une seule instruction dans un if…else.

Exemple d’utilisation

c
KITAQGB_ASSERT(1);KITAQGB_ASSERT(0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Une assertion vraie et une assertion fausse produisent exactement une entrée de code 1.

KITAQGB_ASSERT: DMG
DMG
KITAQGB_ASSERT: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:45

c
#define KITAQGB_ASSERT(cond) do { if (!(cond)) debug_assert_fail((u16)1); } while (0)
KITAQGB_ASSERT_CODE

Enregistre le code d’assertion choisi uniquement si la condition est fausse.

Syntaxe

c
#define KITAQGB_ASSERT_CODE(cond, code) do { if (!(cond)) debug_assert_fail((u16)(code)); } while (0)

Paramètres

cond

Condition censée être vraie.

code

Expression du code, évaluée en cas d’échec et convertie sur 16 bits.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

La condition est évaluée une seule fois ; l’expression du code ne l’est qu’en cas d’échec. L’exécution continue après l’enregistrement.

Exemple d’utilisation

c
KITAQGB_ASSERT_CODE(1,++side_effect);KITAQGB_ASSERT_CODE(0,77);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Si la condition est vraie, l’expression de code ++side_effect n’est pas évaluée et la variable reste à zéro. Une condition fausse enregistre le code 77.

KITAQGB_ASSERT_CODE: DMG
DMG
KITAQGB_ASSERT_CODE: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:46

c
#define KITAQGB_ASSERT_CODE(cond, code) do { if (!(cond)) debug_assert_fail((u16)(code)); } while (0)
KITAQGB_MARK_FRAME

Convertit un libellé en pointeur de chaîne et ajoute un marqueur de trame de valeur 0xFFFF.

Syntaxe

c
#define KITAQGB_MARK_FRAME(label) debug_mark_frame((const u8*)(label))

Paramètres

label

Libellé terminé par zéro, dans une mémoire qui doit rester lisible jusqu’à l’inspection.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Le journal contient par défaut 32 entrées et abandonne les nouvelles lorsqu’il est plein. Si vous redéfinissez DEBUG_TRACE_MAX, utilisez partout la même valeur, entre 1 et 255, dans chaque unité de traduction. Les noms sont conservés sous forme de pointeurs, sans copie ; leur mémoire doit rester lisible jusqu’à la fin de l’inspection. Vous devez coordonner vous-même les écritures du code principal et des interruptions.

Exemple d’utilisation

c
KITAQGB_MARK_FRAME("END");

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le marqueur END est vérifié avec la valeur 65535 et le numéro de trame 513.

KITAQGB_MARK_FRAME: DMG
DMG
KITAQGB_MARK_FRAME: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:44

c
#define KITAQGB_MARK_FRAME(label) debug_mark_frame((const u8*)(label))
KITAQGB_TRACE

Convertit explicitement une valeur sur 16 bits, puis l’enregistre avec son nom.

Syntaxe

c
#define KITAQGB_TRACE(name, value) debug_trace_u16((const u8*)(name), (u16)(value))

Paramètres

name

Libellé terminé par zéro, dans une mémoire qui doit rester lisible jusqu’à l’inspection.

value

Expression convertie sur 16 bits avant enregistrement.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

La macro reste toujours active ; les paramètres de compilation ne la désactivent pas automatiquement. Elle enregistre les valeurs sur 16 bits comme KITAQGB_TRACE_U16. Le journal contient par défaut 32 entrées et abandonne les nouvelles lorsqu’il est plein. Si vous redéfinissez DEBUG_TRACE_MAX, utilisez partout la même valeur, entre 1 et 255, dans chaque unité de traduction. Les noms sont conservés sous forme de pointeurs, sans copie ; leur mémoire doit rester lisible jusqu’à la fin de l’inspection. Vous devez coordonner vous-même les écritures du code principal et des interruptions.

Exemple d’utilisation

c
KITAQGB_TRACE("SCORE",600);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple enregistre 600, puis relit cette valeur dans le journal pour la vérifier.

KITAQGB_TRACE: DMG
DMG
KITAQGB_TRACE: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:43

c
#define KITAQGB_TRACE(name, value) debug_trace_u16((const u8*)(name), (u16)(value))
KITAQGB_TRACE_U16

Convertit explicitement une valeur sur 16 bits, puis l’enregistre avec son nom.

Syntaxe

c
#define KITAQGB_TRACE_U16(name, value) debug_trace_u16((const u8*)(name), (u16)(value))

Paramètres

name

Libellé terminé par zéro, dans une mémoire qui doit rester lisible jusqu’à l’inspection.

value

Expression convertie sur 16 bits avant enregistrement.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

La macro reste toujours active ; les paramètres de compilation ne la désactivent pas automatiquement. Le journal contient par défaut 32 entrées et abandonne les nouvelles lorsqu’il est plein. Si vous redéfinissez DEBUG_TRACE_MAX, utilisez partout la même valeur, entre 1 et 255, dans chaque unité de traduction. Les noms sont conservés sous forme de pointeurs, sans copie ; leur mémoire doit rester lisible jusqu’à la fin de l’inspection. Vous devez coordonner vous-même les écritures du code principal et des interruptions.

Exemple d’utilisation

c
KITAQGB_TRACE_U16("WORD2",500);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple enregistre 500, puis relit cette valeur dans le journal pour la vérifier.

KITAQGB_TRACE_U16: DMG
DMG
KITAQGB_TRACE_U16: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:42

c
#define KITAQGB_TRACE_U16(name, value) debug_trace_u16((const u8*)(name), (u16)(value))
KITAQGB_TRACE_U8

Convertit explicitement une valeur sur huit bits, puis l’enregistre avec son nom.

Syntaxe

c
#define KITAQGB_TRACE_U8(name, value) debug_trace_u8((const u8*)(name), (u8)(value))

Paramètres

name

Libellé terminé par zéro, dans une mémoire qui doit rester lisible jusqu’à l’inspection.

value

Expression convertie sur huit bits avant enregistrement.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

La macro reste toujours active ; les paramètres de compilation ne la désactivent pas automatiquement. Le journal contient par défaut 32 entrées et abandonne les nouvelles lorsqu’il est plein. Si vous redéfinissez DEBUG_TRACE_MAX, utilisez partout la même valeur, entre 1 et 255, dans chaque unité de traduction. Les noms sont conservés sous forme de pointeurs, sans copie ; leur mémoire doit rester lisible jusqu’à la fin de l’inspection. Vous devez coordonner vous-même les écritures du code principal et des interruptions.

Exemple d’utilisation

c
KITAQGB_TRACE_U8("CAST",0x1234);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple enregistre 52. Seul l’octet de poids faible 0x34 de 0x1234 est conservé.

KITAQGB_TRACE_U8: DMG
DMG
KITAQGB_TRACE_U8: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_debug.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_debug.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/debug.h:41

c
#define KITAQGB_TRACE_U8(name, value) debug_trace_u8((const u8*)(name), (u8)(value))

dmg3d.h — Rendu filaire monochrome de 128×120 pour DMG

Dessin de lignes 3D monochromes. Fournissez sommets, arêtes et faces du modèle, ainsi que position, rotation et échelle de l’objet. Suivez l’ordre initialisation, début d’image, dessin, transfert. La physique est séparée. Les angles ont seize pas par tour ; l’échelle de modèle 256 vaut l’unité.

Vec3 contient x/y/z, Edge les indices de sommets a/b, et Face les indices de triangle a/b/c. Les champs vertices, edges et faces de Model pointent vers ces tableaux ; chaque compteur en donne la longueur. edge_faces contient les indices des faces adjacentes f0/f1, avec FACE_NONE pour une face absente. MODEL_HIDDEN_LINES dans flags demande une sélection d’arêtes fondée sur les faces. L’aire projetée signée détermine l’orientation d’une face : l’ordre des sommets compte.

Object mémorise une référence au modèle, la position x/y/z, les angles rx/ry/rz, scale_q8 et visible. Les objets peuvent partager un modèle, mais le dessin ne copie pas les tables et ne change pas automatiquement leurs banques ROM. Gardez les données référencées lisibles pendant tout le dessin. L’Object CGB possède aussi un indice de couleur.

DMG3D_BeginFrame

Commence le dessin d’une image et désactive le test d’occlusion.

Syntaxe

c
void DMG3D_BeginFrame();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Désactive uniquement le filtrage d’occlusion. La zone de préparation est normalement effacée pendant le transfert ; Init fournit la première zone vierge. Ne supprime pas une image non soumise, n’efface pas le masque et ne réinitialise ni écritures BG en attente ni indicateurs de modification.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    DMG3D_SetCamera(8,0,0,0,0,0);
    result[1]=DMG3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=DMG3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    DMG3D_SetCamera(0,0,0,0,0,0);
    DMG3D_BeginFrame();
    DMG3D_DrawLine2D(8,8,56,8);
    DMG3D_DrawLine2D(56,8,56,40);
    DMG3D_DrawLine2D(56,40,8,40);
    DMG3D_DrawLine2D(8,40,8,8);
    DMG3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    DMG3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    DMG3D_PutBgTile(1,1,160);
    DMG3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

DMG3D_BeginFrame: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG3D_BeginFrame: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_raster.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:17

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Disable occlusion filtering only. Stage clearing normally happens during
transfer, and Init supplies the first clean stage. This does not discard an
unsubmitted frame, clear the mask, or reset pending BG writes/dirty flags.

kitaqgb/lib/wire3d_dmg.c:2641

c
void Wire3DDMG_BeginFrame()
{




    /* The consuming stage transfer clears D000 as it uploads, so BeginFrame only
       resets draw state. Wire3DDMG_Init supplies the first clean buffer. */

    w3ddmg_occlusion_active = 0;
}
DMG3D_DrawIndexedEdges

Dessine un modèle de lignes à échelle entière à partir de sommets et de paires d’indices d’arêtes sur deux octets.

Syntaxe

c
void DMG3D_DrawIndexedEdges(const Wire3DDMG_Vec3* vertices, w3ddmg_u8 vertex_count, const w3ddmg_u8* edges, w3ddmg_u8 edge_count, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 scale);

Paramètres

vertices

Tableau de sommets 3D.

vertex_count

Nombre d’entrées du tableau de sommets.

edges

Indices des sommets de chaque arête, dans le format déclaré de structure ou de paire d’octets.

edge_count

Nombre d’arêtes.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

scale

Échelle entière ; zéro est traité comme un.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Trace les arêtes indexées par paires d’octets après mise à l’échelle entière et translation ; l’échelle zéro signifie un, sans rotation d’objet ni filtrage de faces. Projette au plus 24 sommets. Fournissez au plus 128 paires d’arêtes, car les décalages sur octets bouclent après 255. Ignore les ID de sommets invalides, les extrémités rejetées en profondeur et les tableaux null. Produits et sommes de coordonnées doivent tenir dans s16.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Upload a main line and an auxiliary block separately; verify source consumption.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom DMG3D_Vec3 vertices[2]={{-32,0,0},{32,0,0}};
__prg_rom u8 edge_pairs[2]={0,1};
u8* stage_byte;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        DMG3D_BeginFrame();
    DMG3D_DrawIndexedEdges(vertices,2,edge_pairs,1,-64,104,96,1);
    DMG3D_TransferMainNow();
    // Direct auxiliary transfer writes a separate tile after the main upload.
    for(i=24;i<=31;i++) DMG3D_DrawLine2D(40,i,47,i);
    stage_byte=(u8*)0xD518;result[1]=*stage_byte;
    DMG3D_TransferAuxNow();result[2]=*stage_byte;

    // Do not upload the consumed stage again.
    result[7]=0xA55A; while(1) {}
}

Résultat attendu

Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.

DMG3D_DrawIndexedEdges: DMG — Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.
DMG — Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.
DMG3D_DrawIndexedEdges: CGB — Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.
CGB — Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_direct.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_direct.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:20

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Draw byte-pair edge indices after integer scaling and translation; scale
zero means one, and there is no object rotation or face filtering. Project at
most 24 vertices. Supply at most 128 edge pairs because byte offsets wrap
after 255. Invalid vertex IDs/depth-rejected endpoints are skipped; null arrays
are ignored. Keep coordinate products/sums representable as s16.

kitaqgb/lib/wire3d_dmg.c:3824

c
void Wire3DDMG_DrawIndexedEdges(const Wire3DDMG_Vec3* vertices, w3ddmg_u8 vertex_count, const w3ddmg_u8* edges, w3ddmg_u8 edge_count, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 scale)
{
    w3ddmg_u8 i;
    w3ddmg_u8 count;

    if (vertices == 0) return;
    if (edges == 0) return;

    count = vertex_count;
    if (count > WIRE3D_DMG_MODEL_VERTEX_LIMIT) count = WIRE3D_DMG_MODEL_VERTEX_LIMIT;
    if (scale == 0) scale = 1;

    i = 0;
    while (i < count)
    {
        const Wire3DDMG_Vec3* v;
        w3ddmg_i16 vx;
        w3ddmg_i16 vy;
        w3ddmg_i16 vz;
        w3ddmg_u8 sx;
        w3ddmg_u8 sy;

        v = &vertices[(__safe_index w3ddmg_u8)i];
        vx = (w3ddmg_i16)(x + (w3ddmg_i16)(v->x * scale));
        vy = (w3ddmg_i16)(y + (w3ddmg_i16)(v->y * scale));
        vz = (w3ddmg_i16)(z + (w3ddmg_i16)(v->z * scale));

        if (w3ddmg_project_world(vx, vy, vz, &sx, &sy))
        {
            w3ddmg_screen_x[(__safe_index w3ddmg_u8)i] = sx;
            w3ddmg_screen_y[(__safe_index w3ddmg_u8)i] = sy;
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 1;
        }
        else
        {
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 0;
        }

        i = (w3ddmg_u8)(i + 1);
    }

    i = 0;
    while (i < edge_count)
    {
        w3ddmg_u8 a;
        w3ddmg_u8 b;

        a = edges[(__safe_index w3ddmg_u8)((w3ddmg_u8)(i << 1))];
        b = edges[(__safe_index w3ddmg_u8)((w3ddmg_u8)((i << 1) + 1))];
        if ((a < count) && (b < count) &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)a] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)b])
        {
            Wire3DDMG_DrawLine2D(
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)a],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)a],
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)b],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)b]);
        }

        i = (w3ddmg_u8)(i + 1);
    }
}
DMG3D_DrawLine2D

Trace dans la zone de préparation une ligne en coordonnées écran à connexité 4, extrémités incluses.

Syntaxe

c
void DMG3D_DrawLine2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by);

Paramètres

ax

Coordonnée X du sommet A en pixels du viewport.

ay

Coordonnée Y du sommet A en pixels du viewport.

bx

Coordonnée X du sommet B en pixels du viewport.

by

Coordonnée Y du sommet B en pixels du viewport.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Si le transfert des zones modifiées est actif, marque le rectangle englobant en tuiles, puis trace une ligne connexe préparée. Le dessin de scène peut la rejeter avec cinq échantillons du masque. Fournissez des extrémités dans le viewport 128×120 ; les contrôles de pixels bas niveau ne découpent pas géométriquement le segment.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    DMG3D_SetCamera(8,0,0,0,0,0);
    result[1]=DMG3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=DMG3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    DMG3D_SetCamera(0,0,0,0,0,0);
    DMG3D_BeginFrame();
    DMG3D_DrawLine2D(8,8,56,8);
    DMG3D_DrawLine2D(56,8,56,40);
    DMG3D_DrawLine2D(56,40,8,40);
    DMG3D_DrawLine2D(8,40,8,8);
    DMG3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    DMG3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    DMG3D_PutBgTile(1,1,160);
    DMG3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

DMG3D_DrawLine2D: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG3D_DrawLine2D: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_raster.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:21

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Mark the bounding tile rectangle when dirty transfer is enabled, then draw
a connected staged line. Scene drawing may reject it using five mask samples.
Supply 128x120 viewport endpoints; low-level pixel bounds checks do not clip
the segment geometrically.

kitaqgb/lib/wire3d_dmg.c:2685

c
void Wire3DDMG_DrawLine2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by)
{

    w3ddmg_mark_line_dirty(ax, ay, bx, by);


    if (w3ddmg_occlusion_active)
    {
        w3ddmg_line_stage_masked_c(ax, ay, bx, by);
        return;
    }

    w3ddmg_line_x0 = ax;
    w3ddmg_line_y0 = ay;
    w3ddmg_line_x1 = bx;
    w3ddmg_line_y1 = by;
    if (ax < 128 && bx < 128 && ay < WIRE3D_DMG_SCREEN_H && by < WIRE3D_DMG_SCREEN_H)
        w3ddmg_line_inside_asm();
    else
        w3ddmg_line_stage_asm();
}
DMG3D_DrawLine3D

Projette deux extrémités du monde et trace une ligne entre elles.

Syntaxe

c
void DMG3D_DrawLine3D(w3ddmg_i16 ax, w3ddmg_i16 ay, w3ddmg_i16 az, w3ddmg_i16 bx, w3ddmg_i16 by, w3ddmg_i16 bz);

Paramètres

ax

Composante X du point de départ en coordonnées du monde.

ay

Composante Y du point de départ en coordonnées du monde.

az

Composante Z du point de départ en coordonnées du monde.

bx

Composante X du point d’arrivée en coordonnées du monde.

by

Composante Y du point d’arrivée en coordonnées du monde.

bz

Composante Z du point d’arrivée en coordonnées du monde.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Projette les deux extrémités du monde et dessine uniquement si les deux passent la plage de profondeur. Ne calcule pas l’intersection d’un segment traversant avec les plans proche ou lointain ; chaque extrémité projetée est bornée indépendamment aux bords de l’écran.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    DMG3D_SetCamera(8,0,0,0,0,0);
    result[1]=DMG3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=DMG3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    DMG3D_SetCamera(0,0,0,0,0,0);
    DMG3D_BeginFrame();
    DMG3D_DrawLine2D(8,8,56,8);
    DMG3D_DrawLine2D(56,8,56,40);
    DMG3D_DrawLine2D(56,40,8,40);
    DMG3D_DrawLine2D(8,40,8,8);
    DMG3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    DMG3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    DMG3D_PutBgTile(1,1,160);
    DMG3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

DMG3D_DrawLine3D: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG3D_DrawLine3D: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_raster.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:22

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Project both world endpoints and draw only when both pass the depth range.
Do not intersect a crossing segment with near/far planes; projected endpoints
are independently clamped to the screen edges.

kitaqgb/lib/wire3d_dmg.c:2808

c
void Wire3DDMG_DrawLine3D(w3ddmg_i16 ax, w3ddmg_i16 ay, w3ddmg_i16 az, w3ddmg_i16 bx, w3ddmg_i16 by, w3ddmg_i16 bz)
{
    w3ddmg_u8 sx0;
    w3ddmg_u8 sy0;
    w3ddmg_u8 sx1;
    w3ddmg_u8 sy1;

    if (w3ddmg_project_world(ax, ay, az, &sx0, &sy0) == 0) return;
    if (w3ddmg_project_world(bx, by, bz, &sx1, &sy1) == 0) return;
    Wire3DDMG_DrawLine2D(sx0, sy0, sx1, sy1);
}
DMG3D_DrawModel

Dessine un modèle de sommets et d’arêtes à la position et avec la rotation demandées, à l’échelle unitaire.

Syntaxe

c
void DMG3D_DrawModel(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Dessine un modèle sans redimensionnement en appelant DrawModelScaled avec l’échelle 256.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Compare direct model scaling with an object-array scene.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom DMG3D_Vec3 vertices[8]={{-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},{-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}};
__prg_rom DMG3D_Edge edges[12]={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
DMG3D_Model cube;
DMG3D_Object objects[2];
s16 px; s16 py; s16 pz;
void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;

    cube.vertices=vertices;cube.edges=edges;cube.faces=0;cube.edge_faces=0;
    cube.vertex_count=8;cube.edge_count=12;cube.face_count=0;cube.flags=0;

    DMG3D_BeginFrame();
    // Upper pair: direct model calls at unity and half scale.
    DMG3D_DrawModel(&cube,-32,32,96,0,0,0);
    DMG3D_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    // Lower pair: the caller owns both object records and the model tables.
    for(i=0;i<2;i++) {
        objects[i].model=&cube;objects[i].x=-32+(s16)i*64;
        objects[i].y=-32;objects[i].z=96;
        objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256-(s16)i*128;objects[i].visible=1;
    }
    DMG3D_DrawScene(objects,2);
    // Numeric checks cover the operation supplied by this viewport profile.
    px=16;py=0;pz=0;DMG3D_RotatePoint(&px,&py,&pz,0,4,0);
    result[1]=px; result[2]=py; result[3]=pz;
    DMG3D_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

DMG3D_DrawModel: DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
DMG3D_DrawModel: CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_models.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:23

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Draw an unscaled model by delegating to DrawModelScaled with scale 256.

kitaqgb/lib/wire3d_dmg.c:2827

c
void Wire3DDMG_DrawModel(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz)

{
    Wire3DDMG_DrawModelScaled(model, x, y, z, rx, ry, rz, 256);
}
DMG3D_DrawModelScaled

Redimensionne un modèle, le tourne dans l’ordre Y/X/Z, translate et projette ses sommets, puis trace ses arêtes.

Syntaxe

c
void DMG3D_DrawModelScaled(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz, w3ddmg_i16 scale_q8);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

scale_q8

Échelle dont l’unité vaut 256 ; les valeurs nulles ou négatives signifient aussi l’unité.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Redimensionne au plus 24 sommets, les tourne Y/X/Z, les translate et les projette, puis parcourt les edge_count entrées, compteur sur un octet, avec filtrage facultatif par faces adjacentes. Le tampon de faces est limité à 16 ; les tables d’arêtes doivent contenir toutes les entrées déclarées. Une échelle non positive signifie 256. Les pointeurs de modèle, sommets ou arêtes nuls sont ignorés. Gardez produits et translations sur 16 bits signés ; les arêtes traversant une limite de profondeur sont rejetées.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Compare direct model scaling with an object-array scene.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom DMG3D_Vec3 vertices[8]={{-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},{-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}};
__prg_rom DMG3D_Edge edges[12]={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
DMG3D_Model cube;
DMG3D_Object objects[2];
s16 px; s16 py; s16 pz;
void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;

    cube.vertices=vertices;cube.edges=edges;cube.faces=0;cube.edge_faces=0;
    cube.vertex_count=8;cube.edge_count=12;cube.face_count=0;cube.flags=0;

    DMG3D_BeginFrame();
    // Upper pair: direct model calls at unity and half scale.
    DMG3D_DrawModel(&cube,-32,32,96,0,0,0);
    DMG3D_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    // Lower pair: the caller owns both object records and the model tables.
    for(i=0;i<2;i++) {
        objects[i].model=&cube;objects[i].x=-32+(s16)i*64;
        objects[i].y=-32;objects[i].z=96;
        objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256-(s16)i*128;objects[i].visible=1;
    }
    DMG3D_DrawScene(objects,2);
    // Numeric checks cover the operation supplied by this viewport profile.
    px=16;py=0;pz=0;DMG3D_RotatePoint(&px,&py,&pz,0,4,0);
    result[1]=px; result[2]=py; result[3]=pz;
    DMG3D_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

DMG3D_DrawModelScaled: DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
DMG3D_DrawModelScaled: CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_models.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:24

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Scale up to 24 vertices, rotate Y/X/Z, translate and project, then traverse
all edge_count entries (a byte count) with optional adjacent-face filtering.
Face scratch is capped at 16; edge tables must contain all declared entries.
Nonpositive scale means 256. Null model/vertex/edge pointers are ignored.
Keep products/translations in signed 16-bit range; depth-crossing edges are dropped.

kitaqgb/lib/wire3d_dmg.c:2972

c
void Wire3DDMG_DrawModelScaled(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz, w3ddmg_i16 scale_q8)

{
    w3ddmg_u8 i;
    w3ddmg_u8 count;
    w3ddmg_u8 edge_count;
    w3ddmg_u8 face_count;

    if (model == 0) return;
    if (model->vertices == 0) return;
    if (model->edges == 0) return;
    if (scale_q8 <= 0) scale_q8 = 256;

    count = model->vertex_count;
    if (count > WIRE3D_DMG_MODEL_VERTEX_LIMIT) count = WIRE3D_DMG_MODEL_VERTEX_LIMIT;

    i = 0;
    while (i < count)
    {
        const Wire3DDMG_Vec3* v;
        w3ddmg_i16 vx;
        w3ddmg_i16 vy;
        w3ddmg_i16 vz;
        w3ddmg_u8 sx;
        w3ddmg_u8 sy;

        v = &model->vertices[(__safe_index w3ddmg_u8)i];
        vx = (w3ddmg_i16)((v->x * scale_q8) >> 8);
        vy = (w3ddmg_i16)((v->y * scale_q8) >> 8);
        vz = (w3ddmg_i16)((v->z * scale_q8) >> 8);






        w3ddmg_rotate_y(&vx, &vz, ry);
        w3ddmg_rotate_x(&vy, &vz, rx);
        w3ddmg_rotate_z(&vx, &vy, rz);


        vx = (w3ddmg_i16)(vx + x);
        vy = (w3ddmg_i16)(vy + y);
        vz = (w3ddmg_i16)(vz + z);

        if (w3ddmg_project_world(vx, vy, vz, &sx, &sy))
        {
            w3ddmg_screen_x[(__safe_index w3ddmg_u8)i] = sx;
            w3ddmg_screen_y[(__safe_index w3ddmg_u8)i] = sy;
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 1;
        }
        else
        {
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 0;
        }
        i = (w3ddmg_u8)(i + 1);
    }

    face_count = model->face_count;
    if (face_count > WIRE3D_DMG_MODEL_FACE_LIMIT) face_count = WIRE3D_DMG_MODEL_FACE_LIMIT;
    if ((model->flags & WIRE3D_DMG_MODEL_HIDDEN_LINES) && (model->faces != 0) && (model->edge_faces != 0))
    {
        w3ddmg_build_face_visibility(model, count, face_count);
    }

    edge_count = model->edge_count;




    i = 0;
    while (i < edge_count)
    {
        const Wire3DDMG_Edge* e;
        e = &model->edges[(__safe_index w3ddmg_u8)i];
        if ((e->a < count) && (e->b < count))
        {
            if (w3ddmg_screen_visible[(__safe_index w3ddmg_u8)e->a] &&
                w3ddmg_screen_visible[(__safe_index w3ddmg_u8)e->b] &&



                w3ddmg_is_edge_visible(model, i, face_count))

            {
                Wire3DDMG_DrawLine2D(
                    w3ddmg_screen_x[(__safe_index w3ddmg_u8)e->a],
                    w3ddmg_screen_y[(__safe_index w3ddmg_u8)e->a],
                    w3ddmg_screen_x[(__safe_index w3ddmg_u8)e->b],
                    w3ddmg_screen_y[(__safe_index w3ddmg_u8)e->b]);
            }
        }
        i = (w3ddmg_u8)(i + 1);
    }
}
DMG3D_DrawScene

Dessine au plus huit objets du plus proche au plus lointain, les faces proches masquant les arêtes suivantes.

Syntaxe

c
void DMG3D_DrawScene(Wire3DDMG_Object* objects, w3ddmg_u8 count);

Paramètres

objects

Tableau d’objets contenant positions, rotations, échelles et indicateurs de visibilité.

count

Nombre d’entrées fournies ; consultez la limite de traitement propre à l’opération.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Trie au plus huit origines d’objets selon leur profondeur caméra, du plus proche au plus lointain. Dessine les modèles visibles et valides et marque les rectangles englobants des faces avant pour les objets suivants. La première place triée évite les tests de masque ; la dernière n’ajoute pas d’occultant. C’est un rejet grossier de lignes, pas un tampon de profondeur. Ignore null et les entrées vides ; données de l’appelant et cache de projection courant doivent rester valides pendant le parcours.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Compare direct model scaling with an object-array scene.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom DMG3D_Vec3 vertices[8]={{-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},{-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}};
__prg_rom DMG3D_Edge edges[12]={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
DMG3D_Model cube;
DMG3D_Object objects[2];
s16 px; s16 py; s16 pz;
void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;

    cube.vertices=vertices;cube.edges=edges;cube.faces=0;cube.edge_faces=0;
    cube.vertex_count=8;cube.edge_count=12;cube.face_count=0;cube.flags=0;

    DMG3D_BeginFrame();
    // Upper pair: direct model calls at unity and half scale.
    DMG3D_DrawModel(&cube,-32,32,96,0,0,0);
    DMG3D_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    // Lower pair: the caller owns both object records and the model tables.
    for(i=0;i<2;i++) {
        objects[i].model=&cube;objects[i].x=-32+(s16)i*64;
        objects[i].y=-32;objects[i].z=96;
        objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256-(s16)i*128;objects[i].visible=1;
    }
    DMG3D_DrawScene(objects,2);
    // Numeric checks cover the operation supplied by this viewport profile.
    px=16;py=0;pz=0;DMG3D_RotatePoint(&px,&py,&pz,0,4,0);
    result[1]=px; result[2]=py; result[3]=pz;
    DMG3D_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

DMG3D_DrawScene: DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
DMG3D_DrawScene: CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_models.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:25

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Sort at most eight object origins by camera depth, near to far. Draw visible
valid models and mark front-face bounding rectangles for later objects. The
first sorted slot bypasses mask tests and the last needs no new occluder.
This is coarse line rejection, not a depth buffer. Null/empty input is ignored;
caller data and the current projection cache must remain valid during traversal.

kitaqgb/lib/wire3d_dmg.c:2723

c
void Wire3DDMG_DrawScene(Wire3DDMG_Object* objects, w3ddmg_u8 count)
{
    w3ddmg_u8 scene_count;
    w3ddmg_u8 i;

    if (objects == 0) return;

    scene_count = count;
    if (scene_count > WIRE3D_DMG_SCENE_OBJECT_LIMIT) scene_count = WIRE3D_DMG_SCENE_OBJECT_LIMIT;

    if (scene_count == 0) return;


    i = 0;
    while (i < scene_count)
    {
        w3ddmg_scene_order[(__safe_index w3ddmg_u8)i] = i;
        w3ddmg_scene_depth[(__safe_index w3ddmg_u8)i] = w3ddmg_scene_object_depth(&objects[(__safe_index w3ddmg_u8)i]);
        i = (w3ddmg_u8)(i + 1);
    }

    i = 0;
    while (i < scene_count)
    {
        w3ddmg_u8 j;
        j = (w3ddmg_u8)(i + 1);
        while (j < scene_count)
        {
            w3ddmg_u8 oi;
            w3ddmg_u8 oj;
            oi = w3ddmg_scene_order[(__safe_index w3ddmg_u8)i];
            oj = w3ddmg_scene_order[(__safe_index w3ddmg_u8)j];





            if (w3ddmg_scene_depth[(__safe_index w3ddmg_u8)oj] < w3ddmg_scene_depth[(__safe_index w3ddmg_u8)oi])
            {
                w3ddmg_scene_order[(__safe_index w3ddmg_u8)i] = oj;
                w3ddmg_scene_order[(__safe_index w3ddmg_u8)j] = oi;
            }
            j = (w3ddmg_u8)(j + 1);
        }
        i = (w3ddmg_u8)(i + 1);
    }

    w3ddmg_clear_occlusion_mask();



    w3ddmg_occlusion_active = 0;


    i = 0;
    while (i < scene_count)
    {
        Wire3DDMG_Object* obj;
        obj = &objects[(__safe_index w3ddmg_u8)w3ddmg_scene_order[(__safe_index w3ddmg_u8)i]];
        if ((obj->visible != 0) && (obj->model != 0))
        {




            w3ddmg_occlusion_active = i == 0 ? 0 : 1;
            Wire3DDMG_DrawModelScaled(obj->model, obj->x, obj->y, obj->z, obj->rx, obj->ry, obj->rz, obj->scale_q8);
            if ((w3ddmg_u8)(i + 1) < scene_count)
            {
                w3ddmg_mark_model_occluder(obj->model);
            }

        }
        i = (w3ddmg_u8)(i + 1);
    }

    w3ddmg_occlusion_active = 0;
}
DMG3D_EndFrame

Soumet à la VRAM les écritures du fond en attente et le dessin préparé.

Syntaxe

c
void DMG3D_EndFrame();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Attend le prochain VBlank et applique les écritures BG, puis consomme éventuellement les bandes auxiliaires avant de transférer les tuiles modifiées ou toute la zone principale. Le recouvrement des sources auxiliaire et principale rend cet ordre important. L’interrogation de STAT continue à travers les fenêtres d’accès ; la mise à jour peut dépasser un seul VBlank.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    DMG3D_SetCamera(8,0,0,0,0,0);
    result[1]=DMG3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=DMG3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    DMG3D_SetCamera(0,0,0,0,0,0);
    DMG3D_BeginFrame();
    DMG3D_DrawLine2D(8,8,56,8);
    DMG3D_DrawLine2D(56,8,56,40);
    DMG3D_DrawLine2D(56,40,8,40);
    DMG3D_DrawLine2D(8,40,8,8);
    DMG3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    DMG3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    DMG3D_PutBgTile(1,1,160);
    DMG3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

DMG3D_EndFrame: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG3D_EndFrame: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_raster.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:28

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Wait for the next VBlank and flush BG writes, then optionally consume the
auxiliary strips before uploading either dirty tiles or the entire main stage.
Auxiliary/main source overlap makes that ordering significant. STAT polling
continues across access windows; the update need not fit one VBlank.

kitaqgb/lib/wire3d_dmg.c:3081

c
void Wire3DDMG_EndFrame()
{
    w3ddmg_wait_vblank_start();
    w3ddmg_flush_bg_queue();



    if (w3ddmg_aux_transfer_enabled)
    {
        w3ddmg_transfer_stage_aux_asm();
    }
    if (w3ddmg_dirty_transfer_enabled)
    {
        w3ddmg_transfer_dirty_stage();
    }
    else
    {
        w3ddmg_transfer_stage_asm();
    }

}
DMG3D_EraseModelFaces

Projette les triangles avant du modèle et efface les pixels préparés à l’intérieur.

Syntaxe

c
void DMG3D_EraseModelFaces(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz, w3ddmg_i16 scale_q8);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

scale_q8

Échelle dont l’unité vaut 256 ; les valeurs nulles ou négatives signifient aussi l’unité.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Projette au plus 24 sommets et efface l’intérieur des triangles avant dans la zone de préparation, pour un modèle doté d’indicateurs de lignes cachées et de données de faces. Une échelle non positive signifie 256, soit l’unité. Examine au plus 16 faces ; celles traversant une limite de profondeur sont ignorées. Remplace aussi les caches de projection partagés, sans mettre à jour la VRAM.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Erase a screen triangle and a projected model face from separate filled panels.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom DMG3D_Vec3 vertices[4]={{-24,-24,0},{24,-24,0},{24,24,0},{-24,24,0}};
__prg_rom DMG3D_Edge edges[4]={{0,1},{1,2},{2,3},{3,0}};
__prg_rom DMG3D_Face faces[2]={{0,2,1},{0,3,2}};
DMG3D_Model plane;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        plane.vertices=vertices;plane.edges=edges;plane.faces=faces;plane.edge_faces=0;
    plane.vertex_count=4;plane.edge_count=4;plane.face_count=2;plane.flags=1;
    DMG3D_BeginFrame();
    // Separate panels show a direct screen triangle and a projected square face.
    for(i=8;i<=32;i++) DMG3D_DrawLine2D(8,i,32,i);
    for(i=36;i<=84;i++) DMG3D_DrawLine2D(40,i,88,i);
    DMG3D_EraseTriangle2D(12,12,28,12,12,28);
    DMG3D_EraseModelFaces(&plane,0,0,64,0,0,0,256);

    DMG3D_EndFrame(); result[7]=0xA55A; while(1) {}
}

Résultat attendu

Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.

DMG3D_EraseModelFaces: DMG — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.
DMG — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.
DMG3D_EraseModelFaces: CGB — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.
CGB — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_faces.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_faces.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:29

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Project up to 24 vertices and erase front-facing triangle interiors from
the stage for a model with hidden-line flags and face data. Nonpositive scale
means 256 (unity). Up to 16 faces are considered; depth-crossing faces are
skipped. This also replaces shared projection caches, but does not update VRAM.

kitaqgb/lib/wire3d_dmg.c:2843

c
void Wire3DDMG_EraseModelFaces(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz, w3ddmg_i16 scale_q8)

{
    w3ddmg_u8 i;
    w3ddmg_u8 count;
    w3ddmg_u8 face_count;

    if (model == 0) return;
    if (model->vertices == 0) return;
    if (model->faces == 0) return;
    if ((model->flags & WIRE3D_DMG_MODEL_HIDDEN_LINES) == 0) return;
    if (scale_q8 <= 0) scale_q8 = 256;

    count = model->vertex_count;
    if (count > WIRE3D_DMG_MODEL_VERTEX_LIMIT) count = WIRE3D_DMG_MODEL_VERTEX_LIMIT;

    i = 0;
    while (i < count)
    {
        const Wire3DDMG_Vec3* v;
        w3ddmg_i16 vx;
        w3ddmg_i16 vy;
        w3ddmg_i16 vz;
        w3ddmg_u8 sx;
        w3ddmg_u8 sy;

        v = &model->vertices[(__safe_index w3ddmg_u8)i];
        vx = (w3ddmg_i16)((v->x * scale_q8) >> 8);
        vy = (w3ddmg_i16)((v->y * scale_q8) >> 8);
        vz = (w3ddmg_i16)((v->z * scale_q8) >> 8);






        w3ddmg_rotate_y(&vx, &vz, ry);
        w3ddmg_rotate_x(&vy, &vz, rx);
        w3ddmg_rotate_z(&vx, &vy, rz);


        vx = (w3ddmg_i16)(vx + x);
        vy = (w3ddmg_i16)(vy + y);
        vz = (w3ddmg_i16)(vz + z);

        if (w3ddmg_project_world(vx, vy, vz, &sx, &sy))
        {
            w3ddmg_screen_x[(__safe_index w3ddmg_u8)i] = sx;
            w3ddmg_screen_y[(__safe_index w3ddmg_u8)i] = sy;
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 1;
        }
        else
        {
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 0;
        }
        i = (w3ddmg_u8)(i + 1);
    }

    face_count = model->face_count;
    if (face_count > WIRE3D_DMG_MODEL_FACE_LIMIT) face_count = WIRE3D_DMG_MODEL_FACE_LIMIT;
    w3ddmg_build_face_visibility(model, count, face_count);

    i = 0;
    while (i < face_count)
    {
        const Wire3DDMG_Face* f;
        f = &model->faces[(__safe_index w3ddmg_u8)i];
        if (w3ddmg_face_visible[(__safe_index w3ddmg_u8)i] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)f->a] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)f->b] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)f->c])
        {
            w3ddmg_clear_triangle(
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)f->a],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)f->a],
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)f->b],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)f->b],
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)f->c],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)f->c]);
        }
        i = (w3ddmg_u8)(i + 1);
    }
}
DMG3D_EraseSpan2D

Efface un segment horizontal, bornes incluses, sur une ligne préparée.

Syntaxe

c
void DMG3D_EraseSpan2D(w3ddmg_u8 y, w3ddmg_u8 x0, w3ddmg_u8 x1);

Paramètres

y

Coordonnée Y en pixels de la ligne à effacer.

x0

Borne X inférieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

x1

Borne X supérieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Ordonne les extrémités X et efface le segment préparé, bornes incluses. Les deux extrémités doivent être dans 0..127 ; un Y invalide est ignoré. La routine ne découpe pas X à votre place.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    DMG3D_SetCamera(8,0,0,0,0,0);
    result[1]=DMG3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=DMG3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    DMG3D_SetCamera(0,0,0,0,0,0);
    DMG3D_BeginFrame();
    DMG3D_DrawLine2D(8,8,56,8);
    DMG3D_DrawLine2D(56,8,56,40);
    DMG3D_DrawLine2D(56,40,8,40);
    DMG3D_DrawLine2D(8,40,8,8);
    DMG3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    DMG3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    DMG3D_PutBgTile(1,1,160);
    DMG3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

DMG3D_EraseSpan2D: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG3D_EraseSpan2D: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_raster.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:30

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Order the X endpoints and erase the inclusive staged span. Both endpoints
must be in 0..127; invalid Y is ignored. The routine does not clip X for you.

kitaqgb/lib/wire3d_dmg.c:2943

c
void Wire3DDMG_EraseSpan2D(w3ddmg_u8 y, w3ddmg_u8 x0, w3ddmg_u8 x1)
{
    w3ddmg_u8 tx;

    if (x0 > x1)
    {
        tx = x0;
        x0 = x1;
        x1 = tx;
    }
    w3ddmg_stage_clear_span(y, x0, x1);
}
DMG3D_EraseTriangle2D

Efface un triangle en coordonnées écran dans la zone de préparation, par segments horizontaux de lignes de balayage.

Syntaxe

c
void DMG3D_EraseTriangle2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by, w3ddmg_u8 cx, w3ddmg_u8 cy);

Paramètres

ax

Coordonnée X du sommet A en pixels du viewport.

ay

Coordonnée Y du sommet A en pixels du viewport.

bx

Coordonnée X du sommet B en pixels du viewport.

by

Coordonnée Y du sommet B en pixels du viewport.

cx

Coordonnée X du sommet C en pixels du viewport.

cy

Coordonnée Y du sommet C en pixels du viewport.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Efface un triangle dans les pixels préparés à l’aide d’intersections entières avec les lignes de balayage. Fournissez des coordonnées du viewport. Les triangles dégénérés sont ignorés ; masque d’occlusion et VRAM restent inchangés.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Erase a screen triangle and a projected model face from separate filled panels.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom DMG3D_Vec3 vertices[4]={{-24,-24,0},{24,-24,0},{24,24,0},{-24,24,0}};
__prg_rom DMG3D_Edge edges[4]={{0,1},{1,2},{2,3},{3,0}};
__prg_rom DMG3D_Face faces[2]={{0,2,1},{0,3,2}};
DMG3D_Model plane;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        plane.vertices=vertices;plane.edges=edges;plane.faces=faces;plane.edge_faces=0;
    plane.vertex_count=4;plane.edge_count=4;plane.face_count=2;plane.flags=1;
    DMG3D_BeginFrame();
    // Separate panels show a direct screen triangle and a projected square face.
    for(i=8;i<=32;i++) DMG3D_DrawLine2D(8,i,32,i);
    for(i=36;i<=84;i++) DMG3D_DrawLine2D(40,i,88,i);
    DMG3D_EraseTriangle2D(12,12,28,12,12,28);
    DMG3D_EraseModelFaces(&plane,0,0,64,0,0,0,256);

    DMG3D_EndFrame(); result[7]=0xA55A; while(1) {}
}

Résultat attendu

Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.

DMG3D_EraseTriangle2D: DMG — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.
DMG — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.
DMG3D_EraseTriangle2D: CGB — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.
CGB — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_faces.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_faces.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:31

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Erase a triangle from staged pixels using integer scanline intersections.
Supply viewport coordinates. Degenerate triangles are ignored; the occlusion
mask and VRAM are unchanged.

kitaqgb/lib/wire3d_dmg.c:2933

c
void Wire3DDMG_EraseTriangle2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by, w3ddmg_u8 cx, w3ddmg_u8 cy)
{
    w3ddmg_clear_triangle(ax, ay, bx, by, cx, cy);
}
DMG3D_Init

Initialise le LCD, les tuiles et la carte du fond pour un viewport filaire monochrome.

Syntaxe

c
void DMG3D_Init();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Prend le contrôle du LCD, efface la VRAM des tuiles et la carte BG, puis installe un viewport de 16×15 à partir de la tuile (3,1). Règle le défilement à (8,0), BGP à 0xB4 et active le fond. Réinitialise caméra, files, modes de transfert, les deux tables de modifications et la zone de préparation. Réservez 0xD000..0xDFFF et gardez son mappage WRAM ; le stockage auxiliaire partage ces adresses. Appelez BeginFrame avant de dessiner pour établir l’état d’occlusion.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    DMG3D_SetCamera(8,0,0,0,0,0);
    result[1]=DMG3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=DMG3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    DMG3D_SetCamera(0,0,0,0,0,0);
    DMG3D_BeginFrame();
    DMG3D_DrawLine2D(8,8,56,8);
    DMG3D_DrawLine2D(56,8,56,40);
    DMG3D_DrawLine2D(56,40,8,40);
    DMG3D_DrawLine2D(8,40,8,8);
    DMG3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    DMG3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    DMG3D_PutBgTile(1,1,160);
    DMG3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

DMG3D_Init: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG3D_Init: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_raster.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:35

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Take over LCD state, clear tile VRAM and the BG map, and install a 16x15
viewport beginning at map tile (3,1). Set scroll (8,0), BGP=0xB4 and BG display.
Reset camera, queues, transfer modes, both dirty tables and stage. Reserve
0xD000..0xDFFF and retain its WRAM mapping; auxiliary storage aliases it.
Call BeginFrame before drawing to establish occlusion state.

kitaqgb/lib/wire3d_dmg.c:2572

c
void Wire3DDMG_Init()
{
    w3ddmg_u8 row;
    w3ddmg_u8 col;
    w3ddmg_u8 tid;
    w3ddmg_u16 off;

    w3ddmg_wait_vblank_start();
    w3ddmg_reg_lcdc = 0;

    w3ddmg_clear_vram_asm();



    w3ddmg_fill_bg_map_asm();

    row = 0;
    tid = 0x90;
    while (row < WIRE3D_DMG_TILE_H)
    {



        off = (w3ddmg_u16)(0x23 + ((w3ddmg_u16)row << 5));

        col = 0;
        while (col < WIRE3D_DMG_TILE_W)
        {
            w3ddmg_bg_map_9800[(w3ddmg_u16)(off + (w3ddmg_u16)col)] = tid;
            tid = (w3ddmg_u8)(tid + WIRE3D_DMG_TILE_H);
            col = (w3ddmg_u8)(col + 1);
        }
        row = (w3ddmg_u8)(row + 1);
        tid = (w3ddmg_u8)(0x90 + row);
    }




    w3ddmg_reg_scx = 8;

    w3ddmg_reg_scy = 0;
    w3ddmg_reg_bgp = 0xB4;
    w3ddmg_reg_lcdc = 0x81;
    w3ddmg_bgq_count = 0;

    w3ddmg_aux_transfer_enabled = 0;
    w3ddmg_dirty_transfer_enabled = 0;


    Wire3DDMG_SetCamera(0, 0, 0, 0, 0, 0);
    w3ddmg_clear_stage_asm();

    w3ddmg_clear_stage_aux_asm();
    w3ddmg_clear_dirty_tables();

}
DMG3D_ProjectPoint

Projette un point du monde par la caméra vers les coordonnées du viewport.

Syntaxe

c
w3ddmg_u8 DMG3D_ProjectPoint(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8* sx, w3ddmg_u8* sy);

Paramètres

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

sx

Pointeur u8 valide et accessible en écriture recevant la coordonnée X projetée.

sy

Pointeur u8 valide et accessible en écriture recevant la coordonnée Y projetée.

Valeur renvoyée

Renvoie 1 si la projection réussit, 0 si la profondeur est rejetée.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Projette un point du monde avec la caméra courante. Une profondeur invalide renvoie zéro sans changer les sorties ; le succès écrit des coordonnées bornées à 128×120. Les deux pointeurs de sortie doivent être valides. Les différences de coordonnées doivent tenir dans s16.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    DMG3D_SetCamera(8,0,0,0,0,0);
    result[1]=DMG3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=DMG3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    DMG3D_SetCamera(0,0,0,0,0,0);
    DMG3D_BeginFrame();
    DMG3D_DrawLine2D(8,8,56,8);
    DMG3D_DrawLine2D(56,8,56,40);
    DMG3D_DrawLine2D(56,40,8,40);
    DMG3D_DrawLine2D(8,40,8,8);
    DMG3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    DMG3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    DMG3D_PutBgTile(1,1,160);
    DMG3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

DMG3D_ProjectPoint: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG3D_ProjectPoint: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_raster.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:43

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Project a world point with the current camera. Return zero for invalid
depth without changing outputs; success writes clamped 128x120 coordinates.
Both output pointers must be valid. Coordinate differences must fit s16.

kitaqgb/lib/wire3d_dmg.c:549

c
w3ddmg_u8 Wire3DDMG_ProjectPoint(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8* sx, w3ddmg_u8* sy)
{
    return w3ddmg_project_world(x, y, z, sx, sy);
}
DMG3D_PutBgTile

Met en file une écriture de numéro de tuile dans une case de la carte du fond.

Syntaxe

c
void DMG3D_PutBgTile(w3ddmg_u8 x, w3ddmg_u8 y, w3ddmg_u8 tile);

Paramètres

x

Coordonnée X en tuiles dans la carte de fond de 32×32.

y

Coordonnée Y en tuiles dans la carte de fond de 32×32.

tile

Numéro de tuile sur huit bits pour la case du fond.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Met en file une écriture de tuile dans la carte 32×32 en 0x9800 pour EndFrame. Les coordonnées invalides et les soumissions au-delà de 48 écritures en attente sont ignorées sans signalement. Cette file est distincte de celle de la bibliothèque vram générale.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    DMG3D_SetCamera(8,0,0,0,0,0);
    result[1]=DMG3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=DMG3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    DMG3D_SetCamera(0,0,0,0,0,0);
    DMG3D_BeginFrame();
    DMG3D_DrawLine2D(8,8,56,8);
    DMG3D_DrawLine2D(56,8,56,40);
    DMG3D_DrawLine2D(56,40,8,40);
    DMG3D_DrawLine2D(8,40,8,8);
    DMG3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    DMG3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    DMG3D_PutBgTile(1,1,160);
    DMG3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

DMG3D_PutBgTile: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG3D_PutBgTile: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_raster.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:44

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Queue a tile write to the 32x32 map at 0x9800 for EndFrame. Invalid map
coordinates and submissions beyond 48 pending writes are silently ignored.
This queue is separate from the general vram library queue.

kitaqgb/lib/wire3d_dmg.c:582

c
void Wire3DDMG_PutBgTile(w3ddmg_u8 x, w3ddmg_u8 y, w3ddmg_u8 tile)
{
    if (x >= 32) return;
    if (y >= 32) return;
    if (w3ddmg_bgq_count >= WIRE3D_DMG_BG_QUEUE_LIMIT) return;
    w3ddmg_bgq_x[(__safe_index w3ddmg_u8)w3ddmg_bgq_count] = x;
    w3ddmg_bgq_y[(__safe_index w3ddmg_u8)w3ddmg_bgq_count] = y;
    w3ddmg_bgq_tile[(__safe_index w3ddmg_u8)w3ddmg_bgq_count] = tile;
    w3ddmg_bgq_count = (w3ddmg_u8)(w3ddmg_bgq_count + 1);
}
DMG3D_RotatePoint

Fait tourner un point sur place selon les angles fournis.

Syntaxe

c
void DMG3D_RotatePoint(w3ddmg_i16* x, w3ddmg_i16* y, w3ddmg_i16* z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz);

Paramètres

x

Pointeur s16 distinct et accessible en écriture pour la composante X.

y

Pointeur s16 distinct et accessible en écriture pour la composante Y.

z

Pointeur s16 distinct et accessible en écriture pour la composante Z.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Tourne sur place dans l’ordre Y/X/Z, avec 16 pas par tour. Un pointeur de composante null rend tout l’appel sans effet ; utilisez des pointeurs distincts. Chaque rotation d’axe borne ses entrées à ±220.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Compare direct model scaling with an object-array scene.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom DMG3D_Vec3 vertices[8]={{-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},{-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}};
__prg_rom DMG3D_Edge edges[12]={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
DMG3D_Model cube;
DMG3D_Object objects[2];
s16 px; s16 py; s16 pz;
void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;

    cube.vertices=vertices;cube.edges=edges;cube.faces=0;cube.edge_faces=0;
    cube.vertex_count=8;cube.edge_count=12;cube.face_count=0;cube.flags=0;

    DMG3D_BeginFrame();
    // Upper pair: direct model calls at unity and half scale.
    DMG3D_DrawModel(&cube,-32,32,96,0,0,0);
    DMG3D_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    // Lower pair: the caller owns both object records and the model tables.
    for(i=0;i<2;i++) {
        objects[i].model=&cube;objects[i].x=-32+(s16)i*64;
        objects[i].y=-32;objects[i].z=96;
        objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256-(s16)i*128;objects[i].visible=1;
    }
    DMG3D_DrawScene(objects,2);
    // Numeric checks cover the operation supplied by this viewport profile.
    px=16;py=0;pz=0;DMG3D_RotatePoint(&px,&py,&pz,0,4,0);
    result[1]=px; result[2]=py; result[3]=pz;
    DMG3D_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

DMG3D_RotatePoint: DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
DMG3D_RotatePoint: CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_models.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:46

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Rotate in place in Y/X/Z order using 16 steps per full turn. A null
component pointer makes the whole call a no-op; use distinct pointers.
Each axis rotation clamps its inputs to +/-220.

kitaqgb/lib/wire3d_dmg.c:3121

c
void Wire3DDMG_RotatePoint(w3ddmg_i16* x, w3ddmg_i16* y, w3ddmg_i16* z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz)
{
    if (x == 0) return;
    if (y == 0) return;
    if (z == 0) return;

    w3ddmg_rotate_y(x, z, ry);
    w3ddmg_rotate_x(y, z, rx);
    w3ddmg_rotate_z(x, y, rz);
}
DMG3D_SetAuxTransfer

Choisit si EndFrame transfère aussi les bandes auxiliaires.

Syntaxe

c
void DMG3D_SetAuxTransfer(w3ddmg_u8 flag);

Paramètres

flag

Zéro désactive la fonction de transfert ; toute autre valeur l’active.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Mémorise l’autorisation de transfert auxiliaire d’EndFrame ; toute valeur non nulle l’active. Aucune donnée n’est copiée ou effacée ici. Les octets source auxiliaires partagent les adresses de la zone principale.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Use the auxiliary-transfer gate to consume an overlapping stage strip.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        DMG3D_SetDirtyTransfer(1); DMG3D_SetAuxTransfer(1);
    DMG3D_BeginFrame();
    for(i=24;i<=31;i++) DMG3D_DrawLine2D(40,i,47,i);
    // Auxiliary upload consumes this source before the dirty main tile is sent.

    DMG3D_EndFrame(); result[7]=0xA55A; while(1) {}
}

Résultat attendu

Une partie de la zone principale est consommée par le transfert auxiliaire, ce qui produit un bloc noir de 8×8 à l’écran en (80,24).

DMG3D_SetAuxTransfer: DMG — Une partie de la zone principale est consommée par le transfert auxiliaire, ce qui produit un bloc noir de 8×8 à l’écran en (80,24).
DMG — Une partie de la zone principale est consommée par le transfert auxiliaire, ce qui produit un bloc noir de 8×8 à l’écran en (80,24).
DMG3D_SetAuxTransfer: CGB — Une partie de la zone principale est consommée par le transfert auxiliaire, ce qui produit un bloc noir de 8×8 à l’écran en (80,24).
CGB — Une partie de la zone principale est consommée par le transfert auxiliaire, ce qui produit un bloc noir de 8×8 à l’écran en (80,24).

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_aux_gate.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_aux_gate.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:50

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Store the EndFrame auxiliary-transfer gate; any nonzero value enables it.
No data is copied or cleared here. Auxiliary source bytes alias the main stage.

kitaqgb/lib/wire3d_dmg.c:3895

c
void Wire3DDMG_SetAuxTransfer(w3ddmg_u8 flag)
{
    w3ddmg_aux_transfer_enabled = flag;
}
DMG3D_SetCamera

Mémorise la position et l’orientation de la caméra pour les projections suivantes.

Syntaxe

c
void DMG3D_SetCamera(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 pitch, w3ddmg_u8 yaw, w3ddmg_u8 roll);

Paramètres

x

Composante X de la caméra en coordonnées du monde.

y

Composante Y de la caméra en coordonnées du monde.

z

Composante Z de la caméra en coordonnées du monde.

pitch

Rotation autour de X ; seize pas font un tour complet.

yaw

Rotation autour de Y ; seize pas font un tour complet.

roll

Rotation autour de Z ; seize pas font un tour complet.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Mémorise la position et les angles de caméra pour les dessins suivants ; un tour compte 16 pas angulaires. Ne reprojette pas les dessins existants et ne valide pas les plages d’entrée.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    DMG3D_SetCamera(8,0,0,0,0,0);
    result[1]=DMG3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=DMG3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    DMG3D_SetCamera(0,0,0,0,0,0);
    DMG3D_BeginFrame();
    DMG3D_DrawLine2D(8,8,56,8);
    DMG3D_DrawLine2D(56,8,56,40);
    DMG3D_DrawLine2D(56,40,8,40);
    DMG3D_DrawLine2D(8,40,8,8);
    DMG3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    DMG3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    DMG3D_PutBgTile(1,1,160);
    DMG3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

DMG3D_SetCamera: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG3D_SetCamera: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_raster.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:51

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Store camera position and angles for later draws; a full turn is 16 angle
steps. No existing drawing is reprojected and no input range validation occurs.

kitaqgb/lib/wire3d_dmg.c:2661

c
void Wire3DDMG_SetCamera(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 pitch, w3ddmg_u8 yaw, w3ddmg_u8 roll)

{
    w3ddmg_cam_x = x;
    w3ddmg_cam_y = y;
    w3ddmg_cam_z = z;
    w3ddmg_cam_pitch = pitch;
    w3ddmg_cam_yaw = yaw;
    w3ddmg_cam_roll = roll;
}
DMG3D_SetDirtyTransfer

Sélectionne le transfert des tuiles modifiées pour le viewport principal de 120 lignes.

Syntaxe

c
void DMG3D_SetDirtyTransfer(w3ddmg_u8 flag);

Paramètres

flag

Zéro désactive la fonction de transfert ; toute autre valeur l’active.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Mémorise l’autorisation de transfert des zones modifiées et efface les deux historiques de modifications ainsi que la zone principale, même si la valeur ne change pas. La VRAM est conservée ; l’activer sur une ancienne image peut laisser d’anciennes tuiles non marquées. Préparez donc un affichage de départ propre.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Remove the previous frame and upload only the tracked current/previous tiles.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        DMG3D_SetDirtyTransfer(1); DMG3D_SetAuxTransfer(0);
    DMG3D_BeginFrame();
    DMG3D_DrawLine2D(8,8,24,8); DMG3D_DrawLine2D(24,8,24,24);
    DMG3D_DrawLine2D(24,24,8,24); DMG3D_DrawLine2D(8,24,8,8);
    DMG3D_EndFrame();
    DMG3D_BeginFrame();
    DMG3D_DrawLine2D(80,80,104,80); DMG3D_DrawLine2D(104,80,104,104);
    DMG3D_DrawLine2D(104,104,80,104); DMG3D_DrawLine2D(80,104,80,80);

    DMG3D_EndFrame(); result[7]=0xA55A; while(1) {}
}

Résultat attendu

L’ancien cadre en haut à gauche disparaît ; seul reste le nouveau cadre aux coordonnées écran (96,88)..(120,112).

DMG3D_SetDirtyTransfer: DMG — L’ancien cadre en haut à gauche disparaît ; seul reste le nouveau cadre aux coordonnées écran (96,88)..(120,112).
DMG — L’ancien cadre en haut à gauche disparaît ; seul reste le nouveau cadre aux coordonnées écran (96,88)..(120,112).
DMG3D_SetDirtyTransfer: CGB — L’ancien cadre en haut à gauche disparaît ; seul reste le nouveau cadre aux coordonnées écran (96,88)..(120,112).
CGB — L’ancien cadre en haut à gauche disparaît ; seul reste le nouveau cadre aux coordonnées écran (96,88)..(120,112).

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_dirty.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_dirty.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:52

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Store the dirty-transfer gate and clear both dirty histories and the main
stage, even if the value is unchanged. VRAM is retained; enabling this over an
old image can leave unmarked old tiles, so arrange a clean displayed baseline.

kitaqgb/lib/wire3d_dmg.c:3955

c
void Wire3DDMG_SetDirtyTransfer(w3ddmg_u8 flag)
{
    w3ddmg_dirty_transfer_enabled = flag;
    w3ddmg_clear_dirty_tables();
    w3ddmg_clear_stage_asm();
}
DMG3D_SetPalette

Écrit la correspondance des quatre nuances dans le registre de palette du fond monochrome BGP.

Syntaxe

c
void DMG3D_SetPalette(w3ddmg_u8 bgp);

Paramètres

bgp

Valeur du registre BGP contenant quatre affectations de nuance sur deux bits.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Écrit immédiatement l’encodage brut de la palette DMG BGP, sans synchronisation d’image.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    DMG3D_SetCamera(8,0,0,0,0,0);
    result[1]=DMG3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=DMG3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    DMG3D_SetCamera(0,0,0,0,0,0);
    DMG3D_BeginFrame();
    DMG3D_DrawLine2D(8,8,56,8);
    DMG3D_DrawLine2D(56,8,56,40);
    DMG3D_DrawLine2D(56,40,8,40);
    DMG3D_DrawLine2D(8,40,8,8);
    DMG3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    DMG3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    DMG3D_PutBgTile(1,1,160);
    DMG3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

DMG3D_SetPalette: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG3D_SetPalette: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_raster.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:53

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Write the raw DMG BGP palette encoding immediately; no frame synchronization occurs.

kitaqgb/lib/wire3d_dmg.c:597

c
void Wire3DDMG_SetPalette(w3ddmg_u8 bgp)
{
    w3ddmg_reg_bgp = bgp;
}
DMG3D_TransferAuxNow

Transfère immédiatement six bandes auxiliaires et efface leurs octets source.

Syntaxe

c
void DMG3D_TransferAuxNow();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Transfère et consomme immédiatement les bandes source auxiliaires, indépendamment de leur autorisation. N’attend pas le début du VBlank et ne met à jour ni historique de modifications ni file BG. La source recouvre la zone principale ; coordonnez les deux transferts.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Upload a main line and an auxiliary block separately; verify source consumption.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom DMG3D_Vec3 vertices[2]={{-32,0,0},{32,0,0}};
__prg_rom u8 edge_pairs[2]={0,1};
u8* stage_byte;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        DMG3D_BeginFrame();
    DMG3D_DrawIndexedEdges(vertices,2,edge_pairs,1,-64,104,96,1);
    DMG3D_TransferMainNow();
    // Direct auxiliary transfer writes a separate tile after the main upload.
    for(i=24;i<=31;i++) DMG3D_DrawLine2D(40,i,47,i);
    stage_byte=(u8*)0xD518;result[1]=*stage_byte;
    DMG3D_TransferAuxNow();result[2]=*stage_byte;

    // Do not upload the consumed stage again.
    result[7]=0xA55A; while(1) {}
}

Résultat attendu

Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.

DMG3D_TransferAuxNow: DMG — Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.
DMG — Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.
DMG3D_TransferAuxNow: CGB — Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.
CGB — Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_direct.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_direct.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:57

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Upload and consume auxiliary source strips immediately, independent of the
auxiliary gate. No VBlank-start wait or dirty-history/BG-queue update occurs.
The source overlaps the main stage and must be coordinated with its upload.

kitaqgb/lib/wire3d_dmg.c:3983

c
void Wire3DDMG_TransferAuxNow()
{
    w3ddmg_transfer_stage_aux_asm();
}
DMG3D_TransferMainNow

Transfère immédiatement toute la zone principale et efface les pixels source consommés.

Syntaxe

c
void DMG3D_TransferMainNow();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120. Transfère et consomme immédiatement toute la zone principale en interrogeant STAT, sans attendre le prochain VBlank. Ignore les autorisations de transfert et conserve les historiques de modifications et la file de tuiles BG ; l’appelant coordonne le cycle de l’image.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Upload a main line and an auxiliary block separately; verify source consumption.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "dmg3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom DMG3D_Vec3 vertices[2]={{-32,0,0},{32,0,0}};
__prg_rom u8 edge_pairs[2]={0,1};
u8* stage_byte;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    DMG3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    DMG3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        DMG3D_BeginFrame();
    DMG3D_DrawIndexedEdges(vertices,2,edge_pairs,1,-64,104,96,1);
    DMG3D_TransferMainNow();
    // Direct auxiliary transfer writes a separate tile after the main upload.
    for(i=24;i<=31;i++) DMG3D_DrawLine2D(40,i,47,i);
    stage_byte=(u8*)0xD518;result[1]=*stage_byte;
    DMG3D_TransferAuxNow();result[2]=*stage_byte;

    // Do not upload the consumed stage again.
    result[7]=0xA55A; while(1) {}
}

Résultat attendu

Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.

DMG3D_TransferMainNow: DMG — Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.
DMG — Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.
DMG3D_TransferMainNow: CGB — Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.
CGB — Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg3d_direct.c .\kitaqgb\lib\dmg3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg3d_direct.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/dmg3d.h:58

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 120.
Upload and consume the full main stage immediately, polling STAT but not
waiting for the next VBlank. Ignore transfer gates and leave dirty histories
and BG tile queue unchanged; the caller coordinates the frame lifecycle.

kitaqgb/lib/wire3d_dmg.c:3970

c
void Wire3DDMG_TransferMainNow()
{
    w3ddmg_transfer_stage_asm();
}

entity.h — Réserves d'objets fondées sur des tableaux fixes

entity est un pool d’objets sur tableau fixe destiné aux états des ennemis, projectiles, objets à ramasser, etc. Vous allouez un emplacement libre, y accédez par son identifiant, puis le réutilisez lorsque l’objet n’est plus nécessaire. Il n’y a aucune allocation sur le tas. Le jeu définit les unités de position et de vitesse, les déplacements, les collisions et la mise à jour des compteurs de temps.

Incluez entity.h et compilez entity.c exactement une fois. Appelez d’abord entity_init et vérifiez que entity_create ne renvoie pas 0xFF. ENTITY_MAX vaut 16 par défaut. Les identifiants permettent une capacité de 1 à 255 emplacements, mais la capacité réellement utilisable dépend de la RAM disponible. Utilisez la même définition de capacité dans toutes les unités de compilation.

Le pointeur renvoyé par entity_get désigne un emplacement réutilisable du pool. Après libération, le même identifiant peut désigner un autre objet : ni l’identifiant ni le pointeur ne constituent donc une identité permanente. entity_destroy se contente de désactiver l’emplacement. Il revient à l’appelant de masquer ou de libérer les sprites et de nettoyer les autres ressources. Le champ sprite sert au suivi interne ; il ne met pas automatiquement l’OAM à jour.

entity_update_all et entity_draw_all parcourent les emplacements actifs par identifiant croissant et appellent fn(id). Placez le travail de mise à jour ou de dessin dans la fonction de rappel. Un rappel nul ne fait rien. Créer ou libérer un emplacement situé plus loin dans l’ordre de parcours modifie le parcours en cours. Effectuer les mises à jour avant le dessin permet de séparer ces deux responsabilités.

entity_clear_all

Libère toutes les entités et réinitialise leurs champs, y compris le marqueur d’absence de sprite.

Syntaxe

c
void entity_clear_all();

Valeur renvoyée

Aucune (void).

Conditions et limites

Le pool est un tableau fixe, sans allocation sur le tas. ENTITY_MAX vaut 16 par défaut et doit être compris entre 1 et 255, avec la même définition dans chaque unité de compilation. Les ID commencent à zéro ; 0xFF indique un échec.

Met à zéro active,type,x,y,vx,vy,state,timer et place sprite à 0xFF dans chaque emplacement. Ne masque ni ne libère les sprites matériels ; gérez séparément ces ressources.

Exemple d’utilisation

c
entity_clear_all();
after_clear = entity_count_active();
if (after_clear != 0 || entity_get(reused) != 0) { failures++; }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet illustre le cycle de vie d’un emplacement réutilisable. Lisez les nombres avec leurs libellés : CREATED 002 après deux allocations ; AFTER FREE 001 après libération de la première ; REUSED ID 000 quand le plus petit ID libre est réutilisé ; AFTER CLEAR 000 après vidage du pool. Il vérifie aussi la recherche null après libération et la remise à zéro après réallocation. FAILED CHECKS 000 indique que les valeurs concordent.

Le parcours GB appelle chaque rappel pour les deux entités actives : UPDATE CALLS 002 et DRAW CALLS 002. Le rappel de mise à jour déplace les deux objets d’une tuile vers la droite. Celui de dessin place A en (3,12) et B en (7,12) pour les représenter. Ce sont des tuiles de police du fond dessinées par le rappel, pas des sprites alloués automatiquement.

entity_clear_all: DMG
DMG
entity_clear_all: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\entity.c .\kitaq-docs\samples\api-examples\gb\entity_pool.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\entity_pool.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm
Implémentation et source

kitaqgb/lib/entity.h:43

Notes de déclaration (texte source)
Release every entity and restore deterministic defaults, including the no-sprite sentinel.

kitaqgb/lib/entity.c:14

c
void entity_clear_all()
{
    u8 i = 0;
    while (i < ENTITY_MAX) {
        entity_pool[i].active = 0;
        entity_pool[i].type = 0;
        entity_pool[i].x = 0;
        entity_pool[i].y = 0;
        entity_pool[i].vx = 0;
        entity_pool[i].vy = 0;
        entity_pool[i].state = 0;
        entity_pool[i].timer = 0;
        entity_pool[i].sprite = 0xFF;
        i++;
    }
}
entity_count_active

Compte les emplacements d’entités occupés sans les modifier.

Syntaxe

c
u8 entity_count_active();

Valeur renvoyée

Nombre d’emplacements dont active est non nul, de 0 à ENTITY_MAX. C’est l’occupation, pas le plus grand ID ni le nombre de sprites à l’écran.

Conditions et limites

Le pool est un tableau fixe, sans allocation sur le tas. ENTITY_MAX vaut 16 par défaut et doit être compris entre 1 et 255, avec la même définition dans chaque unité de compilation. Les ID commencent à zéro ; 0xFF indique un échec.

Exemple d’utilisation

c
created = entity_count_active();
if (created != 2) { failures++; }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet illustre le cycle de vie d’un emplacement réutilisable. Lisez les nombres avec leurs libellés : CREATED 002 après deux allocations ; AFTER FREE 001 après libération de la première ; REUSED ID 000 quand le plus petit ID libre est réutilisé ; AFTER CLEAR 000 après vidage du pool. Il vérifie aussi la recherche null après libération et la remise à zéro après réallocation. FAILED CHECKS 000 indique que les valeurs concordent.

Le parcours GB appelle chaque rappel pour les deux entités actives : UPDATE CALLS 002 et DRAW CALLS 002. Le rappel de mise à jour déplace les deux objets d’une tuile vers la droite. Celui de dessin place A en (3,12) et B en (7,12) pour les représenter. Ce sont des tuiles de police du fond dessinées par le rappel, pas des sprites alloués automatiquement.

entity_count_active: DMG
DMG
entity_count_active: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\entity.c .\kitaq-docs\samples\api-examples\gb\entity_pool.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\entity_pool.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm
Implémentation et source

kitaqgb/lib/entity.h:41

Notes de déclaration (texte source)
Count occupied slots without changing entity state.

kitaqgb/lib/entity.c:93

c
u8 entity_count_active()
{
    u8 i = 0;
    u8 count = 0;
    while (i < ENTITY_MAX) {
        if (entity_pool[i].active != 0) count++;
        i++;
    }
    return count;
}
entity_create

Alloue une entité du type et à la position indiqués ; renvoie son ID réutilisable ou 0xFF si le pool est plein.

Syntaxe

c
u8 entity_create(u8 type, s16 x, s16 y);

Paramètres

type

Étiquette de type définie par le jeu, de 0 à 255. Le pool la conserve sans sélectionner de comportement ni de routine de dessin.

x, y

Coordonnées signées sur 16 bits (-32768–32767). Le jeu choisit l’unité, par exemple pixels ou Q8.8 ; le pool ne convertit pas les unités, ne borne pas les positions et n’applique pas automatiquement les vitesses.

Valeur renvoyée

L’ID du premier emplacement libre (0–ENTITY_MAX-1), ou 0xFF si aucun n’est libre. L’allocation fixe active=1, conserve type et position, efface vitesse/état/temporisateur et place sprite=0xFF.

Conditions et limites

Le pool est un tableau fixe, sans allocation sur le tas. ENTITY_MAX vaut 16 par défaut et doit être compris entre 1 et 255, avec la même définition dans chaque unité de compilation. Les ID commencent à zéro ; 0xFF indique un échec.

Exemple d’utilisation

c
first = entity_create(1, 2, 12);
second = entity_create(2, 6, 12);
if (first == 0xFF || second == 0xFF) { failures++; }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet illustre le cycle de vie d’un emplacement réutilisable. Lisez les nombres avec leurs libellés : CREATED 002 après deux allocations ; AFTER FREE 001 après libération de la première ; REUSED ID 000 quand le plus petit ID libre est réutilisé ; AFTER CLEAR 000 après vidage du pool. Il vérifie aussi la recherche null après libération et la remise à zéro après réallocation. FAILED CHECKS 000 indique que les valeurs concordent.

Le parcours GB appelle chaque rappel pour les deux entités actives : UPDATE CALLS 002 et DRAW CALLS 002. Le rappel de mise à jour déplace les deux objets d’une tuile vers la droite. Celui de dessin place A en (3,12) et B en (7,12) pour les représenter. Ce sont des tuiles de police du fond dessinées par le rappel, pas des sprites alloués automatiquement.

entity_create: DMG
DMG
entity_create: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\entity.c .\kitaq-docs\samples\api-examples\gb\entity_pool.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\entity_pool.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm
Implémentation et source

kitaqgb/lib/entity.h:29

Notes de déclaration (texte source)
Returns a reusable slot ID, or 0xFF if no slot is free.

kitaqgb/lib/entity.c:33

c
u8 entity_create(u8 type, s16 x, s16 y)
{
    u8 i = 0;
    while (i < ENTITY_MAX) {
        if (entity_pool[i].active == 0) {
            entity_pool[i].active = 1;
            entity_pool[i].type = type;
            entity_pool[i].x = x;
            entity_pool[i].y = y;
            entity_pool[i].vx = 0;
            entity_pool[i].vy = 0;
            entity_pool[i].state = 0;
            entity_pool[i].timer = 0;
            entity_pool[i].sprite = 0xFF;
            return i;
        }
        i++;
    }
    return 0xFF;
}
entity_destroy

Libère l’entité id ; ses données restent en place jusqu’à la prochaine allocation.

Syntaxe

c
void entity_destroy(u8 id);

Paramètres

id

Indice d’emplacement réutilisable, de 0 à ENTITY_MAX-1. Au-delà, l’ID est invalide. Sa destruction n’a aucun effet et sa recherche renvoie null.

Valeur renvoyée

Aucune (void).

Conditions et limites

Le pool est un tableau fixe, sans allocation sur le tas. ENTITY_MAX vaut 16 par défaut et doit être compris entre 1 et 255, avec la même définition dans chaque unité de compilation. Les ID commencent à zéro ; 0xFF indique un échec.

La destruction efface seulement active : elle n’efface pas les autres champs et ne libère ni sprite ni ressource. Une allocation ultérieure peut réutiliser le même ID et la même adresse pour une autre entité. Le jeu doit gérer les ressources associées.

Exemple d’utilisation

c
entity_destroy(first);
after_free = entity_count_active();
if (entity_get(first) != 0 || after_free != 1) { failures++; }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet illustre le cycle de vie d’un emplacement réutilisable. Lisez les nombres avec leurs libellés : CREATED 002 après deux allocations ; AFTER FREE 001 après libération de la première ; REUSED ID 000 quand le plus petit ID libre est réutilisé ; AFTER CLEAR 000 après vidage du pool. Il vérifie aussi la recherche null après libération et la remise à zéro après réallocation. FAILED CHECKS 000 indique que les valeurs concordent.

Le parcours GB appelle chaque rappel pour les deux entités actives : UPDATE CALLS 002 et DRAW CALLS 002. Le rappel de mise à jour déplace les deux objets d’une tuile vers la droite. Celui de dessin place A en (3,12) et B en (7,12) pour les représenter. Ce sont des tuiles de police du fond dessinées par le rappel, pas des sprites alloués automatiquement.

entity_destroy: DMG
DMG
entity_destroy: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\entity.c .\kitaq-docs\samples\api-examples\gb\entity_pool.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\entity_pool.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm
Implémentation et source

kitaqgb/lib/entity.h:32

Notes de déclaration (texte source)
Release a valid slot without clearing its payload. Reallocation resets the payload;
a saved pointer or ID must not be treated as a persistent entity identity.

kitaqgb/lib/entity.c:56

c
void entity_destroy(u8 id)
{
    if (id >= ENTITY_MAX) return;
    // Deactivation only releases this pool slot; the caller handles sprite/resource cleanup.
    entity_pool[id].active = 0;
}
entity_draw_all

Parcourt les entités actives et transmet chaque ID au rappel de dessin. Le parcours est celui de entity_update_all ; aucun sprite ni pixel n’est dessiné si le rappel ne soumet pas de données de dessin.

Syntaxe

c
void entity_draw_all(EntityFn fn);

Paramètres

fn

Pointeur de fonction de signature void fn(u8 id). Reçoit un ID ; utilisez entity_get(id) pour accéder aux champs. Null est accepté et n’entraîne aucun appel.

Valeur renvoyée

Aucune (void).

Conditions et limites

Le pool est un tableau fixe, sans allocation sur le tas. ENTITY_MAX vaut 16 par défaut et doit être compris entre 1 et 255, avec la même définition dans chaque unité de compilation. Les ID commencent à zéro ; 0xFF indique un échec.

L’activité est testée au moment d’atteindre l’emplacement. Un rappel peut désactiver un emplacement suivant pour le sauter, ou l’activer pour le visiter dans cette passe. Ce n’est pas un instantané de l’ensemble actif initial.

Exemple d’utilisation

c
void demo_draw(u8 id) {
    Entity* entity;
    entity = entity_get(id);
    if (entity != 0) {
        m_put((u8)entity->x, (u8)entity->y, (u8)('A' + entity->type - 1));
        draw_calls++;
    }
}

// From main(), after creating two entities:
draw_calls = 0;
entity_draw_all(demo_draw);
automatic_draws = draw_calls;
if (automatic_draws != 2) { failures++; }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet illustre le cycle de vie d’un emplacement réutilisable. Lisez les nombres avec leurs libellés : CREATED 002 après deux allocations ; AFTER FREE 001 après libération de la première ; REUSED ID 000 quand le plus petit ID libre est réutilisé ; AFTER CLEAR 000 après vidage du pool. Il vérifie aussi la recherche null après libération et la remise à zéro après réallocation. FAILED CHECKS 000 indique que les valeurs concordent.

Le parcours GB appelle chaque rappel pour les deux entités actives : UPDATE CALLS 002 et DRAW CALLS 002. Le rappel de mise à jour déplace les deux objets d’une tuile vers la droite. Celui de dessin place A en (3,12) et B en (7,12) pour les représenter. Ce sont des tuiles de police du fond dessinées par le rappel, pas des sprites alloués automatiquement.

entity_draw_all: DMG
DMG
entity_draw_all: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\entity.c .\kitaq-docs\samples\api-examples\gb\entity_pool.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\entity_pool.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm
Implémentation et source

kitaqgb/lib/entity.h:39

Notes de déclaration (texte source)
Use the same active-slot traversal for drawing; the callback supplies all rendering.

kitaqgb/lib/entity.c:87

c
void entity_draw_all(EntityFn fn)
{
    entity_update_all(fn);
}
entity_get

Renvoie un pointeur vers l’entité active, ou null pour un ID invalide ou libre. Cet espace peut être réutilisé.

Syntaxe

c
Entity* entity_get(u8 id);

Paramètres

id

Indice d’emplacement réutilisable, de 0 à ENTITY_MAX-1. Au-delà, l’ID est invalide. Sa destruction n’a aucun effet et sa recherche renvoie null.

Valeur renvoyée

Pointeur modifiable vers l’emplacement actif, ou null pour un ID invalide ou libre. La mémoire appartient au pool ; ne la libérez pas et ne traitez pas le pointeur comme une identité permanente après destruction et réallocation.

Conditions et limites

Le pool est un tableau fixe, sans allocation sur le tas. ENTITY_MAX vaut 16 par défaut et doit être compris entre 1 et 255, avec la même définition dans chaque unité de compilation. Les ID commencent à zéro ; 0xFF indique un échec.

La destruction efface seulement active : elle n’efface pas les autres champs et ne libère ni sprite ni ressource. Une allocation ultérieure peut réutiliser le même ID et la même adresse pour une autre entité. Le jeu doit gérer les ressources associées.

Exemple d’utilisation

c
current_entity = entity_get(first);
if (current_entity != 0) { current_entity->vx = 5; }
else { failures++; }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet illustre le cycle de vie d’un emplacement réutilisable. Lisez les nombres avec leurs libellés : CREATED 002 après deux allocations ; AFTER FREE 001 après libération de la première ; REUSED ID 000 quand le plus petit ID libre est réutilisé ; AFTER CLEAR 000 après vidage du pool. Il vérifie aussi la recherche null après libération et la remise à zéro après réallocation. FAILED CHECKS 000 indique que les valeurs concordent.

Le parcours GB appelle chaque rappel pour les deux entités actives : UPDATE CALLS 002 et DRAW CALLS 002. Le rappel de mise à jour déplace les deux objets d’une tuile vers la droite. Celui de dessin place A en (3,12) et B en (7,12) pour les représenter. Ce sont des tuiles de police du fond dessinées par le rappel, pas des sprites alloués automatiquement.

entity_get: DMG
DMG
entity_get: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\entity.c .\kitaq-docs\samples\api-examples\gb\entity_pool.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\entity_pool.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm
Implémentation et source

kitaqgb/lib/entity.h:34

Notes de déclaration (texte source)
Returns null for an invalid or inactive ID; the returned pointer aliases reusable pool storage.

kitaqgb/lib/entity.c:65

c
Entity* entity_get(u8 id)
{
    if (id >= ENTITY_MAX) return 0;
    if (entity_pool[id].active == 0) return 0;
    return &entity_pool[(__safe_index u8)id];
}
entity_init

Initialise tous les emplacements du pool d’entités.

Syntaxe

c
void entity_init();

Valeur renvoyée

Aucune (void).

Conditions et limites

Le pool est un tableau fixe, sans allocation sur le tas. ENTITY_MAX vaut 16 par défaut et doit être compris entre 1 et 255, avec la même définition dans chaque unité de compilation. Les ID commencent à zéro ; 0xFF indique un échec.

Met à zéro active,type,x,y,vx,vy,state,timer et place sprite à 0xFF dans chaque emplacement. Ne masque ni ne libère les sprites matériels ; gérez séparément ces ressources.

Exemple d’utilisation

c
entity_init();
if (entity_count_active() != 0) { failures++; }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet illustre le cycle de vie d’un emplacement réutilisable. Lisez les nombres avec leurs libellés : CREATED 002 après deux allocations ; AFTER FREE 001 après libération de la première ; REUSED ID 000 quand le plus petit ID libre est réutilisé ; AFTER CLEAR 000 après vidage du pool. Il vérifie aussi la recherche null après libération et la remise à zéro après réallocation. FAILED CHECKS 000 indique que les valeurs concordent.

Le parcours GB appelle chaque rappel pour les deux entités actives : UPDATE CALLS 002 et DRAW CALLS 002. Le rappel de mise à jour déplace les deux objets d’une tuile vers la droite. Celui de dessin place A en (3,12) et B en (7,12) pour les représenter. Ce sont des tuiles de police du fond dessinées par le rappel, pas des sprites alloués automatiquement.

entity_init: DMG
DMG
entity_init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\entity.c .\kitaq-docs\samples\api-examples\gb\entity_pool.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\entity_pool.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm
Implémentation et source

kitaqgb/lib/entity.h:27

Notes de déclaration (texte source)
Reset every slot before the game starts using the pool.

kitaqgb/lib/entity.c:8

c
void entity_init()
{
    entity_clear_all();
}
entity_update_all

Parcourt les emplacements actifs par ID croissant et appelle fn(id) une fois pour chacun. Le rappel implémente déplacements, collisions ou temporisateurs ; le pool ne fournit pas cette logique. Un rappel null ne fait rien.

Syntaxe

c
void entity_update_all(EntityFn fn);

Paramètres

fn

Pointeur de fonction de signature void fn(u8 id). Reçoit un ID ; utilisez entity_get(id) pour accéder aux champs. Null est accepté et n’entraîne aucun appel.

Valeur renvoyée

Aucune (void).

Conditions et limites

Le pool est un tableau fixe, sans allocation sur le tas. ENTITY_MAX vaut 16 par défaut et doit être compris entre 1 et 255, avec la même définition dans chaque unité de compilation. Les ID commencent à zéro ; 0xFF indique un échec.

L’activité est testée au moment d’atteindre l’emplacement. Un rappel peut désactiver un emplacement suivant pour le sauter, ou l’activer pour le visiter dans cette passe. Ce n’est pas un instantané de l’ensemble actif initial.

Exemple d’utilisation

c
void demo_update(u8 id) {
    Entity* entity;
    entity = entity_get(id);
    if (entity != 0) { entity->x = entity->x + 1; update_calls++; }
}

// From main(), after creating two entities:
update_calls = 0;
entity_update_all(demo_update);
automatic_updates = update_calls;
if (automatic_updates != 2) { failures++; }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet illustre le cycle de vie d’un emplacement réutilisable. Lisez les nombres avec leurs libellés : CREATED 002 après deux allocations ; AFTER FREE 001 après libération de la première ; REUSED ID 000 quand le plus petit ID libre est réutilisé ; AFTER CLEAR 000 après vidage du pool. Il vérifie aussi la recherche null après libération et la remise à zéro après réallocation. FAILED CHECKS 000 indique que les valeurs concordent.

Le parcours GB appelle chaque rappel pour les deux entités actives : UPDATE CALLS 002 et DRAW CALLS 002. Le rappel de mise à jour déplace les deux objets d’une tuile vers la droite. Celui de dessin place A en (3,12) et B en (7,12) pour les représenter. Ce sont des tuiles de police du fond dessinées par le rappel, pas des sprites alloués automatiquement.

entity_update_all: DMG
DMG
entity_update_all: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\entity.c .\kitaq-docs\samples\api-examples\gb\entity_pool.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\entity_pool.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm
Implémentation et source

kitaqgb/lib/entity.h:37

Notes de déclaration (texte source)
Call fn for each slot that is active when the scan reaches it; null is a no-op.
Callbacks may change the pool, so newly activated later slots can run in this pass.

kitaqgb/lib/entity.c:74

c
void entity_update_all(EntityFn fn)
{
    u8 i = 0;
    if (fn == 0) return;
    while (i < ENTITY_MAX) {
        if (entity_pool[i].active != 0) {
            fn(i);
        }
        i++;
    }
}

fixed.h — Calcul en virgule fixe Q8.8 et rectangles

L’arithmétique Q8.8 représente les coordonnées et vitesses fractionnaires avec des entiers ; elle s’accompagne de tests de collision entre rectangles et points. Vérifiez la précision et les limites de chaque opération.

fix_div

Divise des valeurs Q8.8 après avoir réduit la précision des opérandes.

Syntaxe

c
fix8 fix_div(fix8 a, fix8 b);

Paramètres

a

Opérande de gauche au format Q8.8.

b

Opérande de droite au format Q8.8.

Valeur renvoyée

Renvoie un quotient Q8.8, ou zéro si b == 0.

Conditions et limites

L’expression calculée est ((a >> 4) * 256) / (b >> 4). Un diviseur non nul doit le rester après le décalage : n’utilisez pas de valeur brute positive de 1 à 15. Le numérateur mis à l’échelle doit lui aussi tenir sur 16 bits.

Exemple d’utilisation

c
result[3]=fix_div(768,512);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Diviser 3,0 par 2,0 donne 1,5 (valeur brute 384). Une vérification distincte contrôle le retour prévu lorsque le diviseur est exactement nul.

fix_div: DMG
DMG
fix_div: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_math.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_math.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/fixed.h:32

Notes de déclaration (texte source)
Scale the reduced-precision quotient back to 8.8 and return zero for b == 0.
Callers must also ensure (b >> 4) is nonzero; the explicit check only tests b.
The intermediate product must fit the compiler's integer arithmetic.

kitaqgb/lib/fixed.c:26

c
fix8 fix_div(fix8 a, fix8 b)
{
    if (b == 0) return 0;
    return (fix8)(((a >> 4) * 256) / (b >> 4));
}
fix_from_int

Convertit une coordonnée ou une vitesse entière en Q8.8 pour conserver les parties fractionnaires dans les calculs suivants.

Syntaxe

c
fix8 fix_from_int(s16 n);

Paramètres

n

Entier à convertir, de −128 à 127.

Valeur renvoyée

Renvoie la valeur brute n × 256.

Conditions et limites

fix8 est un format Q8.8 signé : la valeur brute 256 représente 1,0. Les valeurs intermédiaires et les résultats doivent tenir sur 16 bits.

Exemple d’utilisation

c
result[0]=fix_from_int(-3);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple convertit −3. L’affichage −00768 correspond au résultat brut Q8.8, soit −768.

fix_from_int: DMG
DMG
fix_from_int: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_math.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_math.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/fixed.h:23

Notes de déclaration (texte source)
Convert an integer to signed 8.8 fixed point by moving it into the high byte.
The caller must keep the result within the representable 16-bit range.

kitaqgb/lib/fixed.c:5

c
fix8 fix_from_int(s16 n)
{
    return (fix8)(n << 8);
}
fix_lerp

Interpole entre deux valeurs Q8.8 à l’aide d’un poids sur huit bits.

Syntaxe

c
fix8 fix_lerp(fix8 a, fix8 b, u8 t_q8);

Paramètres

a

Opérande de gauche au format Q8.8.

b

Opérande de droite au format Q8.8.

t_q8

Poids d’interpolation, de 0 à 255.

Valeur renvoyée

Renvoie la valeur Q8.8 interpolée approximativement.

Conditions et limites

La différence et le poids sont chacun décalés de quatre bits vers la droite. Le poids n’a donc que 16 niveaux, et même 255 ne permet pas nécessairement d’atteindre la valeur finale. b - a et le résultat doivent tenir sur 16 bits.

Exemple d’utilisation

c
result[4]=fix_lerp(0,1024,128);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Entre 0 et 4,0, un poids de 128 donne 2,0 (valeur brute 512). Un poids de 255 donne 3,75 (valeur brute 960), ce qui montre que la valeur finale n’est pas atteinte.

fix_lerp: DMG
DMG
fix_lerp: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_math.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_math.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/fixed.h:35

Notes de déclaration (texte source)
Interpolate toward b using a quantized Q0.8 weight. Both shifts discard low
bits, so small changes may vanish and a weight of 255 need not reach b.

kitaqgb/lib/fixed.c:34

c
fix8 fix_lerp(fix8 a, fix8 b, u8 t_q8)
{
    // The endpoint difference must fit s16 before the reduced-precision multiplication.
    fix8 d = (fix8)(b - a);
    return (fix8)(a + (fix8)((d >> 4) * (s16)(t_q8 >> 4)));
}
fix_mul

Multiplie deux valeurs Q8.8 par une approximation peu coûteuse en calcul.

Syntaxe

c
fix8 fix_mul(fix8 a, fix8 b);

Paramètres

a

Opérande de gauche au format Q8.8.

b

Opérande de droite au format Q8.8.

Valeur renvoyée

Renvoie le produit au format Q8.8.

Conditions et limites

Chaque opérande est décalé de quatre bits vers la droite avant la multiplication, ce qui supprime ses quatre bits de poids faible. La précision est donc inférieure à celle d’un produit complet de deux valeurs de 16 bits. fix8 est un format Q8.8 signé où la valeur brute 256 représente 1,0. Les valeurs intermédiaires et les résultats doivent tenir sur 16 bits.

Exemple d’utilisation

c
result[2]=fix_mul(384,512);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Multiplier 1,5 par 2,0 donne 3,0 (valeur brute 768). Le programme vérifie aussi un cas de quantification : le produit des valeurs brutes 271 et 271 donne 256.

fix_mul: DMG
DMG
fix_mul: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_math.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_math.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/fixed.h:28

Notes de déclaration (texte source)
Approximate 8.8 multiplication by discarding four low bits from each operand
before multiplying. This trades precision for a smaller intermediate product.

kitaqgb/lib/fixed.c:18

c
fix8 fix_mul(fix8 a, fix8 b)
{
    return (fix8)((a >> 4) * (b >> 4));
}
fix_to_int

Extrait une coordonnée entière d’une valeur Q8.8 en supprimant les bits fractionnaires. Les valeurs négatives sont arrondies vers moins l’infini.

Syntaxe

c
s16 fix_to_int(fix8 x);

Paramètres

x

Valeur Q8.8 à convertir en entier.

Valeur renvoyée

Renvoie un entier signé.

Conditions et limites

fix8 est un format Q8.8 signé : la valeur brute 256 représente 1,0. Les valeurs intermédiaires et les résultats doivent tenir sur 16 bits.

Exemple d’utilisation

c
result[1]=fix_to_int(-384);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La valeur brute −384 (−1,5) donne −2, affiché sous la forme −00002. Un test de limite vérifie aussi que la valeur brute −1 devient −1.

fix_to_int: DMG
DMG
fix_to_int: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_math.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_math.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/fixed.h:25

Notes de déclaration (texte source)
Discard the eight fractional bits using a signed right shift.

kitaqgb/lib/fixed.c:11

c
s16 fix_to_int(fix8 x)
{
    return (s16)(x >> 8);
}
kq_abs_s16

Calcule la valeur absolue d’un entier signé sur 16 bits.

Syntaxe

c
s16 kq_abs_s16(s16 v);

Paramètres

v

Valeur signée sur 16 bits dont on cherche la valeur absolue.

Valeur renvoyée

Renvoie une valeur absolue non négative, sauf pour −32768, dont la valeur absolue n’est pas représentable.

Conditions et limites

La valeur positive 32768 ne tient pas dans un s16. Excluez −32768 si vous avez besoin d’un résultat non négatif.

Exemple d’utilisation

c
result[0]=kq_abs_s16(-123);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple transforme −123 en 123, comme pour mesurer l’amplitude d’un écart entre deux coordonnées.

kq_abs_s16: DMG
DMG
kq_abs_s16: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_math_limits.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_math_limits.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/fixed.h:38

Notes de déclaration (texte source)
Return the magnitude in s16. The most-negative s16 has no positive s16
representation and must be excluded by callers needing a nonnegative result.

kitaqgb/lib/fixed.c:43

c
s16 kq_abs_s16(s16 v)
{
    if (v < 0) return (s16)(0 - v);
    return v;
}
kq_clamp_s16

Limite une coordonnée ou une vitesse à un intervalle dont les bornes sont incluses.

Syntaxe

c
s16 kq_clamp_s16(s16 v, s16 lo, s16 hi);

Paramètres

v

Valeur signée à limiter.

lo

Borne inférieure incluse.

hi

Borne supérieure incluse.

Valeur renvoyée

Renvoie lo en dessous de l’intervalle, hi au-dessus, ou v si la valeur est dans l’intervalle.

Conditions et limites

Fournissez un intervalle valide tel que lo <= hi.

Exemple d’utilisation

c
result[3]=kq_clamp_s16(25,-10,10);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Limiter 25 à l’intervalle −10…10 donne 10. Les tests couvrent aussi −11→−10 à la borne inférieure et 3→3 à l’intérieur de l’intervalle.

kq_clamp_s16: DMG
DMG
kq_clamp_s16: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_math_limits.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_math_limits.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/fixed.h:44

Notes de déclaration (texte source)
Clamp to an inclusive interval; callers must provide lo <= hi.

kitaqgb/lib/fixed.c:64

c
s16 kq_clamp_s16(s16 v, s16 lo, s16 hi)
{
    if (v < lo) return lo;
    if (v > hi) return hi;
    return v;
}
kq_max_s16

Sélectionne le plus grand de deux entiers signés sur 16 bits.

Syntaxe

c
s16 kq_max_s16(s16 a, s16 b);

Paramètres

a

Première valeur signée à comparer.

b

Seconde valeur signée à comparer.

Valeur renvoyée

Renvoie l’opérande sélectionné.

Conditions et limites

La comparaison tient compte du signe. Si les opérandes sont égaux, leur valeur commune est renvoyée. Aucun des deux n’est modifié.

Exemple d’utilisation

c
result[2]=kq_max_s16(-7,4);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Comparer −7 et 4 donne 4. Les résultats négatifs sont affichés avec un signe moins.

kq_max_s16: DMG
DMG
kq_max_s16: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_math_limits.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_math_limits.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/fixed.h:42

Notes de déclaration (texte source)
Select the larger signed value.

kitaqgb/lib/fixed.c:57

c
s16 kq_max_s16(s16 a, s16 b)
{
    if (a > b) return a;
    return b;
}
kq_min_s16

Sélectionne le plus petit de deux entiers signés sur 16 bits.

Syntaxe

c
s16 kq_min_s16(s16 a, s16 b);

Paramètres

a

Première valeur signée à comparer.

b

Seconde valeur signée à comparer.

Valeur renvoyée

Renvoie l’opérande sélectionné.

Conditions et limites

La comparaison tient compte du signe. Si les opérandes sont égaux, leur valeur commune est renvoyée. Aucun des deux n’est modifié.

Exemple d’utilisation

c
result[1]=kq_min_s16(-7,4);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Comparer −7 et 4 donne -7. Les résultats négatifs sont affichés avec un signe moins.

kq_min_s16: DMG
DMG
kq_min_s16: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_math_limits.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_math_limits.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/fixed.h:40

Notes de déclaration (texte source)
Select the smaller signed value.

kitaqgb/lib/fixed.c:50

c
s16 kq_min_s16(s16 a, s16 b)
{
    if (a < b) return a;
    return b;
}
kq_point_in_rect

Teste si un point se trouve dans un rectangle, bords gauche et supérieur inclus.

Syntaxe

c
u8 kq_point_in_rect(s16 x, s16 y, KQRect r);

Paramètres

x

Coordonnée X du point, dans le repère du rectangle.

y

Coordonnée Y du point.

r

Rectangle à tester, passé par valeur.

Valeur renvoyée

Renvoie 1 à l’intérieur et 0 à l’extérieur.

Conditions et limites

Utilisez des dimensions positives et veillez à ce que les sommes coordonnée + dimension soient représentables en s16. Les bords droit et inférieur sont exclus. Les rectangles d’aire nulle ne sont pas explicitement rejetés.

Exemple d’utilisation

c
result[1]=kq_point_in_rect(9,1,a);
for(gy=0;gy<11;gy++){for(gx=0;gx<15;gx++){
inside_a=kq_point_in_rect(gx,gy,a);inside_b=kq_point_in_rect(gx,gy,b);
tile=0;if(inside_a){tile=65;result[3]=result[3]+1;}if(inside_b)tile=66;if(inside_a && inside_b){tile=79;result[4]=result[4]+1;}
m_put(1+gx,2+gy,tile);if(tile!=0)vram_example_color(1+gx,2+gy,1,1,tile==65?1:(tile==66?2:3));
}}

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Chaque unité de coordonnée correspond à une tuile. Les rectangles A en (1,1) et B en (5,4) mesurent tous deux 8×6. Les cases propres à A affichent A, celles propres à B affichent B, et le chevauchement de 4×3 affiche 12 cases O. Le bord droit de A, x=9, est exclu. Sur CGB, A est rouge, B bleu et O vert.

kq_point_in_rect: DMG
DMG
kq_point_in_rect: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_geometry.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_geometry.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/fixed.h:51

Notes de déclaration (texte source)
Test a half-open rectangle: left/top edges are included, right/bottom excluded.
The coordinate-plus-size sums must remain representable as s16.

kitaqgb/lib/fixed.c:85

c
u8 kq_point_in_rect(s16 x, s16 y, KQRect r)
{
    if (x < r.x) return 0;
    if (y < r.y) return 0;
    if (x >= (s16)(r.x + r.w)) return 0;
    if (y >= (s16)(r.y + r.h)) return 0;
    return 1;
}
kq_rect_intersect

Teste si deux rectangles alignés sur les axes se recouvrent sur une aire strictement positive.

Syntaxe

c
u8 kq_rect_intersect(KQRect a, KQRect b);

Paramètres

a

Premier rectangle, passé par valeur : x, y indiquent son coin supérieur gauche ; w, h sont sa largeur et sa hauteur.

b

Second rectangle, dans le même repère que A.

Valeur renvoyée

Renvoie 1 en cas de recouvrement, et 0 en cas de séparation ou de simple contact des bords.

Conditions et limites

Utilisez des dimensions positives et veillez à ce que les sommes coordonnée + dimension soient représentables en s16. Les bords droit et inférieur sont exclus. Les rectangles d’aire nulle ne sont pas explicitement rejetés.

Exemple d’utilisation

c
result[0]=kq_rect_intersect(a,b);result[2]=kq_rect_intersect(a,touch);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Chaque unité de coordonnée correspond à une tuile. Les rectangles A en (1,1) et B en (5,4) mesurent tous deux 8×6. Les cases propres à A affichent A, celles propres à B affichent B, et le chevauchement de 4×3 affiche 12 cases O. Le bord droit de A, x=9, est exclu. Sur CGB, A est rouge, B bleu et O vert.

kq_rect_intersect: DMG
DMG
kq_rect_intersect: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_geometry.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_geometry.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/fixed.h:48

Notes de déclaration (texte source)
Test overlap using exclusive right/bottom edges; touching edges do not collide.
Require positive dimensions and edge sums that fit s16; zero-sized rectangles
are not explicitly rejected and may be reported as overlapping.

kitaqgb/lib/fixed.c:74

c
u8 kq_rect_intersect(KQRect a, KQRect b)
{
    if ((s16)(a.x + a.w) <= b.x) return 0;
    if ((s16)(b.x + b.w) <= a.x) return 0;
    if ((s16)(a.y + a.h) <= b.y) return 0;
    if ((s16)(b.y + b.h) <= a.y) return 0;
    return 1;
}

input.h — État des boutons, appuis, relâchements et répétition

Utilisez input_down pour un mouvement continu, input_pressed pour une action unique, input_released pour agir au relâchement et input_repeat pour répéter une sélection de menu. Initialisez une fois, mettez à jour une fois par cycle d’entrée, puis consultez autant que nécessaire. btn_down, btn_pressed, btn_released et btn_repeat sont les alias de ces quatre consultations.

Masques communs : BTN_RIGHT=0x01, BTN_LEFT=0x02, BTN_UP=0x04, BTN_DOWN=0x08, BTN_A=0x10, BTN_B=0x20, BTN_SELECT=0x40, BTN_START=0x80. Un bit à 1 indique un bouton maintenu. Ce format s’applique à input_* sur GB et FC ; les lectures brutes FC utilisent un autre ordre.

Les délais se comptent en mises à jour, pas en millisecondes. Un nouvel appui produit un événement immédiat. Avec INPUT_REPEAT_DELAY=18 et INPUT_REPEAT_RATE=5, le suivant arrive 19 mises à jour plus tard, puis tous les 6 appels. Chaque bouton a son compteur. Appliquez les mêmes macros lors de la compilation de input.c ; modifier seulement l’en-tête du code appelant ne reconfigure pas la bibliothèque.

btn_down

btn_down est un alias de input_down. Vérifie si au moins un des boutons sélectionnés est actuellement maintenu.

Indique si au moins un bouton sélectionné par mask est maintenu.

Syntaxe

c
u8 btn_down(u8 mask);

Paramètres

mask

Un masque BTN_*, ou plusieurs combinés avec |. Un seul bouton correspondant suffit ; BTN_A | BTN_B n’exige pas les deux. Le masque 0 renvoie toujours 0. Pour vérifier que tous sont maintenus, comparez (input_current() & mask) == mask.

Valeur renvoyée

Renvoie exactement 1 si un bouton sélectionné remplit la condition, sinon 0. Le résultat n’est pas un masque de boutons.

Conditions et limites

L’en-tête définit une macro objet qui se développe en nom d’implémentation. Arguments, résultats et accès à l’état sont identiques à ceux de la cible ; l’alias n’ajoute aucun état ni traitement distinct. Utilisez input.h/input.c pour les entrées ou system.h/system.c pour les services d’images, comme dans l’exemple complet et sa commande de compilation.

Masques communs : BTN_RIGHT=0x01, BTN_LEFT=0x02, BTN_UP=0x04, BTN_DOWN=0x08, BTN_A=0x10, BTN_B=0x20, BTN_SELECT=0x40, BTN_START=0x80. Un bit à 1 indique un bouton maintenu. Ce format s’applique à input_* sur GB et FC ; les lectures brutes FC utilisent un autre ordre.

Les fonctions de consultation lisent le dernier input_update() sans relire le contrôleur, consommer d’événement ni avancer les compteurs. Plusieurs consultations dans un même cycle donnent le même résultat. Deux appels à input_update() avec un bouton maintenu effacent son événement de nouvel appui au second appel.

input_down

Exemple d’utilisation

c
if (btn_down(BTN_A)!=0) held_ticks++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme distingue le maintien d’un bouton, un nouvel appui, le relâchement et la répétition automatique. Maintenez A pendant 40 mises à jour, puis relâchez-le. FIRST DOWN, FIRST PRESS et FIRST REPEAT valent 1 ; FIRST CURRENT vaut 16. HELD TICKS vaut 40, PRESS COUNT vaut 1 et REPEAT COUNT vaut 5. Au relâchement, RELEASE vaut 1, LAST CURRENT vaut 0 et LAST PREVIOUS vaut 16. FAILED CHECKS doit valoir 0. Une autre durée modifie les compteurs ; le programme vérifie les intervalles de répétition selon la durée réellement observée.

btn_down: DMG
DMG
btn_down: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\input.c .\kitaq-docs\samples\api-examples\gb\input_aliases.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\input_aliases.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm --no-cache
Implémentation et source

kitaqgb/lib/input.h:48

c
#define btn_down input_down

kitaqgb/lib/input.c:68

c
u8 input_down(u8 mask)
{
    return (u8)((kq_input_keys & mask) != 0);
}
btn_pressed

btn_pressed est un alias de input_pressed. Vérifie si au moins un des boutons sélectionnés vient d’être enfoncé lors de la dernière mise à jour des entrées.

Détecte un passage de relâché à appuyé pour un bouton du masque lors de la dernière mise à jour.

Syntaxe

c
u8 btn_pressed(u8 mask);

Paramètres

mask

Un masque BTN_*, ou plusieurs combinés avec |. Un seul bouton correspondant suffit ; BTN_A | BTN_B n’exige pas les deux. Le masque 0 renvoie toujours 0. Pour vérifier que tous sont maintenus, comparez (input_current() & mask) == mask.

Valeur renvoyée

Renvoie exactement 1 si un bouton sélectionné remplit la condition, sinon 0. Le résultat n’est pas un masque de boutons.

Conditions et limites

L’en-tête définit une macro objet qui se développe en nom d’implémentation. Arguments, résultats et accès à l’état sont identiques à ceux de la cible ; l’alias n’ajoute aucun état ni traitement distinct. Utilisez input.h/input.c pour les entrées ou system.h/system.c pour les services d’images, comme dans l’exemple complet et sa commande de compilation.

Masques communs : BTN_RIGHT=0x01, BTN_LEFT=0x02, BTN_UP=0x04, BTN_DOWN=0x08, BTN_A=0x10, BTN_B=0x20, BTN_SELECT=0x40, BTN_START=0x80. Un bit à 1 indique un bouton maintenu. Ce format s’applique à input_* sur GB et FC ; les lectures brutes FC utilisent un autre ordre.

Les fonctions de consultation lisent le dernier input_update() sans relire le contrôleur, consommer d’événement ni avancer les compteurs. Plusieurs consultations dans un même cycle donnent le même résultat. Deux appels à input_update() avec un bouton maintenu effacent son événement de nouvel appui au second appel.

input_pressed

Exemple d’utilisation

c
if (btn_pressed(BTN_A)!=0) {
        press_count++; seen_press=1;
        first_down=btn_down(BTN_A); first_press=btn_pressed(BTN_A);
        first_repeat=btn_repeat(BTN_A);
        first_current=input_current(); // Only A held: BTN_A, or decimal 16.
        first_previous=input_previous(); // No buttons in the preceding sample: 0.
        if (first_down!=1 || first_press!=1 || first_repeat!=1) failures++;
        if (first_current!=BTN_A || first_previous!=0) failures++;
        if (btn_down(BTN_A|BTN_B)!=1 || btn_down(0)!=0) failures++;
    }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme distingue le maintien d’un bouton, un nouvel appui, le relâchement et la répétition automatique. Maintenez A pendant 40 mises à jour, puis relâchez-le. FIRST DOWN, FIRST PRESS et FIRST REPEAT valent 1 ; FIRST CURRENT vaut 16. HELD TICKS vaut 40, PRESS COUNT vaut 1 et REPEAT COUNT vaut 5. Au relâchement, RELEASE vaut 1, LAST CURRENT vaut 0 et LAST PREVIOUS vaut 16. FAILED CHECKS doit valoir 0. Une autre durée modifie les compteurs ; le programme vérifie les intervalles de répétition selon la durée réellement observée.

btn_pressed: DMG
DMG
btn_pressed: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\input.c .\kitaq-docs\samples\api-examples\gb\input_aliases.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\input_aliases.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm --no-cache
Implémentation et source

kitaqgb/lib/input.h:49

c
#define btn_pressed input_pressed

kitaqgb/lib/input.c:74

c
u8 input_pressed(u8 mask)
{
    return (u8)((kq_input_press_keys & mask) != 0);
}
btn_released

btn_released est un alias de input_released. Vérifie si au moins un des boutons sélectionnés a été relâché lors de la dernière mise à jour des entrées.

Détecte un relâchement pour un bouton du masque lors de la dernière mise à jour.

Syntaxe

c
u8 btn_released(u8 mask);

Paramètres

mask

Un masque BTN_*, ou plusieurs combinés avec |. Un seul bouton correspondant suffit ; BTN_A | BTN_B n’exige pas les deux. Le masque 0 renvoie toujours 0. Pour vérifier que tous sont maintenus, comparez (input_current() & mask) == mask.

Valeur renvoyée

Renvoie exactement 1 si un bouton sélectionné remplit la condition, sinon 0. Le résultat n’est pas un masque de boutons.

Conditions et limites

L’en-tête définit une macro objet qui se développe en nom d’implémentation. Arguments, résultats et accès à l’état sont identiques à ceux de la cible ; l’alias n’ajoute aucun état ni traitement distinct. Utilisez input.h/input.c pour les entrées ou system.h/system.c pour les services d’images, comme dans l’exemple complet et sa commande de compilation.

Masques communs : BTN_RIGHT=0x01, BTN_LEFT=0x02, BTN_UP=0x04, BTN_DOWN=0x08, BTN_A=0x10, BTN_B=0x20, BTN_SELECT=0x40, BTN_START=0x80. Un bit à 1 indique un bouton maintenu. Ce format s’applique à input_* sur GB et FC ; les lectures brutes FC utilisent un autre ordre.

Les fonctions de consultation lisent le dernier input_update() sans relire le contrôleur, consommer d’événement ni avancer les compteurs. Plusieurs consultations dans un même cycle donnent le même résultat. Deux appels à input_update() avec un bouton maintenu effacent son événement de nouvel appui au second appel.

input_released

Exemple d’utilisation

c
if (btn_released(BTN_A)!=0) {
        release_result=btn_released(BTN_A);
        last_current=input_current(); last_previous=input_previous();
        if (btn_down(BTN_A)!=0 || btn_pressed(BTN_A)!=0 || btn_repeat(BTN_A)!=0) failures++;
        break;
    }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme distingue le maintien d’un bouton, un nouvel appui, le relâchement et la répétition automatique. Maintenez A pendant 40 mises à jour, puis relâchez-le. FIRST DOWN, FIRST PRESS et FIRST REPEAT valent 1 ; FIRST CURRENT vaut 16. HELD TICKS vaut 40, PRESS COUNT vaut 1 et REPEAT COUNT vaut 5. Au relâchement, RELEASE vaut 1, LAST CURRENT vaut 0 et LAST PREVIOUS vaut 16. FAILED CHECKS doit valoir 0. Une autre durée modifie les compteurs ; le programme vérifie les intervalles de répétition selon la durée réellement observée.

btn_released: DMG
DMG
btn_released: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\input.c .\kitaq-docs\samples\api-examples\gb\input_aliases.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\input_aliases.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm --no-cache
Implémentation et source

kitaqgb/lib/input.h:50

c
#define btn_released input_released

kitaqgb/lib/input.c:80

c
u8 input_released(u8 mask)
{
    return (u8)((kq_input_release_keys & mask) != 0);
}
btn_repeat

btn_repeat est un alias de input_repeat. Détecte l’appui initial ou une impulsion de répétition programmée pendant le maintien d’un bouton.

Détecte un premier appui ou une impulsion de répétition pour un bouton du masque.

Syntaxe

c
u8 btn_repeat(u8 mask);

Paramètres

mask

Un masque BTN_*, ou plusieurs combinés avec |. Un seul bouton correspondant suffit ; BTN_A | BTN_B n’exige pas les deux. Le masque 0 renvoie toujours 0. Pour vérifier que tous sont maintenus, comparez (input_current() & mask) == mask.

Valeur renvoyée

Renvoie exactement 1 si un bouton sélectionné remplit la condition, sinon 0. Le résultat n’est pas un masque de boutons.

Conditions et limites

L’en-tête définit une macro objet qui se développe en nom d’implémentation. Arguments, résultats et accès à l’état sont identiques à ceux de la cible ; l’alias n’ajoute aucun état ni traitement distinct. Utilisez input.h/input.c pour les entrées ou system.h/system.c pour les services d’images, comme dans l’exemple complet et sa commande de compilation.

Masques communs : BTN_RIGHT=0x01, BTN_LEFT=0x02, BTN_UP=0x04, BTN_DOWN=0x08, BTN_A=0x10, BTN_B=0x20, BTN_SELECT=0x40, BTN_START=0x80. Un bit à 1 indique un bouton maintenu. Ce format s’applique à input_* sur GB et FC ; les lectures brutes FC utilisent un autre ordre.

Les fonctions de consultation lisent le dernier input_update() sans relire le contrôleur, consommer d’événement ni avancer les compteurs. Plusieurs consultations dans un même cycle donnent le même résultat. Deux appels à input_update() avec un bouton maintenu effacent son événement de nouvel appui au second appel.

Les délais se comptent en mises à jour, pas en millisecondes. Un nouvel appui produit un événement immédiat. Avec INPUT_REPEAT_DELAY=18 et INPUT_REPEAT_RATE=5, le suivant arrive 19 mises à jour plus tard, puis tous les 6 appels. Chaque bouton a son compteur. Appliquez les mêmes macros lors de la compilation de input.c ; modifier seulement l’en-tête du code appelant ne reconfigure pas la bibliothèque.

input_repeat

Exemple d’utilisation

c
if (btn_repeat(BTN_A)!=0) {
        // The initial press is pulse 1. Defaults then wait 19 updates, followed by 6.
        if (repeat_count==1 && held_ticks-previous_pulse!=19) failures++;
        if (repeat_count>1 && held_ticks-previous_pulse!=6) failures++;
        previous_pulse=held_ticks; repeat_count++;
        if (btn_repeat(BTN_A)!=1) failures++; // Reading again does not consume it.
    }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme distingue le maintien d’un bouton, un nouvel appui, le relâchement et la répétition automatique. Maintenez A pendant 40 mises à jour, puis relâchez-le. FIRST DOWN, FIRST PRESS et FIRST REPEAT valent 1 ; FIRST CURRENT vaut 16. HELD TICKS vaut 40, PRESS COUNT vaut 1 et REPEAT COUNT vaut 5. Au relâchement, RELEASE vaut 1, LAST CURRENT vaut 0 et LAST PREVIOUS vaut 16. FAILED CHECKS doit valoir 0. Une autre durée modifie les compteurs ; le programme vérifie les intervalles de répétition selon la durée réellement observée.

btn_repeat: DMG
DMG
btn_repeat: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\input.c .\kitaq-docs\samples\api-examples\gb\input_aliases.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\input_aliases.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm --no-cache
Implémentation et source

kitaqgb/lib/input.h:51

c
#define btn_repeat input_repeat

kitaqgb/lib/input.c:86

c
u8 input_repeat(u8 mask)
{
    return (u8)((kq_input_repeat_keys & mask) != 0);
}
input_current

Renvoie le masque complet des boutons maintenus lors de la dernière mise à jour.

Syntaxe

c
u8 input_current();

Valeur renvoyée

Un masque de 8 bits au format commun BTN_*. Plusieurs boutons peuvent être présents simultanément ; 0 signifie aucun.

Conditions et limites

Masques communs : BTN_RIGHT=0x01, BTN_LEFT=0x02, BTN_UP=0x04, BTN_DOWN=0x08, BTN_A=0x10, BTN_B=0x20, BTN_SELECT=0x40, BTN_START=0x80. Un bit à 1 indique un bouton maintenu. Ce format s’applique à input_* sur GB et FC ; les lectures brutes FC utilisent un autre ordre.

Les fonctions de consultation lisent le dernier input_update() sans relire le contrôleur, consommer d’événement ni avancer les compteurs. Plusieurs consultations dans un même cycle donnent le même résultat. Deux appels à input_update() avec un bouton maintenu effacent son événement de nouvel appui au second appel.

Exemple d’utilisation

c
first_current=input_current(); // Only A held: BTN_A, or decimal 16.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme distingue le maintien d’un bouton, un nouvel appui, le relâchement et la répétition automatique. Maintenez A pendant 40 mises à jour, puis relâchez-le. FIRST DOWN, FIRST PRESS et FIRST REPEAT valent 1 ; FIRST CURRENT vaut 16. HELD TICKS vaut 40, PRESS COUNT vaut 1 et REPEAT COUNT vaut 5. Au relâchement, RELEASE vaut 1, LAST CURRENT vaut 0 et LAST PREVIOUS vaut 16. FAILED CHECKS doit valoir 0. Une autre durée modifie les compteurs ; le programme vérifie les intervalles de répétition selon la durée réellement observée.

input_current: DMG
DMG
input_current: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\input.c .\kitaq-docs\samples\api-examples\gb\input_edges.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\input_edges.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm --no-cache
Implémentation et source

kitaqgb/lib/input.h:44

Notes de déclaration (texte source)
Return the complete held-button mask from the latest update.

kitaqgb/lib/input.c:92

c
u8 input_current()
{
    return kq_input_keys;
}
input_down

Indique si au moins un bouton sélectionné par mask est maintenu.

Syntaxe

c
u8 input_down(u8 mask);

Paramètres

mask

Un masque BTN_*, ou plusieurs combinés avec |. Un seul bouton correspondant suffit ; BTN_A | BTN_B n’exige pas les deux. Le masque 0 renvoie toujours 0. Pour vérifier que tous sont maintenus, comparez (input_current() & mask) == mask.

Valeur renvoyée

Renvoie exactement 1 si un bouton sélectionné remplit la condition, sinon 0. Le résultat n’est pas un masque de boutons.

Conditions et limites

Masques communs : BTN_RIGHT=0x01, BTN_LEFT=0x02, BTN_UP=0x04, BTN_DOWN=0x08, BTN_A=0x10, BTN_B=0x20, BTN_SELECT=0x40, BTN_START=0x80. Un bit à 1 indique un bouton maintenu. Ce format s’applique à input_* sur GB et FC ; les lectures brutes FC utilisent un autre ordre.

Les fonctions de consultation lisent le dernier input_update() sans relire le contrôleur, consommer d’événement ni avancer les compteurs. Plusieurs consultations dans un même cycle donnent le même résultat. Deux appels à input_update() avec un bouton maintenu effacent son événement de nouvel appui au second appel.

Exemple d’utilisation

c
if (input_down(BTN_A)!=0) held_ticks++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme distingue le maintien d’un bouton, un nouvel appui, le relâchement et la répétition automatique. Maintenez A pendant 40 mises à jour, puis relâchez-le. FIRST DOWN, FIRST PRESS et FIRST REPEAT valent 1 ; FIRST CURRENT vaut 16. HELD TICKS vaut 40, PRESS COUNT vaut 1 et REPEAT COUNT vaut 5. Au relâchement, RELEASE vaut 1, LAST CURRENT vaut 0 et LAST PREVIOUS vaut 16. FAILED CHECKS doit valoir 0. Une autre durée modifie les compteurs ; le programme vérifie les intervalles de répétition selon la durée réellement observée.

input_down: DMG
DMG
input_down: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\input.c .\kitaq-docs\samples\api-examples\gb\input_edges.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\input_edges.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm --no-cache
Implémentation et source

kitaqgb/lib/input.h:36

Notes de déclaration (texte source)
Return whether any masked button is currently held.

kitaqgb/lib/input.c:68

c
u8 input_down(u8 mask)
{
    return (u8)((kq_input_keys & mask) != 0);
}
input_init

Efface les masques courant, précédent, d’appui, de relâchement et de répétition, puis réinitialise les huit compteurs à INPUT_REPEAT_DELAY. Le contrôleur n’est pas lu. Un bouton maintenu lors de la première mise à jour suivante est considéré comme un nouvel appui.

Syntaxe

c
void input_init();

Valeur renvoyée

Aucune (void).

Conditions et limites

Masques communs : BTN_RIGHT=0x01, BTN_LEFT=0x02, BTN_UP=0x04, BTN_DOWN=0x08, BTN_A=0x10, BTN_B=0x20, BTN_SELECT=0x40, BTN_START=0x80. Un bit à 1 indique un bouton maintenu. Ce format s’applique à input_* sur GB et FC ; les lectures brutes FC utilisent un autre ordre.

Les délais se comptent en mises à jour, pas en millisecondes. Un nouvel appui produit un événement immédiat. Avec INPUT_REPEAT_DELAY=18 et INPUT_REPEAT_RATE=5, le suivant arrive 19 mises à jour plus tard, puis tous les 6 appels. Chaque bouton a son compteur. Appliquez les mêmes macros lors de la compilation de input.c ; modifier seulement l’en-tête du code appelant ne reconfigure pas la bibliothèque.

Exemple d’utilisation

c
input_init();
if (input_current()!=0 || input_previous()!=0) failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme distingue le maintien d’un bouton, un nouvel appui, le relâchement et la répétition automatique. Maintenez A pendant 40 mises à jour, puis relâchez-le. FIRST DOWN, FIRST PRESS et FIRST REPEAT valent 1 ; FIRST CURRENT vaut 16. HELD TICKS vaut 40, PRESS COUNT vaut 1 et REPEAT COUNT vaut 5. Au relâchement, RELEASE vaut 1, LAST CURRENT vaut 0 et LAST PREVIOUS vaut 16. FAILED CHECKS doit valoir 0. Une autre durée modifie les compteurs ; le programme vérifie les intervalles de répétition selon la durée réellement observée.

input_init: DMG
DMG
input_init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\input.c .\kitaq-docs\samples\api-examples\gb\input_edges.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\input_edges.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm --no-cache
Implémentation et source

kitaqgb/lib/input.h:31

Notes de déclaration (texte source)
Clear sampled/edge state and initialize an independent repeat timer for each button.

kitaqgb/lib/input.c:18

c
void input_init()
{
    u8 i;
    kq_input_prev_keys = 0;
    kq_input_keys = 0;
    kq_input_press_keys = 0;
    kq_input_release_keys = 0;
    kq_input_repeat_keys = 0;
    i = 0;
    while (i < 8) {
        input_repeat_timer[i] = INPUT_REPEAT_DELAY;
        i++;
    }
}
input_pressed

Détecte un passage de relâché à appuyé pour un bouton du masque lors de la dernière mise à jour.

Syntaxe

c
u8 input_pressed(u8 mask);

Paramètres

mask

Un masque BTN_*, ou plusieurs combinés avec |. Un seul bouton correspondant suffit ; BTN_A | BTN_B n’exige pas les deux. Le masque 0 renvoie toujours 0. Pour vérifier que tous sont maintenus, comparez (input_current() & mask) == mask.

Valeur renvoyée

Renvoie exactement 1 si un bouton sélectionné remplit la condition, sinon 0. Le résultat n’est pas un masque de boutons.

Conditions et limites

Masques communs : BTN_RIGHT=0x01, BTN_LEFT=0x02, BTN_UP=0x04, BTN_DOWN=0x08, BTN_A=0x10, BTN_B=0x20, BTN_SELECT=0x40, BTN_START=0x80. Un bit à 1 indique un bouton maintenu. Ce format s’applique à input_* sur GB et FC ; les lectures brutes FC utilisent un autre ordre.

Les fonctions de consultation lisent le dernier input_update() sans relire le contrôleur, consommer d’événement ni avancer les compteurs. Plusieurs consultations dans un même cycle donnent le même résultat. Deux appels à input_update() avec un bouton maintenu effacent son événement de nouvel appui au second appel.

Exemple d’utilisation

c
if (input_pressed(BTN_A)!=0) {
        press_count++; seen_press=1;
        first_down=input_down(BTN_A); first_press=input_pressed(BTN_A);
        first_repeat=input_repeat(BTN_A);
        first_current=input_current(); // Only A held: BTN_A, or decimal 16.
        first_previous=input_previous(); // No buttons in the preceding sample: 0.
        if (first_down!=1 || first_press!=1 || first_repeat!=1) failures++;
        if (first_current!=BTN_A || first_previous!=0) failures++;
        if (input_down(BTN_A|BTN_B)!=1 || input_down(0)!=0) failures++;
    }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme distingue le maintien d’un bouton, un nouvel appui, le relâchement et la répétition automatique. Maintenez A pendant 40 mises à jour, puis relâchez-le. FIRST DOWN, FIRST PRESS et FIRST REPEAT valent 1 ; FIRST CURRENT vaut 16. HELD TICKS vaut 40, PRESS COUNT vaut 1 et REPEAT COUNT vaut 5. Au relâchement, RELEASE vaut 1, LAST CURRENT vaut 0 et LAST PREVIOUS vaut 16. FAILED CHECKS doit valoir 0. Une autre durée modifie les compteurs ; le programme vérifie les intervalles de répétition selon la durée réellement observée.

input_pressed: DMG
DMG
input_pressed: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\input.c .\kitaq-docs\samples\api-examples\gb\input_edges.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\input_edges.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm --no-cache
Implémentation et source

kitaqgb/lib/input.h:38

Notes de déclaration (texte source)
Return whether any masked button became pressed in the latest sample.

kitaqgb/lib/input.c:74

c
u8 input_pressed(u8 mask)
{
    return (u8)((kq_input_press_keys & mask) != 0);
}
input_previous

Renvoie le masque des boutons maintenus avant la dernière mise à jour.

Syntaxe

c
u8 input_previous();

Valeur renvoyée

Un masque de 8 bits au format commun BTN_*. Plusieurs boutons peuvent être présents simultanément ; 0 signifie aucun.

Conditions et limites

Masques communs : BTN_RIGHT=0x01, BTN_LEFT=0x02, BTN_UP=0x04, BTN_DOWN=0x08, BTN_A=0x10, BTN_B=0x20, BTN_SELECT=0x40, BTN_START=0x80. Un bit à 1 indique un bouton maintenu. Ce format s’applique à input_* sur GB et FC ; les lectures brutes FC utilisent un autre ordre.

Les fonctions de consultation lisent le dernier input_update() sans relire le contrôleur, consommer d’événement ni avancer les compteurs. Plusieurs consultations dans un même cycle donnent le même résultat. Deux appels à input_update() avec un bouton maintenu effacent son événement de nouvel appui au second appel.

Exemple d’utilisation

c
first_previous=input_previous(); // No buttons in the preceding sample: 0.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme distingue le maintien d’un bouton, un nouvel appui, le relâchement et la répétition automatique. Maintenez A pendant 40 mises à jour, puis relâchez-le. FIRST DOWN, FIRST PRESS et FIRST REPEAT valent 1 ; FIRST CURRENT vaut 16. HELD TICKS vaut 40, PRESS COUNT vaut 1 et REPEAT COUNT vaut 5. Au relâchement, RELEASE vaut 1, LAST CURRENT vaut 0 et LAST PREVIOUS vaut 16. FAILED CHECKS doit valoir 0. Une autre durée modifie les compteurs ; le programme vérifie les intervalles de répétition selon la durée réellement observée.

input_previous: DMG
DMG
input_previous: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\input.c .\kitaq-docs\samples\api-examples\gb\input_edges.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\input_edges.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm --no-cache
Implémentation et source

kitaqgb/lib/input.h:46

Notes de déclaration (texte source)
Return the held-button mask that preceded the latest update.

kitaqgb/lib/input.c:98

c
u8 input_previous()
{
    return kq_input_prev_keys;
}
input_released

Détecte un relâchement pour un bouton du masque lors de la dernière mise à jour.

Syntaxe

c
u8 input_released(u8 mask);

Paramètres

mask

Un masque BTN_*, ou plusieurs combinés avec |. Un seul bouton correspondant suffit ; BTN_A | BTN_B n’exige pas les deux. Le masque 0 renvoie toujours 0. Pour vérifier que tous sont maintenus, comparez (input_current() & mask) == mask.

Valeur renvoyée

Renvoie exactement 1 si un bouton sélectionné remplit la condition, sinon 0. Le résultat n’est pas un masque de boutons.

Conditions et limites

Masques communs : BTN_RIGHT=0x01, BTN_LEFT=0x02, BTN_UP=0x04, BTN_DOWN=0x08, BTN_A=0x10, BTN_B=0x20, BTN_SELECT=0x40, BTN_START=0x80. Un bit à 1 indique un bouton maintenu. Ce format s’applique à input_* sur GB et FC ; les lectures brutes FC utilisent un autre ordre.

Les fonctions de consultation lisent le dernier input_update() sans relire le contrôleur, consommer d’événement ni avancer les compteurs. Plusieurs consultations dans un même cycle donnent le même résultat. Deux appels à input_update() avec un bouton maintenu effacent son événement de nouvel appui au second appel.

Exemple d’utilisation

c
if (input_released(BTN_A)!=0) {
        release_result=input_released(BTN_A);
        last_current=input_current(); last_previous=input_previous();
        if (input_down(BTN_A)!=0 || input_pressed(BTN_A)!=0 || input_repeat(BTN_A)!=0) failures++;
        break;
    }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme distingue le maintien d’un bouton, un nouvel appui, le relâchement et la répétition automatique. Maintenez A pendant 40 mises à jour, puis relâchez-le. FIRST DOWN, FIRST PRESS et FIRST REPEAT valent 1 ; FIRST CURRENT vaut 16. HELD TICKS vaut 40, PRESS COUNT vaut 1 et REPEAT COUNT vaut 5. Au relâchement, RELEASE vaut 1, LAST CURRENT vaut 0 et LAST PREVIOUS vaut 16. FAILED CHECKS doit valoir 0. Une autre durée modifie les compteurs ; le programme vérifie les intervalles de répétition selon la durée réellement observée.

input_released: DMG
DMG
input_released: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\input.c .\kitaq-docs\samples\api-examples\gb\input_edges.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\input_edges.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm --no-cache
Implémentation et source

kitaqgb/lib/input.h:40

Notes de déclaration (texte source)
Return whether any masked button became released in the latest sample.

kitaqgb/lib/input.c:80

c
u8 input_released(u8 mask)
{
    return (u8)((kq_input_release_keys & mask) != 0);
}
input_repeat

Détecte un premier appui ou une impulsion de répétition pour un bouton du masque.

Syntaxe

c
u8 input_repeat(u8 mask);

Paramètres

mask

Un masque BTN_*, ou plusieurs combinés avec |. Un seul bouton correspondant suffit ; BTN_A | BTN_B n’exige pas les deux. Le masque 0 renvoie toujours 0. Pour vérifier que tous sont maintenus, comparez (input_current() & mask) == mask.

Valeur renvoyée

Renvoie exactement 1 si un bouton sélectionné remplit la condition, sinon 0. Le résultat n’est pas un masque de boutons.

Conditions et limites

Masques communs : BTN_RIGHT=0x01, BTN_LEFT=0x02, BTN_UP=0x04, BTN_DOWN=0x08, BTN_A=0x10, BTN_B=0x20, BTN_SELECT=0x40, BTN_START=0x80. Un bit à 1 indique un bouton maintenu. Ce format s’applique à input_* sur GB et FC ; les lectures brutes FC utilisent un autre ordre.

Les fonctions de consultation lisent le dernier input_update() sans relire le contrôleur, consommer d’événement ni avancer les compteurs. Plusieurs consultations dans un même cycle donnent le même résultat. Deux appels à input_update() avec un bouton maintenu effacent son événement de nouvel appui au second appel.

Les délais se comptent en mises à jour, pas en millisecondes. Un nouvel appui produit un événement immédiat. Avec INPUT_REPEAT_DELAY=18 et INPUT_REPEAT_RATE=5, le suivant arrive 19 mises à jour plus tard, puis tous les 6 appels. Chaque bouton a son compteur. Appliquez les mêmes macros lors de la compilation de input.c ; modifier seulement l’en-tête du code appelant ne reconfigure pas la bibliothèque.

Exemple d’utilisation

c
if (input_repeat(BTN_A)!=0) {
        // The initial press is pulse 1. Defaults then wait 19 updates, followed by 6.
        if (repeat_count==1 && held_ticks-previous_pulse!=19) failures++;
        if (repeat_count>1 && held_ticks-previous_pulse!=6) failures++;
        previous_pulse=held_ticks; repeat_count++;
        if (input_repeat(BTN_A)!=1) failures++; // Reading again does not consume it.
    }

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme distingue le maintien d’un bouton, un nouvel appui, le relâchement et la répétition automatique. Maintenez A pendant 40 mises à jour, puis relâchez-le. FIRST DOWN, FIRST PRESS et FIRST REPEAT valent 1 ; FIRST CURRENT vaut 16. HELD TICKS vaut 40, PRESS COUNT vaut 1 et REPEAT COUNT vaut 5. Au relâchement, RELEASE vaut 1, LAST CURRENT vaut 0 et LAST PREVIOUS vaut 16. FAILED CHECKS doit valoir 0. Une autre durée modifie les compteurs ; le programme vérifie les intervalles de répétition selon la durée réellement observée.

input_repeat: DMG
DMG
input_repeat: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\input.c .\kitaq-docs\samples\api-examples\gb\input_edges.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\input_edges.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm --no-cache
Implémentation et source

kitaqgb/lib/input.h:42

Notes de déclaration (texte source)
Return whether any masked button produced a fresh press or scheduled repeat pulse.

kitaqgb/lib/input.c:86

c
u8 input_repeat(u8 mask)
{
    return (u8)((kq_input_repeat_keys & mask) != 0);
}
input_update

Mémorise le masque courant comme état précédent, lit les boutons du Game Boy avec __readpadex, calcule les relâchements et avance un compteur indépendant par bouton. Appelez-la une fois par cycle d’entrée avant de consulter l’état mémorisé.

Syntaxe

c
void input_update();

Valeur renvoyée

Aucune (void).

Conditions et limites

Masques communs : BTN_RIGHT=0x01, BTN_LEFT=0x02, BTN_UP=0x04, BTN_DOWN=0x08, BTN_A=0x10, BTN_B=0x20, BTN_SELECT=0x40, BTN_START=0x80. Un bit à 1 indique un bouton maintenu. Ce format s’applique à input_* sur GB et FC ; les lectures brutes FC utilisent un autre ordre.

Les délais se comptent en mises à jour, pas en millisecondes. Un nouvel appui produit un événement immédiat. Avec INPUT_REPEAT_DELAY=18 et INPUT_REPEAT_RATE=5, le suivant arrive 19 mises à jour plus tard, puis tous les 6 appels. Chaque bouton a son compteur. Appliquez les mêmes macros lors de la compilation de input.c ; modifier seulement l’en-tête du code appelant ne reconfigure pas la bibliothèque.

Exemple d’utilisation

c
input_update(); // One update per input tick, followed by any number of queries.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Ce programme distingue le maintien d’un bouton, un nouvel appui, le relâchement et la répétition automatique. Maintenez A pendant 40 mises à jour, puis relâchez-le. FIRST DOWN, FIRST PRESS et FIRST REPEAT valent 1 ; FIRST CURRENT vaut 16. HELD TICKS vaut 40, PRESS COUNT vaut 1 et REPEAT COUNT vaut 5. Au relâchement, RELEASE vaut 1, LAST CURRENT vaut 0 et LAST PREVIOUS vaut 16. FAILED CHECKS doit valoir 0. Une autre durée modifie les compteurs ; le programme vérifie les intervalles de répétition selon la durée réellement observée.

input_update: DMG
DMG
input_update: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\input.c .\kitaq-docs\samples\api-examples\gb\input_edges.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\input_edges.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-disasm --no-cache
Implémentation et source

kitaqgb/lib/input.h:34

Notes de déclaration (texte source)
Sample input once per game tick and derive press, release and repeat masks.
Repeat delays are measured in calls to this function, not elapsed wall-clock time.

kitaqgb/lib/input.c:35

c
void input_update()
{
    u8 i;
    u16 kt;

    kq_input_prev_keys = kq_input_keys;
    // The intrinsic packs held buttons in the low byte and new presses in the high byte.
    kt = __readpadex(kq_input_prev_keys);
    kq_input_keys = (u8)kt;
    kq_input_press_keys = (u8)(kt >> 8);
    kq_input_release_keys = (u8)(kq_input_prev_keys & (u8)(kq_input_keys ^ 0xFF));
    kq_input_repeat_keys = kq_input_press_keys;

    i = 0;
    while (i < 8) {
        u8 mask = input_mask_for_index(i);
        if ((kq_input_keys & mask) != 0) {
            if ((kq_input_press_keys & mask) != 0) {
                input_repeat_timer[i] = INPUT_REPEAT_DELAY;
            } else if (input_repeat_timer[i] != 0) {
                input_repeat_timer[i]--;
            } else {
                kq_input_repeat_keys = (u8)(kq_input_repeat_keys | mask);
                input_repeat_timer[i] = INPUT_REPEAT_RATE;
            }
        } else {
            input_repeat_timer[i] = INPUT_REPEAT_DELAY;
        }
        i++;
    }
}

La bibliothèque propose trois niveaux : échanges d’octets, paquets jusqu’à 24 octets et files par correspondant. Commencez par BYTE MASTER/SLAVE, puis PACKET, puis LINK4 pour comprendre la source d’horloge et la disponibilité des données reçues. Incluez exactement une fois dans le programme l’unité des registres matériels, link.c et link_packet.c ; gb_link_example.h fournit cet ordre.

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Continuez à interroger les deux extrémités. Le délai expire après 90 appels sans progression, pas après un nombre d’images matérielles. Envoyer 0xFF uniquement pour fournir l’horloge d’un ACK ne repousse pas cette échéance ; au plus trois tentatives sont permises. Les retransmissions peuvent livrer des doublons : ajoutez des identifiants applicatifs si une commande doit s’exécuter exactement une fois.

Link4_BeginTransferTo

Sélectionne une destination, puis démarre un échange d’octet.

Syntaxe

c
u8 __stackcall Link4_BeginTransferTo(u8 peer_slot, u8 out);

Paramètres

peer_slot

Emplacement distant configuré : de 1 à slot_count−1 depuis l’hôte, ou 0 depuis un correspondant.

out

Valeur sortante sur huit bits.

Valeur renvoyée

Renvoie la première erreur de sélection ou de démarrage, ou 0 en cas de succès.

Conditions et limites

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Codes d’erreur : 0=aucune, 1=occupé, 2=expiration du délai, 3=débordement en réception, 4=configuration/protocole invalide, 5=expiration ACK avec une réponse évoquant une déconnexion. Les appels de démarrage/configuration réussissent avec 0 ; ceux de réception/extraction avec 1. Un appel réussi n’efface pas une erreur mémorisée.

Link4 copie chaque octet reçu dans le tampon général et dans un tampon propre au correspondant. Lire l’un ne vide pas l’autre. L’interrogation des paquets consomme le tampon général ; éliminez aussi régulièrement les octets bruts inutilisés des tampons par correspondant pour éviter un débordement.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[6+slot]=Link4_BeginTransferTo(slot,16+slot);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_BeginTransferTo: DMG
DMG
Link4_BeginTransferTo: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:129

Notes de déclaration (texte source)
Select the logical peer and start a byte exchange, returning the first error.

kitaqgb/lib/link.c:584

c
u8 __stackcall Link4_BeginTransferTo(u8 peer_slot, u8 out) {
    u8 err = Link4_SelectPeer(peer_slot);
    if (err != LINK_ERR_NONE) return err;
    return Link_BeginTransfer(out);
}
Link4_GetLastRxPeer

Lit le correspondant attribué au dernier octet reçu complètement.

Syntaxe

c
u8 Link4_GetLastRxPeer();

Valeur renvoyée

L’hôte renvoie le correspondant sélectionné et un correspondant renvoie 0 ; avant toute réception, renvoie 255.

Conditions et limites

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Ces fonctions lisent la configuration et l’historique. Elles ne détectent pas les connexions physiques, n’interrogent pas tous les correspondants et n’attendent pas la fin des transferts.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[19]=Link4_GetLastRxPeer();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_GetLastRxPeer: DMG
DMG
Link4_GetLastRxPeer: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:121

Notes de déclaration (texte source)
Return the peer attributed to the last completed byte transfer.

kitaqgb/lib/link.c:540

c
u8 Link4_GetLastRxPeer() {
    return Link4_LastRxPeer;
}
Link4_GetLastTxPeer

Lit la destination mémorisée au début du dernier transfert d’octet.

Syntaxe

c
u8 Link4_GetLastTxPeer();

Valeur renvoyée

Renvoie la destination mémorisée, ou 255 avant tout démarrage.

Conditions et limites

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Ces fonctions lisent la configuration et l’historique. Elles ne détectent pas les connexions physiques, n’interrogent pas tous les correspondants et n’attendent pas la fin des transferts.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[20]=Link4_GetLastTxPeer();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_GetLastTxPeer: DMG
DMG
Link4_GetLastTxPeer: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:123

Notes de déclaration (texte source)
Return the peer attributed when the last byte transfer was started.

kitaqgb/lib/link.c:545

c
u8 Link4_GetLastTxPeer() {
    return Link4_LastTxPeer;
}
Link4_GetLocalSlot

Lit l’emplacement configuré de cette machine.

Syntaxe

c
u8 Link4_GetLocalSlot();

Valeur renvoyée

L’hôte vaut 0, les correspondants 1 à 3. L’état non configuré renvoie aussi 0.

Conditions et limites

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Ces fonctions lisent la configuration et l’historique. Elles ne détectent pas les connexions physiques, n’interrogent pas tous les correspondants et n’attendent pas la fin des transferts.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[2]=Link4_GetLocalSlot();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_GetLocalSlot: DMG
DMG
Link4_GetLocalSlot: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:115

Notes de déclaration (texte source)
Return the configured zero-based local slot.

kitaqgb/lib/link.c:525

c
u8 Link4_GetLocalSlot() {
    return Link4_LocalSlot;
}
Link4_GetMode

Lit le rôle logique configuré.

Syntaxe

c
u8 Link4_GetMode();

Valeur renvoyée

0=non configuré, 1=hôte, 2=correspondant.

Conditions et limites

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Ces fonctions lisent la configuration et l’historique. Elles ne détectent pas les connexions physiques, n’interrogent pas tous les correspondants et n’attendent pas la fin des transferts.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[1]=Link4_GetMode();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_GetMode: DMG
DMG
Link4_GetMode: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:113

Notes de déclaration (texte source)
Return the configured cooperative role; this is not a hardware connection probe.

kitaqgb/lib/link.c:520

c
u8 Link4_GetMode() {
    return Link4_ModeState;
}
Link4_GetSelectedPeer

Lit la destination logique actuellement sélectionnée.

Syntaxe

c
u8 Link4_GetSelectedPeer();

Valeur renvoyée

L’hôte renvoie le correspondant sélectionné ; un correspondant renvoie 0 ; non configuré renvoie 255.

Conditions et limites

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Ces fonctions lisent la configuration et l’historique. Elles ne détectent pas les connexions physiques, n’interrogent pas tous les correspondants et n’attendent pas la fin des transferts.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[4]=Link4_GetSelectedPeer();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_GetSelectedPeer: DMG
DMG
Link4_GetSelectedPeer: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:119

Notes de déclaration (texte source)
Return the current logical destination, or the invalid-slot sentinel when unset.

kitaqgb/lib/link.c:535

c
u8 Link4_GetSelectedPeer() {
    return Link4_SelectedPeer;
}
Link4_GetSlotCount

Lit le nombre total d’emplacements configuré.

Syntaxe

c
u8 Link4_GetSlotCount();

Valeur renvoyée

Une configuration valide renvoie 2 à 4 ; non configuré renvoie 0.

Conditions et limites

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Ces fonctions lisent la configuration et l’historique. Elles ne détectent pas les connexions physiques, n’interrogent pas tous les correspondants et n’attendent pas la fin des transferts.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[3]=Link4_GetSlotCount();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_GetSlotCount: DMG
DMG
Link4_GetSlotCount: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:117

Notes de déclaration (texte source)
Return the configured number of logical slots, not a live connection count.

kitaqgb/lib/link.c:530

c
u8 Link4_GetSlotCount() {
    return Link4_SlotCount;
}
Link4_HasByteFrom

Vérifie les données non lues du tampon de réception d’un correspondant.

Syntaxe

c
u8 __stackcall Link4_HasByteFrom(u8 peer_slot);

Paramètres

peer_slot

Emplacement distant configuré : de 1 à slot_count−1 depuis l’hôte, ou 0 depuis un correspondant.

Valeur renvoyée

Renvoie 1 si des données sont en file, 0 si vide ou si le correspondant est invalide.

Conditions et limites

Le tampon circulaire de réception de huit entrées contient sept octets utiles. S’il est plein, le nouvel octet est abandonné et l’erreur 3 est mémorisée. Un octet reçu de valeur zéro est une donnée valide.

Link4 copie chaque octet reçu dans le tampon général et dans un tampon propre au correspondant. Lire l’un ne vide pas l’autre. L’interrogation des paquets consomme le tampon général ; éliminez aussi régulièrement les octets bruts inutilisés des tampons par correspondant pour éviter un débordement.

Cette requête n’interroge pas le matériel ; un correspondant invalide ne modifie pas l’erreur mémorisée.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[9+slot]=Link4_HasByteFrom(slot);value=0;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_HasByteFrom: DMG
DMG
Link4_HasByteFrom: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:131

Notes de déclaration (texte source)
Inspect a valid peer ring without polling the hardware.

kitaqgb/lib/link.c:591

c
u8 __stackcall Link4_HasByteFrom(u8 peer_slot) {
    if (Link4_IsValidRemoteSlotInternal(peer_slot) == 0) return 0;
    if (Link4_RxHead[(__safe_index u8)peer_slot] == Link4_RxTail[(__safe_index u8)peer_slot]) return 0;
    return 1;
}
Link4_HasPacketFrom

Consulte la boîte des paquets terminés d’un emplacement distant.

Syntaxe

c
u8 __stackcall Link4_HasPacketFrom(u8 peer_slot);

Paramètres

peer_slot

Emplacement distant configuré : de 1 à slot_count−1 depuis l’hôte, ou 0 depuis un correspondant.

Valeur renvoyée

Renvoie 1 pour un paquet non lu, 0 si vide ou si le correspondant est invalide.

Conditions et limites

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Un paquet contient 0xA5, la commande, la longueur, 0 à 24 octets utiles et une somme de contrôle XOR. La réponse est 0x79 (ACK, accepté) ou 0x1F (NAK, refusé). Le contrôle combine par XOR la commande, la longueur et les données utiles. Chaque machine possède une boîte de réception de paquets partagée ; Link4 en ajoute une par correspondant.

Cette requête n’interroge pas le matériel ; un correspondant invalide ne modifie pas l’erreur mémorisée.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[9]=Link4_HasPacketFrom(0);result[10]=Link4_ReadPacketFrom(0,&cmd,&len,data);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Pour le correspondant 1 parmi quatre emplacements, les valeurs attendues sont HOST BYTE=17, COMMAND=65, LENGTH=3 et PAYLOAD 2=42. CONSUMED=0 est l’indicateur de la boîte de l’hôte après consommation.

Link4_HasPacketFrom: DMG
DMG
Link4_HasPacketFrom: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:142

Notes de déclaration (texte source)
Inspect the one-packet mailbox for a valid remote slot without consuming it.

kitaqgb/lib/link_packet.c:484

c
u8 __stackcall Link4_HasPacketFrom(u8 peer_slot) {
    return Link4_PacketPeerReady(peer_slot);
}
Link4_InitHost

Initialise un hôte logique de deux à quatre emplacements et sélectionne le correspondant 1.

Syntaxe

c
u8 __stackcall Link4_InitHost(u8 slot_count);

Paramètres

slot_count

Nombre d’emplacements, hôte compris, de 2 à 4.

Valeur renvoyée

Renvoie 0 pour une configuration valide, 4 pour un nombre d’emplacements invalide.

Conditions et limites

L’initialisation supprime les files d’octets, les paquets, la sélection du correspondant et les erreurs, puis désactive le transfert et la source IRQ série. Un échange en cours n’est pas conservé.

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Les sections critiques internes suivent leur profondeur d’imbrication logicielle. Sortir de la section la plus externe active les interruptions CPU ; ne supposez donc pas qu’un état IME précédemment désactivé sera conservé.

L’initialisation précède la validation. Même un appel échoué supprime l’ancienne topologie et les données non lues.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[0]=Link4_InitHost(4);result[1]=Link4_GetMode();result[2]=Link4_GetLocalSlot();result[3]=Link4_GetSlotCount();result[4]=Link4_GetSelectedPeer();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_InitHost: DMG
DMG
Link4_InitHost: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:108

Notes de déclaration (texte source)
Cooperative 4-player adapter helpers.

This layer models the common host-selected adapter pattern:
- Slot 0 is always the host.
- The host selects one active peer slot at a time.
- Packet mailboxes stay one-deep per peer.
- The original Link_* API remains available for normal 2-player projects.
Reset as master, validate slot count and select logical peer one. Invalid configuration still discards old link state.

kitaqgb/lib/link.c:489

c
u8 __stackcall Link4_InitHost(u8 slot_count) {
    u8 err;

    Link_InitMaster();
    err = Link4_ValidateConfig(LINK4_MODE_HOST, LINK4_HOST_SLOT, slot_count);
    if (err != LINK_ERR_NONE) {
        Link_SetErrorInternal(err);
        return err;
    }

    Link4_ApplyConfig(LINK4_MODE_HOST, LINK4_HOST_SLOT, slot_count);
    return LINK_ERR_NONE;
}
Link4_InitPeer

Initialise un correspondant à horloge externe et sélectionne l’emplacement hôte 0.

Syntaxe

c
u8 __stackcall Link4_InitPeer(u8 local_slot, u8 slot_count);

Paramètres

local_slot

Emplacement local, de 1 à slot_count−1.

slot_count

Nombre total d’emplacements, hôte compris, de 2 à 4.

Valeur renvoyée

Renvoie 0 pour une configuration valide, 4 pour un nombre d’emplacements ou un emplacement local invalide.

Conditions et limites

L’initialisation supprime les files d’octets, les paquets, la sélection du correspondant et les erreurs, puis désactive le transfert et la source IRQ série. Un échange en cours n’est pas conservé.

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Les sections critiques internes suivent leur profondeur d’imbrication logicielle. Sortir de la section la plus externe active les interruptions CPU ; ne supposez donc pas qu’un état IME précédemment désactivé sera conservé.

L’initialisation précède la validation. Même un appel échoué supprime l’ancienne topologie et les données non lues.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[0]=Link4_InitPeer(1,4);result[1]=Link4_GetMode();result[2]=Link4_GetLocalSlot();result[3]=Link4_GetSlotCount();result[4]=Link4_GetSelectedPeer();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Pour le correspondant 1 parmi quatre emplacements, les valeurs attendues sont HOST BYTE=17, COMMAND=65, LENGTH=3 et PAYLOAD 2=42. CONSUMED=0 est l’indicateur de la boîte de l’hôte après consommation.

Link4_InitPeer: DMG
DMG
Link4_InitPeer: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:111

Notes de déclaration (texte source)
Reset as slave and validate the local nonzero slot and total slot count.
An invalid configuration still discards the previous link state.

kitaqgb/lib/link.c:505

c
u8 __stackcall Link4_InitPeer(u8 local_slot, u8 slot_count) {
    u8 err;

    Link_InitSlave();
    err = Link4_ValidateConfig(LINK4_MODE_PEER, local_slot, slot_count);
    if (err != LINK_ERR_NONE) {
        Link_SetErrorInternal(err);
        return err;
    }

    Link4_ApplyConfig(LINK4_MODE_PEER, local_slot, slot_count);
    return LINK_ERR_NONE;
}
Link4_PollPacket

Fait avancer une fois le moteur de paquets partagé pour le correspondant sélectionné.

Syntaxe

c
void Link4_PollPacket();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Un paquet contient 0xA5, la commande, la longueur, 0 à 24 octets utiles et une somme de contrôle XOR. La réponse est 0x79 (ACK, accepté) ou 0x1F (NAK, refusé). Le contrôle combine par XOR la commande, la longueur et les données utiles. Chaque machine possède une boîte de réception de paquets partagée ; Link4 en ajoute une par correspondant.

Continuez à interroger les deux extrémités. Le délai expire après 90 appels sans progression, pas après un nombre d’images matérielles. Envoyer 0xFF uniquement pour fournir l’horloge d’un ACK ne repousse pas cette échéance ; au plus trois tentatives sont permises. Les retransmissions peuvent livrer des doublons : ajoutez des identifiants applicatifs si une commande doit s’exécuter exactement une fois.

Link4 copie chaque octet reçu dans le tampon général et dans un tampon propre au correspondant. Lire l’un ne vide pas l’autre. L’interrogation des paquets consomme le tampon général ; éliminez aussi régulièrement les octets bruts inutilisés des tampons par correspondant pour éviter un débordement.

Ne parcourt pas tous les emplacements en rotation. Ne changez de correspondant qu’après la fin de l’échange, lorsque la sélection est autorisée.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
for(i=0;i<50;i++){Link4_PollPacket();while(Link4_TryReadByteFrom(slot,0)){}m_wait();}

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_PollPacket: DMG
DMG
Link4_PollPacket: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:140

Notes de déclaration (texte source)
Advance the shared packet engine; this does not poll every logical peer in turn.

kitaqgb/lib/link_packet.c:479

c
void Link4_PollPacket() {
    Link_PollPacket();
}
Link4_ReadPacketFrom

Copie un paquet du correspondant indiqué et le retire de sa boîte.

Syntaxe

c
u8 __stackcall Link4_ReadPacketFrom(u8 peer_slot, u8 *cmd, u8 *len, u8 *dst);

Paramètres

peer_slot

Emplacement distant configuré : de 1 à slot_count−1 depuis l’hôte, ou 0 depuis un correspondant.

cmd

Octet de commande inscriptible ; null omet cette sortie.

len

Octet de longueur inscriptible, de 0 à 24 ; null omet cette sortie.

dst

Tampon de données utiles inscriptible d’au moins 24 octets ; null abandonne les données utiles.

Valeur renvoyée

Renvoie 1 si consommé, 0 si vide ou si le correspondant est invalide.

Conditions et limites

Il n’y a pas de paramètre de capacité de destination. Fournissez 24 octets inscriptibles si vous utilisez dst. cmd, len et dst peuvent être nuls indépendamment. Sérialisez l’inspection et la consommation de la boîte de réception par rapport aux autres codes et aux interruptions.

Vide la boîte partagée uniquement si elle désigne le paquet de ce même correspondant. Les paquets non lus des autres correspondants restent disponibles.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[9]=Link4_HasPacketFrom(0);result[10]=Link4_ReadPacketFrom(0,&cmd,&len,data);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Pour le correspondant 1 parmi quatre emplacements, les valeurs attendues sont HOST BYTE=17, COMMAND=65, LENGTH=3 et PAYLOAD 2=42. CONSUMED=0 est l’indicateur de la boîte de l’hôte après consommation.

Link4_ReadPacketFrom: DMG
DMG
Link4_ReadPacketFrom: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:146

Notes de déclaration (texte source)
Consume a peer mailbox, copying to optional outputs. A nonnull destination
needs room for the entire payload. Clear the shared mailbox only when it
refers to this same peer.

kitaqgb/lib/link_packet.c:491

c
u8 __stackcall Link4_ReadPacketFrom(u8 peer_slot, u8 *cmd, u8 *len, u8 *dst) {
    u8 i;
    u8 offset;

    if (Link4_PacketPeerReady(peer_slot) == 0) return 0;

    if (cmd != 0) *cmd = Link4_ReceivedPacketCmd[(__safe_index u8)peer_slot];
    if (len != 0) *len = Link4_ReceivedPacketLen[(__safe_index u8)peer_slot];

    if (dst != 0) {
        for (i = 0; i < Link4_ReceivedPacketLen[(__safe_index u8)peer_slot]; ++i) {
            offset = Link4_PacketOffset(peer_slot, i);
            dst[(__safe_index u8)i] = Link4_ReceivedPacketBuf[(__safe_index u8)offset];
        }
    }

    Link4_ReceivedPacketReady[(__safe_index u8)peer_slot] = 0;
    if (Link4_LastPacketPeer == peer_slot) {
        Link_ReceivedPacketReady = 0;
        Link4_LastPacketPeer = LINK4_INVALID_SLOT;
    }
    return 1;
}
Link4_SelectPeer

Interroge la fin du transfert et ne change la destination logique qu’à l’état inactif.

Syntaxe

c
u8 __stackcall Link4_SelectPeer(u8 peer_slot);

Paramètres

peer_slot

Emplacement distant configuré : de 1 à slot_count−1 depuis l’hôte, ou 0 depuis un correspondant.

Valeur renvoyée

Renvoie 0 après sélection, 1 si l’état octet/paquet/ACK est occupé, ou 4 si non configuré ou si le correspondant est invalide.

Conditions et limites

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Codes d’erreur : 0=aucune, 1=occupé, 2=expiration du délai, 3=débordement en réception, 4=configuration/protocole invalide, 5=expiration ACK avec une réponse évoquant une déconnexion. Les appels de démarrage/configuration réussissent avec 0 ; ceux de réception/extraction avec 1. Un appel réussi n’efface pas une erreur mémorisée.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[25]=Link4_SelectPeer(1);result[26]=Link_LastError();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_SelectPeer: DMG
DMG
Link4_SelectPeer: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:127

Notes de déclaration (texte source)
Poll completion, then change the logical destination only while byte and
packet state are idle. A peer can select only the host. No adapter-routing
command is sent here; the transport must provide the matching physical route.

kitaqgb/lib/link.c:552

c
u8 __stackcall Link4_SelectPeer(u8 peer_slot) {
    Link_Poll();

    if (Link4_IsEnabledInternal() == 0) {
        Link_SetErrorInternal(LINK_ERR_PROTOCOL);
        return LINK_ERR_PROTOCOL;
    }

    if (Link_Busy != 0 || Link_PacketState != LINK_PKT_STATE_IDLE || Link_PendingAck != 0) {
        Link_SetErrorInternal(LINK_ERR_BUSY);
        return LINK_ERR_BUSY;
    }

    if (Link4_ModeState == LINK4_MODE_HOST) {
        if (Link4_IsValidRemoteSlotInternal(peer_slot) == 0) {
            Link_SetErrorInternal(LINK_ERR_PROTOCOL);
            return LINK_ERR_PROTOCOL;
        }
        Link4_SelectedPeer = peer_slot;
        return LINK_ERR_NONE;
    }

    if (Link4_ModeState == LINK4_MODE_PEER && peer_slot == LINK4_HOST_SLOT) {
        Link4_SelectedPeer = LINK4_HOST_SLOT;
        return LINK_ERR_NONE;
    }

    Link_SetErrorInternal(LINK_ERR_PROTOCOL);
    return LINK_ERR_PROTOCOL;
}
Link4_SendPacketTo

Sélectionne un correspondant logique, copie le paquet et programme son envoi.

Syntaxe

c
u8 __stackcall Link4_SendPacketTo(u8 peer_slot, const u8 *data, u8 len, u8 cmd);

Paramètres

peer_slot

Emplacement distant configuré : de 1 à slot_count−1 depuis l’hôte, ou 0 depuis un correspondant.

data

Source lisible sur len octets ; peut être nulle uniquement si len vaut zéro.

len

Longueur des données utiles en octets, de 0 à 24.

cmd

Commande sur huit bits définie par l’application.

Valeur renvoyée

Renvoie la première erreur de sélection ou de mise en file ; 0 signifie accepté.

Conditions et limites

Link4 gère l’emplacement logique hôte 0 et les correspondants 1 à 3. SelectPeer n’envoie aucune commande modifiant le câblage physique. La topologie link4 de KOKURA suit le correspondant sélectionné via les métadonnées du compilateur. Utilisez LinkDmg07 pour le protocole de l’adaptateur physique DMG-07.

Codes d’erreur : 0=aucune, 1=occupé, 2=expiration du délai, 3=débordement en réception, 4=configuration/protocole invalide, 5=expiration ACK avec une réponse évoquant une déconnexion. Les appels de démarrage/configuration réussissent avec 0 ; ceux de réception/extraction avec 1. Un appel réussi n’efface pas une erreur mémorisée.

Un paquet contient 0xA5, la commande, la longueur, 0 à 24 octets utiles et une somme de contrôle XOR. La réponse est 0x79 (ACK, accepté) ou 0x1F (NAK, refusé). Le contrôle combine par XOR la commande, la longueur et les données utiles. Chaque machine possède une boîte de réception de paquets partagée ; Link4 en ajoute une par correspondant.

Continuez à interroger les deux extrémités. Le délai expire après 90 appels sans progression, pas après un nombre d’images matérielles. Envoyer 0xFF uniquement pour fournir l’horloge d’un ACK ne repousse pas cette échéance ; au plus trois tentatives sont permises. Les retransmissions peuvent livrer des doublons : ajoutez des identifiants applicatifs si une commande doit s’exécuter exactement une fois.

Link4 copie chaque octet reçu dans le tampon général et dans un tampon propre au correspondant. Lire l’un ne vide pas l’autre. L’interrogation des paquets consomme le tampon général ; éliminez aussi régulièrement les octets bruts inutilisés des tampons par correspondant pour éviter un débordement.

La sélection précède la validation des données utiles ; même si elles sont refusées, la nouvelle destination peut rester sélectionnée.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[21+slot]=Link4_SendPacketTo(slot,data,3,64+slot);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_SendPacketTo: DMG
DMG
Link4_SendPacketTo: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:138

Notes de déclaration (texte source)
Select a logical peer, then copy and schedule a packet; return the first error.

kitaqgb/lib/link_packet.c:472

c
u8 __stackcall Link4_SendPacketTo(u8 peer_slot, const u8 *data, u8 len, u8 cmd) {
    u8 err = Link4_SelectPeer(peer_slot);
    if (err != LINK_ERR_NONE) return err;
    return Link_SendPacket(data, len, cmd);
}
Link4_TryReadByteAny

Parcourt les emplacements distants par ordre croissant et extrait le premier octet disponible.

Syntaxe

c
u8 __stackcall Link4_TryReadByteAny(u8 *peer_slot, u8 *out);

Paramètres

peer_slot

Octet inscriptible pour l’emplacement d’origine ; null omet cette sortie.

out

Destination d’un octet inscriptible ; null abandonne l’octet.

Valeur renvoyée

Renvoie 1 à la réception, sinon 0.

Conditions et limites

Le tampon circulaire de réception de huit entrées contient sept octets utiles. S’il est plein, le nouvel octet est abandonné et l’erreur 3 est mémorisée. Un octet reçu de valeur zéro est une donnée valide.

Link4 copie chaque octet reçu dans le tampon général et dans un tampon propre au correspondant. Lire l’un ne vide pas l’autre. L’interrogation des paquets consomme le tampon général ; éliminez aussi régulièrement les octets bruts inutilisés des tampons par correspondant pour éviter un débordement.

Les sections critiques internes suivent leur profondeur d’imbrication logicielle. Sortir de la section la plus externe active les interruptions CPU ; ne supposez donc pas qu’un état IME précédemment désactivé sera conservé.

Ignore l’emplacement local. Les emplacements de numéro inférieur continuellement alimentés sont prioritaires ; utilisez les lectures par correspondant si un partage équitable en rotation est nécessaire.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
else {other=255;Link4_TryReadByteAny(&other,&value);result[12+slot]=other;}

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_TryReadByteAny: DMG
DMG
Link4_TryReadByteAny: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:136

Notes de déclaration (texte source)
Scan remote rings in increasing slot order and return the first available
byte. Null output pointers are allowed; lower slots have polling priority.

kitaqgb/lib/link.c:604

c
u8 __stackcall Link4_TryReadByteAny(u8 *peer_slot, u8 *out) {
    u8 slot;

    if (Link4_IsEnabledInternal() == 0) return 0;

    for (slot = 0; slot < Link4_SlotCount; ++slot) {
        if (slot != Link4_LocalSlot) {
            if (Link4_PopRxByte(slot, out) != 0) {
                if (peer_slot != 0) *peer_slot = slot;
                return 1;
            }
        }
    }

    return 0;
}
Link4_TryReadByteFrom

Extrait un octet du tampon de réception du correspondant indiqué.

Syntaxe

c
u8 __stackcall Link4_TryReadByteFrom(u8 peer_slot, u8 *out);

Paramètres

peer_slot

Emplacement distant configuré : de 1 à slot_count−1 depuis l’hôte, ou 0 depuis un correspondant.

out

Destination d’un octet inscriptible ; null abandonne l’octet.

Valeur renvoyée

Renvoie 1 après extraction ; si vide ou si le correspondant est invalide, renvoie 0 et conserve out.

Conditions et limites

Le tampon circulaire de réception de huit entrées contient sept octets utiles. S’il est plein, le nouvel octet est abandonné et l’erreur 3 est mémorisée. Un octet reçu de valeur zéro est une donnée valide.

Link4 copie chaque octet reçu dans le tampon général et dans un tampon propre au correspondant. Lire l’un ne vide pas l’autre. L’interrogation des paquets consomme le tampon général ; éliminez aussi régulièrement les octets bruts inutilisés des tampons par correspondant pour éviter un débordement.

Les sections critiques internes suivent leur profondeur d’imbrication logicielle. Sortir de la section la plus externe active les interruptions CPU ; ne supposez donc pas qu’un état IME précédemment désactivé sera conservé.

Les écrans proviennent de KOKURA. Les exemples à plusieurs extrémités vérifient les valeurs d’instances d’émulateur reliées ; les captures proviennent de leurs états finaux sauvegardés. Ces vérifications ne prouvent pas le comportement d’un câble physique ou d’un adaptateur à quatre joueurs.

Exécutez ces commandes PowerShell depuis le dossier parent contenant kitaqgb, kokura et kitaq-docs. Compilez toutes les ROM participantes avant de lancer la session reliée. Pour Link4, conservez les métadonnées de symboles générées à côté des ROM. Pour les exécutions DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
if(slot==1)result[13]=Link4_TryReadByteFrom(slot,&value);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Reliez les quatre ROM avec la topologie link4 de KOKURA. L’hôte reçoit 161/162/163 des correspondants 1/2/3 et affiche LAST PEER=3. Il envoie ensuite les commandes 65/66/67 avec les données 7/42/255 ; vérifiez aussi ces valeurs sur l’écran de chaque correspondant.

Link4_TryReadByteFrom: DMG
DMG
Link4_TryReadByteFrom: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_host.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_host.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer1.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer1.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer2.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\link_four_peer3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\link_four_peer3.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology link4 --run-frames 360 --link-session "name=four_host|slot=0|rom=.\out\link_four_host.gb|save_state=.\out\four_host.kqs" --link-session "name=four_peer1|slot=1|rom=.\out\link_four_peer1.gb|save_state=.\out\four_peer1.kqs" --link-session "name=four_peer2|slot=2|rom=.\out\link_four_peer2.gb|save_state=.\out\four_peer2.kqs" --link-session "name=four_peer3|slot=3|rom=.\out\link_four_peer3.gb|save_state=.\out\four_peer3.kqs"
.\kokura\kokura-cli.exe .\out\link_four_host.gb --hardware cgb --load-state .\out\four_host.kqs --run-frames 2 --png .\out\four_host.png
.\kokura\kokura-cli.exe .\out\link_four_peer1.gb --hardware cgb --load-state .\out\four_peer1.kqs --run-frames 2 --png .\out\four_peer1.png
.\kokura\kokura-cli.exe .\out\link_four_peer2.gb --hardware cgb --load-state .\out\four_peer2.kqs --run-frames 2 --png .\out\four_peer2.png
.\kokura\kokura-cli.exe .\out\link_four_peer3.gb --hardware cgb --load-state .\out\four_peer3.kqs --run-frames 2 --png .\out\four_peer3.png
Implémentation et source

kitaqgb/lib/link.h:133

Notes de déclaration (texte source)
Pop one byte from the selected peer ring; null output discards it.

kitaqgb/lib/link.c:598

c
u8 __stackcall Link4_TryReadByteFrom(u8 peer_slot, u8 *out) {
    return Link4_PopRxByte(peer_slot, out);
}

Le DMG-07 diffuse l’octet de chaque console aux quatre joueurs. Cette bibliothèque gère découverte, démarrage par le joueur 1, diffusions retardées et contrôle de redémarrage aligné. Découvrez l’échange à quatre avec EXCHANGE, les expirations avec NO ADAPTER, les données non lues avec OVERFLOW et la reprise avec RESTART.

Les joueurs de la bibliothèque sont numérotés 1..4 ; zéro signifie non découvert. Les bits 0..3 du masque de connexion correspondent aux joueurs 1..4. Les slots KOKURA --link-session vont de 0 à 3, convention distincte de l’API ROM.

Ce pilote possède le port série. N’exécutez pas Link ordinaire ou Link4 simultanément ; incluez link_hwregs_gb.c et link_dmg07.c une fois chacun. L’adaptateur fournit les horloges externes ; le pilote ne sélectionne pas le mode série rapide CGB.

Appelez Poll de façon répétée pendant toute la trame et TickFrame exactement une fois par trame. Un Poll par VBlank ne peut pas réarmer le port entre les octets de l’adaptateur. Le d_poll de l’en-tête partagé détecte l’entrée dans LY >= 144 pour appeler TickFrame une fois. Sérialisez les deux opérations au lieu de faire rivaliser ISR et boucle principale.

Avec SIZE=1, chaque console soumet un octet ; la diffusion de quatre octets suit l’ordre des joueurs 1..4. La première diffusion est jetée. Les suivantes contiennent les contributions du paquet précédent. Quatre octets 0xFF sont réservés à l’indication de redémarrage.

LinkDmg07_ClearError

Remet le dernier code d’erreur à zéro.

Syntaxe

c
void LinkDmg07_ClearError();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

SilenceFrames et les compteurs de diagnostic saturent à 255. Init les réinitialise tous ; les redémarrages ordinaires du protocole préservent les diagnostics. ClearError n’efface que le code d’erreur.

Préserve données reçues, phase, connexion et verrou d’expiration. Cet appel seul ne reconnecte pas et ne relance pas la réception.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
LinkDmg07_ClearError();result[21]=LinkDmg07_LastError();result[22]=LinkDmg07_GetErrorCount();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Laissez le premier paquet valide non lu jusqu’au suivant. Attendez SENT SEQ=3, PACKET SEQ=2 et ERROR=6 ; la lecture renvoie les dernières valeurs 33/34/35/36. ClearError met CLEAR ERROR à zéro, mais ErrorCount reste à un.

LinkDmg07_ClearError: DMG / joueur 1
DMG / joueur 1
LinkDmg07_ClearError: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_overflow.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_overflow.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_overflow.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_overflow.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_overflow.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_overflow.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_overflow.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_overflow.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_overflow.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_overflow.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:125

Notes de déclaration (texte source)
Clear only the latest error code, preserving counters and protocol state.

kitaqgb/lib/link_dmg07.c:541

c
void LinkDmg07_ClearError() {
    LinkDmg07_LastErrorCode = LINK_DMG07_ERR_NONE;
}
LinkDmg07_ConsumePingStatus

Consomme et efface une notification de découverte terminée.

Syntaxe

c
u8 LinkDmg07_ConsumePingStatus();

Valeur renvoyée

Renvoie 1 si consommé, sinon 0.

Conditions et limites

Efface seulement la notification, préservant slot, masque et LastStatus. Les appels suivants renvoient zéro jusqu’à une nouvelle notification.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[3]=LinkDmg07_ConsumePingStatus();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_ConsumePingStatus: DMG / joueur 1
DMG / joueur 1
LinkDmg07_ConsumePingStatus: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:71

Notes de déclaration (texte source)
Clear and report the completed-discovery flag; return zero if no new status exists.

kitaqgb/lib/link_dmg07.c:418

c
u8 LinkDmg07_ConsumePingStatus() {
    if (LinkDmg07_PingStatusReady == 0) return 0;
    LinkDmg07_PingStatusReady = 0;
    return 1;
}
LinkDmg07_GetConnectedMask

Lit l’ensemble de joueurs sur quatre bits du dernier état accepté.

Syntaxe

c
u8 LinkDmg07_GetConnectedMask();

Valeur renvoyée

Les bits 0..3 indiquent les joueurs connectés. Zéro signifie non découvert ; quatre joueurs connectés donnent 15.

Conditions et limites

Les joueurs de la bibliothèque sont numérotés 1..4 ; zéro signifie non découvert. Les bits 0..3 du masque de connexion correspondent aux joueurs 1..4. Les slots KOKURA --link-session vont de 0 à 3, convention distincte de l’API ROM.

Renvoie l’état de découverte mémorisé, sans sonder le câblage physique. Pendant le transfert, reflète la dernière notification acceptée.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[1]=LinkDmg07_GetConnectedMask();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_GetConnectedMask: DMG / joueur 1
DMG / joueur 1
LinkDmg07_GetConnectedMask: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:65

Notes de déclaration (texte source)
Normalized mask: bit 0 is player 1, ..., bit 3 is player 4.

kitaqgb/lib/link_dmg07.c:403

c
u8 LinkDmg07_GetConnectedMask() {
    return LinkDmg07_ConnectedMask;
}
LinkDmg07_GetDisconnectCount

Lit les pertes enregistrées : silence après détection d’un adaptateur ou disparition de joueurs de l’état de découverte.

Syntaxe

c
u8 LinkDmg07_GetDisconnectCount();

Valeur renvoyée

Renvoie 0..255 événements, pas le nombre de joueurs perdus.

Conditions et limites

SilenceFrames et les compteurs de diagnostic saturent à 255. Init les réinitialise tous ; les redémarrages ordinaires du protocole préservent les diagnostics. ClearError n’efface que le code d’erreur.

Une expiration avant toute détection d’adaptateur ne l’incrémente pas. Plusieurs joueurs retirés par un seul changement d’état comptent comme un événement.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[8]=LinkDmg07_GetDisconnectCount();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez sans adaptateur. Attendez PLAYER=0, START ERROR=2, SILENT FRAME=12, TIMEOUTS=1 et ERROR=4. DISCONNECTS reste zéro, aucun adaptateur n’ayant été vu. Une lecture vide préserve EMPTY BUFFER=77 ; ClearError donne CLEARED=0.

LinkDmg07_GetDisconnectCount: DMG / joueur 1
DMG / joueur 1
LinkDmg07_GetDisconnectCount: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_absent.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_absent.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe .\out\dmg07_absent.gb --hardware cgb --run-frames 90 --png .\out\absent.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:118

Notes de déclaration (texte source)
Return the saturating count of removed-player and previously-seen-adapter timeout events.

kitaqgb/lib/link_dmg07.c:525

c
u8 LinkDmg07_GetDisconnectCount() {
    return LinkDmg07_DisconnectCount;
}
LinkDmg07_GetErrorCount

Lit le nombre d’erreurs de protocole reçues et d’écrasements de paquets non lus.

Syntaxe

c
u8 LinkDmg07_GetErrorCount();

Valeur renvoyée

Renvoie 0..255. N’inclut pas les erreurs de validation/état de requête ni les expirations.

Conditions et limites

SilenceFrames et les compteurs de diagnostic saturent à 255. Init les réinitialise tous ; les redémarrages ordinaires du protocole préservent les diagnostics. ClearError n’efface que le code d’erreur.

La boîte de réception ne conserve que le dernier paquet. Un nouveau paquet terminé écrase les données non lues, mémorise l’erreur 6 et incrémente ErrorCount. L’adaptateur n’attend pas que l’application lise la boîte.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[19]=LinkDmg07_GetErrorCount();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Laissez le premier paquet valide non lu jusqu’au suivant. Attendez SENT SEQ=3, PACKET SEQ=2 et ERROR=6 ; la lecture renvoie les dernières valeurs 33/34/35/36. ClearError met CLEAR ERROR à zéro, mais ErrorCount reste à un.

LinkDmg07_GetErrorCount: DMG / joueur 1
DMG / joueur 1
LinkDmg07_GetErrorCount: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_overflow.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_overflow.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_overflow.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_overflow.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_overflow.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_overflow.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_overflow.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_overflow.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_overflow.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_overflow.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:121

Notes de déclaration (texte source)
Return the saturating protocol/overflow error count. Timeout and request
validation paths use separate counters or latches and do not increment this value.

kitaqgb/lib/link_dmg07.c:531

c
u8 LinkDmg07_GetErrorCount() {
    return LinkDmg07_ErrorCount;
}
LinkDmg07_GetLastStatus

Lit le dernier octet d’état brut validé de l’adaptateur.

Syntaxe

c
u8 LinkDmg07_GetLastStatus();

Valeur renvoyée

Le quartet de poids fort est le masque de connexion ; les trois bits faibles contiennent le numéro local. Initialement zéro.

Conditions et limites

Les joueurs de la bibliothèque sont numérotés 1..4 ; zéro signifie non découvert. Les bits 0..3 du masque de connexion correspondent aux joueurs 1..4. Les slots KOKURA --link-session vont de 0 à 3, convention distincte de l’API ROM.

Rejette un état avec bit 3 actif, numéro nul ou supérieur à quatre, ou numéro local changé après découverte. Le rejet mémorise l’erreur 5 sans enregistrer cette valeur comme LastStatus.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[2]=LinkDmg07_GetLastStatus();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_GetLastStatus: DMG / joueur 1
DMG / joueur 1
LinkDmg07_GetLastStatus: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:67

Notes de déclaration (texte source)
Return the last validated raw adapter status byte.

kitaqgb/lib/link_dmg07.c:408

c
u8 LinkDmg07_GetLastStatus() {
    return LinkDmg07_LastStatus;
}
LinkDmg07_GetLocalSlot

Lit le numéro de joueur de cette console, appris dans l’état de l’adaptateur.

Syntaxe

c
u8 LinkDmg07_GetLocalSlot();

Valeur renvoyée

Renvoie 1..4 après découverte ; zéro avant ou juste après une réinitialisation de découverte.

Conditions et limites

Les joueurs de la bibliothèque sont numérotés 1..4 ; zéro signifie non découvert. Les bits 0..3 du masque de connexion correspondent aux joueurs 1..4. Les slots KOKURA --link-session vont de 0 à 3, convention distincte de l’API ROM.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
slot=LinkDmg07_GetLocalSlot();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_GetLocalSlot: DMG / joueur 1
DMG / joueur 1
LinkDmg07_GetLocalSlot: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:62

Notes de déclaration (texte source)
Return the one-based player slot, or LINK_DMG07_NO_SLOT before discovery.

kitaqgb/lib/link_dmg07.c:398

c
u8 LinkDmg07_GetLocalSlot() {
    return LinkDmg07_LocalSlot;
}
LinkDmg07_GetPacketSequence

Lit la séquence attribuée au dernier paquet publié.

Syntaxe

c
u8 LinkDmg07_GetPacketSequence();

Valeur renvoyée

Renvoie la séquence du paquet sur huit bits sans changer la disponibilité.

Conditions et limites

Les numéros de séquence passent de 255 à zéro. À la publication du paquet, PacketSequence vaut SentSequence moins un. Les départs de transmission suivants avancent SentSequence ; deux lectures ultérieures ne diffèrent donc pas nécessairement d’un.

La boîte de réception ne conserve que le dernier paquet. Un nouveau paquet terminé écrase les données non lues, mémorise l’erreur 6 et incrémente ErrorCount. L’adaptateur n’attend pas que l’application lise la boîte.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[7]=LinkDmg07_GetPacketSequence();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_GetPacketSequence: DMG / joueur 1
DMG / joueur 1
LinkDmg07_GetPacketSequence: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:109

Notes de déclaration (texte source)
Return the modulo-256 sequence associated with the most recently published packet.

kitaqgb/lib/link_dmg07.c:510

c
u8 LinkDmg07_GetPacketSequence() {
    return LinkDmg07_PacketSequence;
}
LinkDmg07_GetPacketSlot

Lit l’octet d’un joueur dans le paquet mémorisé.

Syntaxe

c
u8 __stackcall LinkDmg07_GetPacketSlot(u8 player_slot);

Paramètres

player_slot

Numéro de joueur physique, 1..4.

Valeur renvoyée

Renvoie l’octet mémorisé du joueur 1..4, ou zéro pour un numéro invalide.

Conditions et limites

Les joueurs de la bibliothèque sont numérotés 1..4 ; zéro signifie non découvert. Les bits 0..3 du masque de connexion correspondent aux joueurs 1..4. Les slots KOKURA --link-session vont de 0 à 3, convention distincte de l’API ROM.

Ne vérifie ni ne consomme la disponibilité. Renvoie zéro juste après initialisation et peut renvoyer des octets conservés après consommation ou remise à zéro de découverte. Ne l’utilisez pas comme test de nouvelles données.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[16]=LinkDmg07_GetPacketSlot(4);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_GetPacketSlot: DMG / joueur 1
DMG / joueur 1
LinkDmg07_GetPacketSlot: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:102

Notes de déclaration (texte source)
Read one cached player byte using a one-based slot. Invalid slots return
zero; the function neither requires readiness nor consumes the packet.

kitaqgb/lib/link_dmg07.c:499

c
u8 __stackcall LinkDmg07_GetPacketSlot(u8 player_slot) {
    if ((player_slot == 0) || (player_slot > LINK_DMG07_MAX_PLAYERS)) return 0;
    return LinkDmg07_RxPacket[(__safe_index u8)(player_slot - 1)];
}
LinkDmg07_GetPhase

Lit la phase courante : découverte, demande de démarrage, confirmation ou transfert.

Syntaxe

c
u8 LinkDmg07_GetPhase();

Valeur renvoyée

0=PING, 1=REQUEST_AA, 2=WAIT_CC, 3=TRANSFER.

Conditions et limites

N’interroge pas le port et n’attend pas. L’acceptation d’une demande de démarrage ne suffit pas pour TRANSFER : quatre octets 0xCC consécutifs sont requis.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[8]=LinkDmg07_GetPhase();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_GetPhase: DMG / joueur 1
DMG / joueur 1
LinkDmg07_GetPhase: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:60

Notes de déclaration (texte source)
Return the discovery, start-handshake or transfer phase without polling.

kitaqgb/lib/link_dmg07.c:393

c
u8 LinkDmg07_GetPhase() {
    return LinkDmg07_Phase;
}
LinkDmg07_GetRestartState

Lit si le contrôle de redémarrage est absent, en attente ou en cours d’envoi.

Syntaxe

c
u8 LinkDmg07_GetRestartState();

Valeur renvoyée

0=aucun, 1=attente de frontière, 2=envoi du contrôle.

Conditions et limites

Distinct de la phase de communication. Zéro seul n’implique pas une connexion établie ou utilisable.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[4]=LinkDmg07_GetRestartState();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le joueur 2 demande le redémarrage et enregistre PENDING=1, SENT FF=1. Les quatre consoles montrent DATA VALID=1, RESET PHASE=0, SLOT AFTER=0 et RESET PRIME=0. Le pilote préserve l’échange actif jusqu’à ce que l’indication de l’adaptateur le ramène à la découverte.

LinkDmg07_GetRestartState: DMG / joueur 2
DMG / joueur 2
LinkDmg07_GetRestartState: CGB / joueur 2
CGB / joueur 2

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_restart.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_restart.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_restart.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_restart.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_restart.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_restart.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_restart.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_restart.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_restart.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_restart.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:85

Notes de déclaration (texte source)
Return whether aligned recovery is absent, pending or sending control traffic.

kitaqgb/lib/link_dmg07.c:457

c
u8 LinkDmg07_GetRestartState() {
    return LinkDmg07_RestartState;
}
LinkDmg07_GetSentSequence

Lit le nombre d’octets applicatifs effectivement transmis sous horloge.

Syntaxe

c
u8 LinkDmg07_GetSentSequence();

Valeur renvoyée

Renvoie la séquence d’envoi sur huit bits. Compte la première contribution, mais exclut le contrôle de redémarrage.

Conditions et limites

Les numéros de séquence passent de 255 à zéro. À la publication du paquet, PacketSequence vaut SentSequence moins un. Les départs de transmission suivants avancent SentSequence ; deux lectures ultérieures ne diffèrent donc pas nécessairement d’un.

Avec SIZE=1, chaque console soumet un octet ; la diffusion de quatre octets suit l’ordre des joueurs 1..4. La première diffusion est jetée. Les suivantes contiennent les contributions du paquet précédent. Quatre octets 0xFF sont réservés à l’indication de redémarrage.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[6]=LinkDmg07_GetSentSequence();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_GetSentSequence: DMG / joueur 1
DMG / joueur 1
LinkDmg07_GetSentSequence: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:107

Notes de déclaration (texte source)
SentSequence increments when this console's packet byte is clocked out.
PacketSequence labels the returned four-byte packet.  For a valid packet it
is one less than SentSequence, making the DMG-07 one-packet delay explicit.

kitaqgb/lib/link_dmg07.c:505

c
u8 LinkDmg07_GetSentSequence() {
    return LinkDmg07_SentSequence;
}
LinkDmg07_GetSilenceFrames

Lit les trames comptées depuis la dernière fin de transfert série traitée.

Syntaxe

c
u8 LinkDmg07_GetSilenceFrames();

Valeur renvoyée

0..255 ; une fin traitée le remet à zéro et chaque TickFrame l’incrémente.

Conditions et limites

Appelez Poll de façon répétée pendant toute la trame et TickFrame exactement une fois par trame. Un Poll par VBlank ne peut pas réarmer le port entre les octets de l’adaptateur. Le d_poll de l’en-tête partagé détecte l’entrée dans LY >= 144 pour appeler TickFrame une fois. Sérialisez les deux opérations au lieu de faire rivaliser ISR et boucle principale.

SilenceFrames et les compteurs de diagnostic saturent à 255. Init les réinitialise tous ; les redémarrages ordinaires du protocole préservent les diagnostics. ClearError n’efface que le code d’erreur.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[6]=LinkDmg07_GetSilenceFrames();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez sans adaptateur. Attendez PLAYER=0, START ERROR=2, SILENT FRAME=12, TIMEOUTS=1 et ERROR=4. DISCONNECTS reste zéro, aucun adaptateur n’ayant été vu. Une lecture vide préserve EMPTY BUFFER=77 ; ClearError donne CLEARED=0.

LinkDmg07_GetSilenceFrames: DMG / joueur 1
DMG / joueur 1
LinkDmg07_GetSilenceFrames: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_absent.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_absent.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe .\out\dmg07_absent.gb --hardware cgb --run-frames 90 --png .\out\absent.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:114

Notes de déclaration (texte source)
SilenceFrames is reset by every completed serial byte.  TimeoutCount counts
distinct serial-silence or AA/CC/restart handshake timeouts. DisconnectCount counts
adapter-silence outages and ping-status membership drops.  All saturate.

kitaqgb/lib/link_dmg07.c:515

c
u8 LinkDmg07_GetSilenceFrames() {
    return LinkDmg07_SilenceFrames;
}
LinkDmg07_GetTimeoutCount

Lit le nombre d’expirations de silence ou de négociation.

Syntaxe

c
u8 LinkDmg07_GetTimeoutCount();

Valeur renvoyée

Renvoie un cumul de 0 à 255.

Conditions et limites

SilenceFrames et les compteurs de diagnostic saturent à 255. Init les réinitialise tous ; les redémarrages ordinaires du protocole préservent les diagnostics. ClearError n’efface que le code d’erreur.

Ne recompte pas le même silence à chaque trame avant la reprise. ClearError conserve ce verrou de suppression et le cumul.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[7]=LinkDmg07_GetTimeoutCount();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez sans adaptateur. Attendez PLAYER=0, START ERROR=2, SILENT FRAME=12, TIMEOUTS=1 et ERROR=4. DISCONNECTS reste zéro, aucun adaptateur n’ayant été vu. Une lecture vide préserve EMPTY BUFFER=77 ; ClearError donne CLEARED=0.

LinkDmg07_GetTimeoutCount: DMG / joueur 1
DMG / joueur 1
LinkDmg07_GetTimeoutCount: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_absent.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_absent.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe .\out\dmg07_absent.gb --hardware cgb --run-frames 90 --png .\out\absent.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:116

Notes de déclaration (texte source)
Return the saturating lifetime timeout count, preserved across protocol restarts.

kitaqgb/lib/link_dmg07.c:520

c
u8 LinkDmg07_GetTimeoutCount() {
    return LinkDmg07_TimeoutCount;
}
LinkDmg07_HasPacket

Vérifie si un paquet de données terminé de quatre octets n’a pas été lu.

Syntaxe

c
u8 LinkDmg07_HasPacket();

Valeur renvoyée

Renvoie 1 pour des données non lues, sinon 0.

Conditions et limites

Avec SIZE=1, chaque console soumet un octet ; la diffusion de quatre octets suit l’ordre des joueurs 1..4. La première diffusion est jetée. Les suivantes contiennent les contributions du paquet précédent. Quatre octets 0xFF sont réservés à l’indication de redémarrage.

La boîte de réception ne conserve que le dernier paquet. Un nouveau paquet terminé écrase les données non lues, mémorise l’erreur 6 et incrémente ErrorCount. L’adaptateur n’attend pas que l’application lise la boîte.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[15]=LinkDmg07_HasPacket();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_HasPacket: DMG / joueur 1
DMG / joueur 1
LinkDmg07_HasPacket: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:96

Notes de déclaration (texte source)
Inspect the one-packet receive mailbox without consuming it.

kitaqgb/lib/link_dmg07.c:473

c
u8 LinkDmg07_HasPacket() {
    return LinkDmg07_PacketReady;
}
LinkDmg07_HasPingStatus

Vérifie si un échange de découverte de quatre octets terminé attend un acquittement.

Syntaxe

c
u8 LinkDmg07_HasPingStatus();

Valeur renvoyée

Renvoie 1 pour une notification non consommée, sinon 0.

Conditions et limites

Ne lit qu’un drapeau. Un échange de découverte peut avancer malgré un état rejeté ; ce drapeau seul ne prouve donc ni des données entièrement valides ni un démarrage terminé. Vérifiez aussi slot, masque et LastError.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[4]=LinkDmg07_HasPingStatus();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_HasPingStatus: DMG / joueur 1
DMG / joueur 1
LinkDmg07_HasPingStatus: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:69

Notes de déclaration (texte source)
Read the completed-discovery status flag without clearing it.

kitaqgb/lib/link_dmg07.c:413

c
u8 LinkDmg07_HasPingStatus() {
    return LinkDmg07_PingStatusReady;
}
LinkDmg07_Init

Réinitialise découverte, stockage de réception et diagnostics, puis arme la réception sur les horloges de l’adaptateur.

Syntaxe

c
void __stackcall LinkDmg07_Init(u8 rate);

Paramètres

rate

Réponse RATE sur huit bits à l’adaptateur ; zéro choisit la valeur par défaut 0x10.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Ce pilote possède le port série. N’exécutez pas Link ordinaire ou Link4 simultanément ; incluez link_hwregs_gb.c et link_dmg07.c une fois chacun. L’adaptateur fournit les horloges externes ; le pilote ne sélectionne pas le mode série rapide CGB.

Les joueurs de la bibliothèque sont numérotés 1..4 ; zéro signifie non découvert. Les bits 0..3 du masque de connexion correspondent aux joueurs 1..4. Les slots KOKURA --link-session vont de 0 à 3, convention distincte de l’API ROM.

Met SC à 0x80 et SB à 0x88 ; efface seulement les bits série dans IE et IF. Ne modifie ni les autres bits d’activation ni l’état IME du CPU.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
LinkDmg07_Init(0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_Init: DMG / joueur 1
DMG / joueur 1
LinkDmg07_Init: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:50

Notes de déclaration (texte source)
Initializes polling-only external-clock operation.  A zero RATE is replaced
with LINK_DMG07_DEFAULT_RATE.  This driver disables only the serial IRQ bit.

kitaqgb/lib/link_dmg07.c:282

c
void __stackcall LinkDmg07_Init(u8 rate) {
    u8 i;

    LinkDmg07_Rate = rate;
    if (LinkDmg07_Rate == 0) LinkDmg07_Rate = LINK_DMG07_DEFAULT_RATE;
    LinkDmg07_LocalByte = 0;
    LinkDmg07_SentSequence = 0;
    LinkDmg07_PacketSequence = 0;
    LinkDmg07_RestartState = LINK_DMG07_RESTART_NONE;
    LinkDmg07_SilenceFrames = 0;
    LinkDmg07_TimeoutCount = 0;
    LinkDmg07_DisconnectCount = 0;
    LinkDmg07_ErrorCount = 0;
    LinkDmg07_LastErrorCode = LINK_DMG07_ERR_NONE;
    LinkDmg07_SeenAdapter = 0;
    LinkDmg07_TimeoutLatched = 0;
    for (i = 0; i < LINK_DMG07_PACKET_BYTES; ++i) {
        LinkDmg07_RxBuild[(__safe_index u8)i] = 0;
        LinkDmg07_RxPacket[(__safe_index u8)i] = 0;
    }
    LinkDmg07_ResetToPingInternal();

    LinkHw_WriteIE((u8)(LinkHw_ReadIE() & LINK_DMG07_IRQ_SERIAL_CLEAR));
    LinkHw_WriteIF((u8)(LinkHw_ReadIF() & LINK_DMG07_IRQ_SERIAL_CLEAR));
    LinkDmg07_ArmInternal(LINK_DMG07_ACK);
}
LinkDmg07_IsPipelinePrimed

Vérifie si la première diffusion indéfinie a été jetée.

Syntaxe

c
u8 LinkDmg07_IsPipelinePrimed();

Valeur renvoyée

Renvoie 1 après la première diffusion ; initialisation, remise à zéro de découverte et confirmation de démarrage l’effacent.

Conditions et limites

Avec SIZE=1, chaque console soumet un octet ; la diffusion de quatre octets suit l’ordre des joueurs 1..4. La première diffusion est jetée. Les suivantes contiennent les contributions du paquet précédent. Quatre octets 0xFF sont réservés à l’indication de redémarrage.

Un pipeline amorcé ne contient pas nécessairement un paquet terminé. Utilisez HasPacket pour savoir si une lecture est disponible.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[9]=LinkDmg07_IsPipelinePrimed();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_IsPipelinePrimed: DMG / joueur 1
DMG / joueur 1
LinkDmg07_IsPipelinePrimed: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:94

Notes de déclaration (texte source)
The first incoming adapter data packet is discarded.  Thereafter ReadPacket
copies four bytes in physical slot order (players 1..4).

kitaqgb/lib/link_dmg07.c:468

c
u8 LinkDmg07_IsPipelinePrimed() {
    return LinkDmg07_PipelinePrimed;
}
LinkDmg07_LastError

Lit le dernier code d’erreur mémorisé.

Syntaxe

c
u8 LinkDmg07_LastError();

Valeur renvoyée

Renvoie un code d’erreur de 0 à 6.

Conditions et limites

Codes d’erreur : 0=aucune, 1=mauvaise phase, 2=pas joueur 1, 3=non prêt, 4=expiration, 5=erreur de protocole, 6=paquet non lu écrasé. Les requêtes réussissent avec zéro ; réception/pop avec un. Une requête réussie n’efface pas une erreur antérieure.

La lecture ne l’efface pas. Ne conserve que le dernier code, pas l’historique des erreurs.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[9]=LinkDmg07_LastError();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez sans adaptateur. Attendez PLAYER=0, START ERROR=2, SILENT FRAME=12, TIMEOUTS=1 et ERROR=4. DISCONNECTS reste zéro, aucun adaptateur n’ayant été vu. Une lecture vide préserve EMPTY BUFFER=77 ; ClearError donne CLEARED=0.

LinkDmg07_LastError: DMG / joueur 1
DMG / joueur 1
LinkDmg07_LastError: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_absent.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_absent.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe .\out\dmg07_absent.gb --hardware cgb --run-frames 90 --png .\out\absent.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:123

Notes de déclaration (texte source)
Return the latest error latch without clearing counters or restarting the protocol.

kitaqgb/lib/link_dmg07.c:536

c
u8 LinkDmg07_LastError() {
    return LinkDmg07_LastErrorCode;
}
LinkDmg07_Poll

Traite un octet série terminé dans la phase courante et arme immédiatement la réponse suivante.

Syntaxe

c
void LinkDmg07_Poll();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Ce pilote possède le port série. N’exécutez pas Link ordinaire ou Link4 simultanément ; incluez link_hwregs_gb.c et link_dmg07.c une fois chacun. L’adaptateur fournit les horloges externes ; le pilote ne sélectionne pas le mode série rapide CGB.

Appelez Poll de façon répétée pendant toute la trame et TickFrame exactement une fois par trame. Un Poll par VBlank ne peut pas réarmer le port entre les octets de l’adaptateur. Le d_poll de l’en-tête partagé détecte l’entrée dans LY >= 144 pour appeler TickFrame une fois. Sérialisez les deux opérations au lieu de faire rivaliser ISR et boucle principale.

Ne fait rien tant que le bit de démarrage de SC est actif. Traiter une fin remet à zéro SilenceFrames et le verrou d’expiration. Initialisez avant d’interroger.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
void d_poll(){LinkDmg07_Poll();if(D_LY>=144){if(d_vblank==0){d_vblank=1;LinkDmg07_TickFrame();}}else d_vblank=0;}

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_Poll: DMG / joueur 1
DMG / joueur 1
LinkDmg07_Poll: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:54

Notes de déclaration (texte source)
Services at most one completed serial byte and immediately re-arms SC=$80.
Call continuously from the main loop, including between VBlanks.

kitaqgb/lib/link_dmg07.c:311

c
void LinkDmg07_Poll() {
    u8 value;
    u8 next;

    if ((LinkHw_ReadSC() & LINK_DMG07_SC_EXTERNAL_START) != 0) return;

    value = LinkHw_ReadSB();
    LinkDmg07_SilenceFrames = 0;
    LinkDmg07_TimeoutLatched = 0;
    LinkDmg07_SeenAdapter = 1;

    next = 0;
    if (LinkDmg07_Phase == LINK_DMG07_PHASE_PING) {
        next = LinkDmg07_ProcessPingInternal(value);
    } else if (LinkDmg07_Phase == LINK_DMG07_PHASE_REQUEST_AA) {
        next = LinkDmg07_ProcessRequestInternal(value);
    } else if (LinkDmg07_Phase == LINK_DMG07_PHASE_WAIT_CC) {
        next = LinkDmg07_ProcessWaitCcInternal(value);
    } else if (LinkDmg07_Phase == LINK_DMG07_PHASE_TRANSFER) {
        next = LinkDmg07_ProcessTransferInternal(value);
    } else {
        LinkDmg07_SetRuntimeErrorInternal(LINK_DMG07_ERR_PROTOCOL);
        LinkDmg07_ResetToPingInternal();
        next = LINK_DMG07_ACK;
    }

    LinkDmg07_ArmInternal(next);
}
LinkDmg07_ReadPacket

Copie le dernier paquet terminé et efface son drapeau non lu.

Syntaxe

c
u8 __stackcall LinkDmg07_ReadPacket(u8 *dst);

Paramètres

dst

Quatre octets accessibles en écriture ; null jette le paquet.

Valeur renvoyée

Renvoie 1 si consommé, 0 si vide. Une lecture vide laisse dst inchangé.

Conditions et limites

Avec SIZE=1, chaque console soumet un octet ; la diffusion de quatre octets suit l’ordre des joueurs 1..4. La première diffusion est jetée. Les suivantes contiennent les contributions du paquet précédent. Quatre octets 0xFF sont réservés à l’indication de redémarrage.

La boîte de réception ne conserve que le dernier paquet. Un nouveau paquet terminé écrase les données non lues, mémorise l’erreur 6 et incrémente ErrorCount. L’adaptateur n’attend pas que l’application lise la boîte.

Les octets mémorisés restent accessibles par GetPacketSlot après consommation. Un ReadPacket vide ne les recopie pas.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[10]=LinkDmg07_ReadPacket(packet);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_ReadPacket: DMG / joueur 1
DMG / joueur 1
LinkDmg07_ReadPacket: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:99

Notes de déclaration (texte source)
Consume the latest four-byte packet. A nonnull destination must hold four
bytes; null discards the packet. Packet storage remains after the flag clears.

kitaqgb/lib/link_dmg07.c:479

c
u8 __stackcall LinkDmg07_ReadPacket(u8 *dst) {
    if (LinkDmg07_PacketReady == 0) return 0;
    if (dst != 0) {
        // Keep this as a sequential pointer copy.  Besides being smaller for a
        // fixed four-byte packet, it avoids making a serial hot-path copy
        // depend on general variable-index pointer lowering.
        *dst = LinkDmg07_RxPacket[0];
        dst++;
        *dst = LinkDmg07_RxPacket[1];
        dst++;
        *dst = LinkDmg07_RxPacket[2];
        dst++;
        *dst = LinkDmg07_RxPacket[3];
    }
    LinkDmg07_PacketReady = 0;
    return 1;
}
LinkDmg07_RequestRestart

Programme le trafic de contrôle de redémarrage à une frontière de paquet de transfert.

Syntaxe

c
u8 LinkDmg07_RequestRestart();

Valeur renvoyée

Renvoie 0 en TRANSFER, sinon 1. Les demandes répétées pendant attente/envoi renvoient aussi 0.

Conditions et limites

Avec SIZE=1, chaque console soumet un octet ; la diffusion de quatre octets suit l’ordre des joueurs 1..4. La première diffusion est jetée. Les suivantes contiennent les contributions du paquet précédent. Quatre octets 0xFF sont réservés à l’indication de redémarrage.

Codes d’erreur : 0=aucune, 1=mauvaise phase, 2=pas joueur 1, 3=non prêt, 4=expiration, 5=erreur de protocole, 6=paquet non lu écrasé. Les requêtes réussissent avec zéro ; réception/pop avec un. Une requête réussie n’efface pas une erreur antérieure.

Tout joueur peut le demander. Préserve la position d’octet, envoie un trafic 0xFF aligné et revient à la découverte après l’indication tout-0xFF de l’adaptateur. La demande seule n’efface ni le slot local ni le pipeline de réception.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[3]=LinkDmg07_RequestRestart();result[4]=LinkDmg07_GetRestartState();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le joueur 2 demande le redémarrage et enregistre PENDING=1, SENT FF=1. Les quatre consoles montrent DATA VALID=1, RESET PHASE=0, SLOT AFTER=0 et RESET PRIME=0. Le pilote préserve l’échange actif jusqu’à ce que l’indication de l’adaptateur le ramène à la découverte.

LinkDmg07_RequestRestart: DMG / joueur 2
DMG / joueur 2
LinkDmg07_RequestRestart: CGB / joueur 2
CGB / joueur 2

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_restart.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_restart.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_restart.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_restart.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_restart.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_restart.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_restart.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_restart.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_restart.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_restart.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:83

Notes de déclaration (texte source)
Any physical slot may schedule FF FF FF FF at the next four-byte packet
boundary while remaining in TRANSFER phase.  The driver keeps sending aligned
FF bytes until it sees the adapter's complete all-FF indicator packet, then
returns to PING.  A transfer-phase silence timeout schedules the same recovery
automatically and preserves the current byte position for clocks that resume.

kitaqgb/lib/link_dmg07.c:445

c
u8 LinkDmg07_RequestRestart() {
    if (LinkDmg07_Phase != LINK_DMG07_PHASE_TRANSFER) {
        LinkDmg07_LastErrorCode = LINK_DMG07_ERR_STATE;
        return LINK_DMG07_ERR_STATE;
    }
    if (LinkDmg07_RestartState == LINK_DMG07_RESTART_NONE) {
        LinkDmg07_RestartState = LINK_DMG07_RESTART_PENDING;
    }
    return LINK_DMG07_ERR_NONE;
}
LinkDmg07_RequestTransmission

Programme la demande de démarrage du joueur physique 1 à la prochaine frontière de paquet de découverte.

Syntaxe

c
u8 LinkDmg07_RequestTransmission();

Valeur renvoyée

Renvoie 0 si programmé, 1 pour une mauvaise phase, 2 si ce n’est pas le joueur 1, 3 si le bit de connexion local manque.

Conditions et limites

Les joueurs de la bibliothèque sont numérotés 1..4 ; zéro signifie non découvert. Les bits 0..3 du masque de connexion correspondent aux joueurs 1..4. Les slots KOKURA --link-session vont de 0 à 3, convention distincte de l’API ROM.

Codes d’erreur : 0=aucune, 1=mauvaise phase, 2=pas joueur 1, 3=non prêt, 4=expiration, 5=erreur de protocole, 6=paquet non lu écrasé. Les requêtes réussissent avec zéro ; réception/pop avec un. Une requête réussie n’efface pas une erreur antérieure.

Ne peut être programmé qu’en PING. N’attend pas lui-même les quatre joueurs ; l’exemple vérifie le masque 15 dans l’application. La programmation est asynchrone : le trafic 0xAA aligné précède la confirmation 0xCC.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
result[5]=LinkDmg07_RequestTransmission();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_RequestTransmission: DMG / joueur 1
DMG / joueur 1
LinkDmg07_RequestTransmission: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:76

Notes de déclaration (texte source)
Only physical player 1 may request AA AA AA AA.  The bytes are aligned to
the next FE/status/status/status ping packet.  All consoles enter transfer
mode only after receiving four consecutive CC bytes.

kitaqgb/lib/link_dmg07.c:426

c
u8 LinkDmg07_RequestTransmission() {
    if (LinkDmg07_Phase != LINK_DMG07_PHASE_PING) {
        LinkDmg07_LastErrorCode = LINK_DMG07_ERR_STATE;
        return LINK_DMG07_ERR_STATE;
    }
    if (LinkDmg07_LocalSlot != 1) {
        LinkDmg07_LastErrorCode = LINK_DMG07_ERR_NOT_PLAYER1;
        return LINK_DMG07_ERR_NOT_PLAYER1;
    }
    if ((LinkDmg07_ConnectedMask & (u8)0x01) == 0) {
        LinkDmg07_LastErrorCode = LINK_DMG07_ERR_NOT_READY;
        return LINK_DMG07_ERR_NOT_READY;
    }
    LinkDmg07_StartRequested = 1;
    return LINK_DMG07_ERR_NONE;
}
LinkDmg07_SetLocalByte

Définit l’octet applicatif d’un prochain paquet sortant.

Syntaxe

c
void __stackcall LinkDmg07_SetLocalByte(u8 value);

Paramètres

value

Valeur applicative sur huit bits à soumettre.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Avec SIZE=1, chaque console soumet un octet ; la diffusion de quatre octets suit l’ordre des joueurs 1..4. La première diffusion est jetée. Les suivantes contiennent les contributions du paquet précédent. Quatre octets 0xFF sont réservés à l’indication de redémarrage.

Échantillonné lorsque l’octet zéro du paquet est armé. Ne change pas un octet SB déjà armé. Définissez la première contribution avant de demander le démarrage.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
LinkDmg07_SetLocalByte(32+slot);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez la même ROM sur quatre consoles, chacune envoyant 32 plus son numéro. Toutes reçoivent PLAYER 1..4 = 33/34/35/36. La première diffusion valide enregistre SENT SEQ=2 et PACKET SEQ=1, montrant le retard d’un paquet. L’écran fige cette observation ; un jeu continue ensuite à interroger le port.

LinkDmg07_SetLocalByte: DMG / joueur 1
DMG / joueur 1
LinkDmg07_SetLocalByte: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_exchange.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_exchange.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe --link-topology dmg07 --run-frames 90 --link-session "name=player1|slot=0|rom=.\out\dmg07_exchange.gb|save_state=.\out\player1.kqs" --link-session "name=player2|slot=1|rom=.\out\dmg07_exchange.gb|save_state=.\out\player2.kqs" --link-session "name=player3|slot=2|rom=.\out\dmg07_exchange.gb|save_state=.\out\player3.kqs" --link-session "name=player4|slot=3|rom=.\out\dmg07_exchange.gb|save_state=.\out\player4.kqs"
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player1.kqs --run-frames 2 --png .\out\player1.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player2.kqs --run-frames 2 --png .\out\player2.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player3.kqs --run-frames 2 --png .\out\player3.png
.\kokura\kokura-cli.exe .\out\dmg07_exchange.gb --hardware cgb --load-state .\out\player4.kqs --run-frames 2 --png .\out\player4.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:90

Notes de déclaration (texte source)
Sets the byte sampled when byte 0 of the next adapter packet is armed.
Set it before the current packet completes (and before requesting start for
the first submission).  During normal transfer, bytes 1..3 are sent as zero.

kitaqgb/lib/link_dmg07.c:463

c
void __stackcall LinkDmg07_SetLocalByte(u8 value) {
    LinkDmg07_LocalByte = value;
}
LinkDmg07_TickFrame

Avance d’une trame les surveillances de silence et de démarrage/redémarrage, puis demande une reprise à l’échéance.

Syntaxe

c
void LinkDmg07_TickFrame();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Appelez Poll de façon répétée pendant toute la trame et TickFrame exactement une fois par trame. Un Poll par VBlank ne peut pas réarmer le port entre les octets de l’adaptateur. Le d_poll de l’en-tête partagé détecte l’entrée dans LY >= 144 pour appeler TickFrame une fois. Sérialisez les deux opérations au lieu de faire rivaliser ISR et boucle principale.

SilenceFrames et les compteurs de diagnostic saturent à 255. Init les réinitialise tous ; les redémarrages ordinaires du protocole préservent les diagnostics. ClearError n’efface que le code d’erreur.

Le délai par défaut est de 12 appels ; définissez LINK_DMG07_TIMEOUT_FRAMES entre 1 et 255 avant inclusion pour le changer. Un épisode de silence n’est compté qu’une fois, jusqu’à ce qu’un octet efface son verrou. La reprise du transfert préserve l’alignement des octets ; celle de découverte/démarrage retourne à la découverte.

Les écrans proviennent du modèle DMG-07 de KOKURA. Chaque console s’exécute indépendamment et les valeurs envoyées/reçues sont comparées. Le comportement électrique et le timing de l’adaptateur et du câble physiques ne sont pas vérifiés. Les écrans CGB affichent les nombres en bleu.

Placez kitaqgb, kokura et kitaq-docs sous un même répertoire parent et ouvrez PowerShell à cet endroit. Les exemples à quatre consoles lancent la même ROM dans quatre sessions. Pour DMG, remplacez partout --cgb=cgb par --cgb=dmg et --hardware cgb par --hardware dmg.

Exemple d’utilisation

c
void d_poll(){LinkDmg07_Poll();if(D_LY>=144){if(d_vblank==0){d_vblank=1;LinkDmg07_TickFrame();}}else d_vblank=0;}

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Exécutez sans adaptateur. Attendez PLAYER=0, START ERROR=2, SILENT FRAME=12, TIMEOUTS=1 et ERROR=4. DISCONNECTS reste zéro, aucun adaptateur n’ayant été vu. Une lecture vide préserve EMPTY BUFFER=77 ; ClearError donne CLEARED=0.

LinkDmg07_TickFrame: DMG / joueur 1
DMG / joueur 1
LinkDmg07_TickFrame: CGB / joueur 1
CGB / joueur 1

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dmg07_absent.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dmg07_absent.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
.\kokura\kokura-cli.exe .\out\dmg07_absent.gb --hardware cgb --run-frames 90 --png .\out\absent.png
Implémentation et source

kitaqgb/lib/link_dmg07.h:57

Notes de déclaration (texte source)
Advances saturating frame-based silence and handshake timeout counters.

kitaqgb/lib/link_dmg07.c:369

c
void LinkDmg07_TickFrame() {
    LinkDmg07_SilenceFrames = LinkDmg07_IncrementSaturatingInternal(LinkDmg07_SilenceFrames);

    if ((LinkDmg07_Phase == LINK_DMG07_PHASE_REQUEST_AA) ||
        (LinkDmg07_Phase == LINK_DMG07_PHASE_WAIT_CC) ||
        (LinkDmg07_RestartState == LINK_DMG07_RESTART_SENDING)) {
        LinkDmg07_HandshakeFrames = LinkDmg07_IncrementSaturatingInternal(LinkDmg07_HandshakeFrames);
    } else {
        LinkDmg07_HandshakeFrames = 0;
    }

    if ((LinkDmg07_SilenceFrames >= LINK_DMG07_TIMEOUT_FRAMES) &&
        (LinkDmg07_TimeoutLatched == 0)) {
        LinkDmg07_TimeoutInternal(1);
        return;
    }

    if ((LinkDmg07_HandshakeFrames >= LINK_DMG07_TIMEOUT_FRAMES) &&
        (LinkDmg07_TimeoutLatched == 0)) {
        LinkDmg07_TimeoutInternal(0);
    }
}

physics2d.h — Mouvement et collisions en 2D

Fournit l’intégration des boîtes, les contacts AABB et un solveur optionnel de réponse aux surfaces. Les corps utilisent des centres et des demi-dimensions ; active=0 exclut un emplacement, et inv_mass_q8<=0 rend le corps statique. KQRect utilise au contraire un coin supérieur gauche et une largeur/hauteur. Les contacts entre boîtes n’utilisent pas le champ restitution du corps ; les réponses aux surfaces utilisent les coefficients de KQSurface2D.

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

Le monde emprunte son tableau : l’appelant alloue et possède la mémoire des corps et doit la garder valide. Initialiser le monde n’initialise pas les éléments du tableau.

kq2d_body_apply_friction

Multiplie les deux composantes de vitesse par un coefficient signé sur un octet divisé par 256, sans vérifier la position ni l’activité.

Syntaxe

c
void kq2d_body_apply_friction(KQBody2D* body, u8 friction_q8);

Paramètres

body

Pointeur vers le corps à modifier. Les champs non utilisés par cette opération sont conservés.

friction_q8

Facteur multiplicatif de vitesse utilisé par cette fonction. Il est converti en s8 : les valeurs 128..255 deviennent donc des coefficients négatifs.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Les valeurs 0..127 donnent des facteurs de 0 à 127/256. Les valeurs 128..255 deviennent négatives après conversion en s8 et inversent la vitesse. Pour un amortissement non négatif sur toute la plage 0..255, utilisez kq2d_scale_q8 sur chaque composante. Les produits sont tronqués vers zéro. NULL est ignoré.

Exemple d’utilisation

c
kq2d_body_apply_friction(&temp,64);
    result[11]=temp.vx; result[12]=temp.vy;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

kq2d_body_apply_friction: DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
kq2d_body_apply_friction: CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body2d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body2d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:66

Notes de déclaration (texte source)
Scale both velocities through the signed 8-bit coefficient intrinsic.
Despite the unsigned parameter, values 128..255 become negative coefficients;
this is not a full-range unsigned Q8 damping helper. Null is ignored.

kitaqgb/lib/physics2d.c:654

c
void kq2d_body_apply_friction(KQBody2D* body, u8 friction_q8)
{
    if (body == 0) return;
    body->vx = (s16)__smul16x8(body->vx, (s8)friction_q8);
    body->vy = (s16)__smul16x8(body->vy, (s8)friction_q8);
}
kq2d_body_apply_gravity

Ajoute la gravité à un corps dynamique actif et borne chaque axe à +/-max_speed, sans modifier la position.

Syntaxe

c
void kq2d_body_apply_gravity(KQBody2D* body, s16 gravity_x, s16 gravity_y, s16 max_speed);

Paramètres

body

Pointeur vers le corps à modifier. Les champs non utilisés par cette opération sont conservés.

gravity_x

Accélération ajoutée à la vitesse X par cet appel.

gravity_y

Accélération ajoutée à la vitesse Y par cet appel.

max_speed

Limite de vitesse. La rubrique précise si elle s’applique à chaque axe ou au vecteur résultant.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

Veillez à ce que sommes, différences, sommes de demi-dimensions et produits de correction des contacts restent dans la plage d’un entier signé de 16 bits. La limitation de vitesse intervient après l’addition et ne peut donc pas empêcher un dépassement pendant celle-ci.

Les routines d’intégration et de collision des boîtes partagent une zone de travail. Ne les rappelez pas depuis une interruption lorsqu’elles sont déjà en cours d’exécution.

Ignore NULL, les corps inactifs et ceux dont la masse inverse est nulle ou négative. Fournissez une limite de vitesse positive ou nulle.

Exemple d’utilisation

c
kq2d_body_apply_gravity(&temp,5,-10,32);
    result[9]=temp.vx; result[10]=temp.vy;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

kq2d_body_apply_gravity: DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
kq2d_body_apply_gravity: CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body2d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body2d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:62

Notes de déclaration (texte source)
Add gravity and clamp each velocity axis separately for an active dynamic
body. Null, inactive and static bodies are ignored. Supply a nonnegative limit
and avoid overflow in the additions before clamping; position is unchanged.

kitaqgb/lib/physics2d.c:630

c
void kq2d_body_apply_gravity(KQBody2D* body, s16 gravity_x, s16 gravity_y, s16 max_speed)
{
    if (body == 0) return;
    if (body->active == 0) return;
    if (body->inv_mass_q8 <= 0) return;

    kq2d_asm_value = body->vx;
    kq2d_asm_operand = gravity_x;
    kq2d_add_s16_asm();
    kq2d_asm_limit = max_speed;
    kq2d_clamp_abs_s16_asm();
    body->vx = kq2d_asm_value;

    kq2d_asm_value = body->vy;
    kq2d_asm_operand = gravity_y;
    kq2d_add_s16_asm();
    kq2d_asm_limit = max_speed;
    kq2d_clamp_abs_s16_asm();
    body->vy = kq2d_asm_value;
}
kq2d_body_init

Initialise une boîte définie par son centre avec les demi-dimensions fournies, une vitesse nulle, une masse inverse de 256 et un état actif.

Syntaxe

c
void kq2d_body_init(KQBody2D* body, s16 x, s16 y, s16 half_x, s16 half_y);

Paramètres

body

Pointeur vers le corps à modifier. Les champs non utilisés par cette opération sont conservés.

x

Coordonnée X du centre ou du point, en pixels dans l’exemple.

y

Coordonnée Y du centre ou du point ; le sens positif va vers le bas dans l’exemple.

half_x

Demi-dimension selon X ; la largeur totale de la boîte vaut deux fois cette valeur.

half_y

Demi-dimension selon Y ; la hauteur totale de la boîte vaut deux fois cette valeur.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

Met restitution_q8 à zéro. Un corps NULL est ignoré. Fournissez des demi-dimensions positives.

Exemple d’utilisation

c
kq2d_body_init(&temp,10,20,8,8);
    result[3]=temp.inv_mass_q8; result[4]=temp.active;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

kq2d_body_init: DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
kq2d_body_init: CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body2d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body2d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:54

Notes de déclaration (texte source)
Initialize an active unit-inverse-mass body at the supplied center and half
extents, with zero velocity and reserved restitution set to zero. Null is ignored.

kitaqgb/lib/physics2d.c:597

c
void kq2d_body_init(KQBody2D* body, s16 x, s16 y, s16 half_x, s16 half_y)
{
    if (body == 0) return;
    body->x = x;
    body->y = y;
    body->vx = 0;
    body->vy = 0;
    body->half_x = half_x;
    body->half_y = half_y;
    body->inv_mass_q8 = 256;
    body->restitution_q8 = 0;
    body->active = 1;
}
kq2d_body_limit_speed

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Estime prudemment la longueur du vecteur et met les deux axes à l’échelle ensemble pour limiter la vitesse résultante.

Syntaxe

c
void kq2d_body_limit_speed(KQBody2D* body, s16 max_speed);

Paramètres

body

Pointeur vers le corps à modifier. Les champs non utilisés par cette opération sont conservés.

max_speed

Limite de vitesse. La rubrique précise si elle s’applique à chaque axe ou au vecteur résultant.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Gardez les valeurs absolues des composantes de vitesse et un max_speed positif à 16383 au plus. Une limite nulle ou négative annule la vitesse. NULL est ignoré, mais ni l’activité ni la masse n’empêchentntntntntntntntnt la modification. La quantification entière peut donner un résultat inférieur à la limite, et un très petit facteur peut produire zéro.

Exemple d’utilisation

c
kq2d_body_limit_speed(&body,250);
    result[2]=body.vx; result[3]=body.vy;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.

kq2d_body_limit_speed: DMG — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.
DMG — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.
kq2d_body_limit_speed: CGB — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.
CGB — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_surface.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_surface.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:92

Notes de déclaration (texte source)
Conservative circular bound, with a shared Q8 scale for both components.
Quantizes toward zero; very small limits relative to input may yield zero.
Components and positive max_speed must be <= 16383 in magnitude.

kitaqgb/lib/physics2d.c:260

c
void kq2d_body_limit_speed(KQBody2D* body, s16 max_speed)
{
    u16 x;
    u16 y;
    u16 swap;
    u16 ratio;
    u16 length;
    if (body == 0) return;
    if (max_speed <= 0) { body->vx = 0; body->vy = 0; return; }
    x = (u16)body->vx;
    y = (u16)body->vy;
    if (body->vx < 0) x = (u16)(0 - body->vx);
    if (body->vy < 0) y = (u16)(0 - body->vy);
    if (x + y <= (u16)max_speed) return;
    if (x < y) { swap = x; x = y; y = swap; }
    // major + minor/2 bounds hypot from above for 0 <= minor <= major.
    if (x + (y >> 1) + 1 <= (u16)max_speed) return;
    // Round the minor/major ratio upward for the 65-entry upper-bound table.
    // The extra unit covers truncation when converting the estimate back to speed.
    ratio = (kq2d__fraction_q8(y, x) + 4) >> 2;
    if (ratio > 64) ratio = 64;
    length = x + (u16)kq2d_scale_q8((s16)x, (s16)kq2d_hypot_extra[(__safe_index u8)ratio]) + 1;
    if (length <= (u16)max_speed) return;
    ratio = kq2d__fraction_q8((u16)max_speed, length);
    body->vx = kq2d_scale_q8(body->vx, (s16)ratio);
    body->vy = kq2d_scale_q8(body->vy, (s16)ratio);
}
kq2d_body_resolve_surface

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Utilise la vitesse relative à une surface mobile pour appliquer un rebond normal, une vitesse minimale de rebond et un frottement tangent.

Syntaxe

c
s16 kq2d_body_resolve_surface(KQBody2D* body, const KQSurface2D* surface);

Paramètres

body

Pointeur vers le corps à modifier. Les champs non utilisés par cette opération sont conservés.

surface

Pointeur vers une KQSurface2D contenant sa normale, sa vitesse et ses paramètres de rebond et de frottement.

Valeur renvoyée

Renvoie la vitesse normale d’approche positive, ou 0 si une entrée est NULL ou si le mouvement s’éloigne de la surface.

Conditions et limites

Utilisez une normale unitaire Q8 de longueur 256. Gardez les composantes relatives dans +/-8191, threshold/kick positifs ou nuls et les coefficients dans 0..255. La restitution ne s’applique que strictement au-dessus du seuil ; kick fixe une vitesse minimale de rebond. Des entrées NULL ou un mouvement d’éloignement laissent la vitesse inchangée. La détection de contact et la correction de pénétration sont séparées ; l’activité et la masse ne sont pas vérifiées.

Exemple d’utilisation

c
result[6]=kq2d_body_resolve_surface(&body,&surface);
    result[7]=body.vx; result[8]=body.vy; result[9]=body.y;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.

kq2d_body_resolve_surface: DMG — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.
DMG — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.
kq2d_body_resolve_surface: CGB — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.
CGB — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_surface.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_surface.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:95

Notes de déclaration (texte source)
Kinematic surface response; returns incoming normal speed, or zero if separating.
Caller resolves penetration separately. Relative components must fit +/-8191.

kitaqgb/lib/physics2d.c:314

c
s16 kq2d_body_resolve_surface(KQBody2D* body, const KQSurface2D* surface)
{
    s16 vx;
    s16 vy;
    s16 speed;
    s16 tangent;
    s16 bounce = 0;
    s16 impulse;
    s16 friction;
    if (body == 0 || surface == 0) return 0;
    vx = (s16)(body->vx - surface->vx);
    vy = (s16)(body->vy - surface->vy);
    speed = (s16)(kq2d_scale_q8(vx,surface->nx_q8) + kq2d_scale_q8(vy,surface->ny_q8));
    if (speed >= 0) return 0;
    speed = (s16)(0 - speed);
    if (speed > surface->bounce_threshold) bounce = kq2d_scale_q8(speed,(s16)surface->restitution_q8);
    if (bounce < surface->kick) bounce = surface->kick;
    impulse = (s16)(speed + bounce);
    // A resting contact is a tangent constraint, not a tiny rounded bounce.
    if (bounce == 0) {
        tangent = (s16)(kq2d__rest_component(vy,surface->nx_q8) - kq2d__rest_component(vx,surface->ny_q8));
        friction = kq2d_scale_q8(impulse,(s16)surface->friction_q8);
        if (tangent > friction) tangent = (s16)(tangent - friction);
        else if (tangent < (s16)(0 - friction)) tangent = (s16)(tangent + friction);
        else tangent = 0;
        body->vx = (s16)(surface->vx - kq2d__rest_component(tangent,surface->ny_q8));
        body->vy = (s16)(surface->vy + kq2d__rest_component(tangent,surface->nx_q8));
        return speed;
    }
    body->vx = (s16)(body->vx + kq2d_scale_q8(impulse,surface->nx_q8));
    body->vy = (s16)(body->vy + kq2d_scale_q8(impulse,surface->ny_q8));
    if (surface->friction_q8 != 0) {
        tangent = (s16)(kq2d_scale_q8(vy,surface->nx_q8) - kq2d_scale_q8(vx,surface->ny_q8));
        friction = kq2d_scale_q8(impulse,(s16)surface->friction_q8);
        if (tangent > friction) tangent = friction;
        if (tangent < (s16)(0 - friction)) tangent = (s16)(0 - friction);
        body->vx = (s16)(body->vx + kq2d_scale_q8(tangent,surface->ny_q8));
        body->vy = (s16)(body->vy - kq2d_scale_q8(tangent,surface->nx_q8));
    }
    return speed;
}
kq2d_body_set_pos

Remplace uniquement le centre du corps, en conservant sa vitesse, ses dimensions et son état d’activité.

Syntaxe

c
void kq2d_body_set_pos(KQBody2D* body, s16 x, s16 y);

Paramètres

body

Pointeur vers le corps à modifier. Les champs non utilisés par cette opération sont conservés.

x

Coordonnée X du centre ou du point, en pixels dans l’exemple.

y

Coordonnée Y du centre ou du point ; le sens positif va vers le bas dans l’exemple.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

NULL est ignoré. Si le pointeur est valide, les corps inactifs et statiques sont également modifiés.

Exemple d’utilisation

c
kq2d_body_set_pos(&temp,-12,20);
    result[5]=temp.x; result[6]=temp.y;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

kq2d_body_set_pos: DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
kq2d_body_set_pos: CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body2d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body2d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:56

Notes de déclaration (texte source)
Replace the center without altering velocity, extents or activity. Null is ignored.

kitaqgb/lib/physics2d.c:612

c
void kq2d_body_set_pos(KQBody2D* body, s16 x, s16 y)
{
    if (body == 0) return;
    body->x = x;
    body->y = y;
}
kq2d_body_set_velocity

Fixe directement la vitesse, sans la borner ni modifier la position.

Syntaxe

c
void kq2d_body_set_velocity(KQBody2D* body, s16 vx, s16 vy);

Paramètres

body

Pointeur vers le corps à modifier. Les champs non utilisés par cette opération sont conservés.

vx

Déplacement selon X par tick de simulation, dans les mêmes unités que la position.

vy

Déplacement selon Y par tick de simulation, dans les mêmes unités que la position.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

NULL est ignoré. Si le pointeur est valide, les corps inactifs et statiques sont également modifiés.

Exemple d’utilisation

c
kq2d_body_set_velocity(&temp,40,-30);
    result[7]=temp.vx; result[8]=temp.vy;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

kq2d_body_set_velocity: DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
kq2d_body_set_velocity: CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body2d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body2d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:58

Notes de déclaration (texte source)
Replace velocity without clamping or checking activity/mass. Null is ignored.

kitaqgb/lib/physics2d.c:620

c
void kq2d_body_set_velocity(KQBody2D* body, s16 vx, s16 vy)
{
    if (body == 0) return;
    body->vx = vx;
    body->vy = vy;
}
kq2d_integrate_body

Applique la gravité du monde et les limites de vitesse par axe à un corps dynamique, puis ajoute sa vitesse à sa position.

Syntaxe

c
void kq2d_integrate_body(KQWorld2D* world, KQBody2D* body);

Paramètres

world

Pointeur vers le monde contenant le tableau de corps et les paramètres de simulation.

body

Pointeur vers le corps à modifier. Les champs non utilisés par cette opération sont conservés.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

Veillez à ce que sommes, différences, sommes de demi-dimensions et produits de correction des contacts restent dans la plage d’un entier signé de 16 bits. La limitation de vitesse intervient après l’addition et ne peut donc pas empêcher un dépassement pendant celle-ci.

Les routines d’intégration et de collision des boîtes partagent une zone de travail. Ne les rappelez pas depuis une interruption lorsqu’elles sont déjà en cours d’exécution.

Ignore NULL, les corps inactifs et ceux dont la masse inverse est nulle ou négative. Fournissez une limite de vitesse positive ou nulle.

Cet appel ne résout pas les contacts avec d’autres corps. Un monde NULL est également ignoré.

Exemple d’utilisation

c
kq2d_integrate_body(&world,&temp);
    result[18]=temp.x; result[19]=temp.y;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

kq2d_integrate_body: DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
kq2d_integrate_body: CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body2d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body2d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:47

Notes de déclaration (texte source)
For one active dynamic body, add gravity, clamp each velocity axis and then
add velocity to position. Null inputs are ignored; no contacts are solved.
Use a nonnegative speed limit and keep additions in signed 16-bit range.

kitaqgb/lib/physics2d.c:664

c
void kq2d_integrate_body(KQWorld2D* world, KQBody2D* body)
{
    if (world == 0) return;
    if (body == 0) return;
    if (body->active == 0) return;
    if (body->inv_mass_q8 <= 0) return;

    kq2d_asm_value = body->vx;
    kq2d_asm_operand = world->gravity_x;
    kq2d_add_s16_asm();
    kq2d_asm_limit = world->max_speed;
    kq2d_clamp_abs_s16_asm();
    body->vx = kq2d_asm_value;

    kq2d_asm_value = body->vy;
    kq2d_asm_operand = world->gravity_y;
    kq2d_add_s16_asm();
    kq2d_asm_limit = world->max_speed;
    kq2d_clamp_abs_s16_asm();
    body->vy = kq2d_asm_value;

    kq2d_asm_value = body->x;
    kq2d_asm_operand = body->vx;
    kq2d_add_s16_asm();
    body->x = kq2d_asm_value;

    kq2d_asm_value = body->y;
    kq2d_asm_operand = body->vy;
    kq2d_add_s16_asm();
    body->y = kq2d_asm_value;
}
kq2d_overlap_aabb

Teste le chevauchement strict de deux boîtes définies par leur centre sur les axes X et Y.

Syntaxe

c
u8 kq2d_overlap_aabb(const KQBody2D* a, const KQBody2D* b);

Paramètres

a

Pointeur valide vers un corps. La requête ignore l’activité, la masse et les indicateurs.

b

Pointeur valide vers un corps. La requête ignore l’activité, la masse et les indicateurs.

Valeur renvoyée

Renvoie 1 si les intérieurs se chevauchent, et 0 si les formes se touchent seulement ou sont séparées.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

Veillez à ce que sommes, différences, sommes de demi-dimensions et produits de correction des contacts restent dans la plage d’un entier signé de 16 bits. La limitation de vitesse intervient après l’addition et ne peut donc pas empêcher un dépassement pendant celle-ci.

Exemple d’utilisation

c
result[20]=kq2d_overlap_aabb(&bodies[0],&bodies[1]);
    bodies[1].x=40; result[21]=kq2d_overlap_aabb(&bodies[0],&bodies[1]);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

kq2d_overlap_aabb: DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
kq2d_overlap_aabb: CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body2d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body2d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:51

Notes de déclaration (texte source)
Test strict overlap of two centered boxes; touching edges return false.
Both pointers must be valid. Active/mass flags are ignored, and coordinate
differences and extent sums must fit the signed 16-bit calculations.

kitaqgb/lib/physics2d.c:579

c
u8 kq2d_overlap_aabb(const KQBody2D* a, const KQBody2D* b)
{
    s16 dx = (s16)(b->x - a->x);
    s16 dy = (s16)(b->y - a->y);

    s16 adx = kq2d__abs_s16(dx);
    s16 ady = kq2d__abs_s16(dy);

    s16 sx = (s16)(a->half_x + b->half_x);
    s16 sy = (s16)(a->half_y + b->half_y);

    if (adx >= sx) return 0;
    if (ady >= sy) return 0;
    return 1;
}
kq2d_point_in_rect

Teste si un point appartient au rectangle, bords gauche et supérieur inclus, bords droit et inférieur exclus.

Syntaxe

c
u8 kq2d_point_in_rect(s16 x, s16 y, KQRect r);

Paramètres

x

Coordonnée X du centre ou du point, en pixels dans l’exemple.

y

Coordonnée Y du centre ou du point ; le sens positif va vers le bas dans l’exemple.

r

Valeur KQRect contenant la position x/y du coin supérieur gauche et la largeur/hauteur w/h.

Valeur renvoyée

Renvoie 1 à l’intérieur et 0 à l’extérieur.

Conditions et limites

Veillez à ce que sommes, différences, sommes de demi-dimensions et produits de correction des contacts restent dans la plage d’un entier signé de 16 bits. La limitation de vitesse intervient après l’addition et ne peut donc pas empêcher un dépassement pendant celle-ci.

Exemple d’utilisation

c
result[16]=kq2d_point_in_rect(0,0,r1);
    result[17]=kq2d_point_in_rect(16,0,r1);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

kq2d_point_in_rect: DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
kq2d_point_in_rect: CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body2d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body2d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:72

Notes de déclaration (texte source)
Delegate the half-open point test: include left/top and exclude right/bottom.
Coordinate-plus-size sums must remain representable as s16.

kitaqgb/lib/physics2d.c:705

c
u8 kq2d_point_in_rect(s16 x, s16 y, KQRect r)
{
    return kq_point_in_rect(x, y, r);
}
kq2d_rect_intersect

Teste le chevauchement intérieur de deux rectangles représentés par leur coin supérieur gauche et leurs dimensions.

Syntaxe

c
u8 kq2d_rect_intersect(KQRect a, KQRect b);

Paramètres

a

Valeur KQRect avec les coordonnées du coin supérieur gauche et une largeur et une hauteur positives.

b

Valeur KQRect avec les coordonnées du coin supérieur gauche et une largeur et une hauteur positives.

Valeur renvoyée

Renvoie 1 si les intérieurs se chevauchent, et 0 si les formes se touchent seulement ou sont séparées.

Conditions et limites

Veillez à ce que sommes, différences, sommes de demi-dimensions et produits de correction des contacts restent dans la plage d’un entier signé de 16 bits. La limitation de vitesse intervient après l’addition et ne peut donc pas empêcher un dépassement pendant celle-ci.

Les dimensions nulles ou négatives ne sont pas explicitement rejetées. Ne copiez pas directement le centre et les demi-dimensions d’un corps dans un KQRect.

Exemple d’utilisation

c
result[14]=kq2d_rect_intersect(r1,r2);
    r2.x=16; result[15]=kq2d_rect_intersect(r1,r2);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

kq2d_rect_intersect: DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
kq2d_rect_intersect: CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body2d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body2d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:69

Notes de déclaration (texte source)
Delegate strict rectangle overlap to the fixed-point utility; edge-only
contact is false. Coordinate-plus-size sums must remain representable as s16.

kitaqgb/lib/physics2d.c:698

c
u8 kq2d_rect_intersect(KQRect a, KQRect b)
{
    return kq_rect_intersect(a, b);
}
kq2d_scale_q8

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Multiplie par un coefficient signé divisé par 256, avec troncature vers zéro pour les deux signes.

Syntaxe

c
s16 kq2d_scale_q8(s16 value, s16 coefficient);

Paramètres

value

Valeur signée de 16 bits à mettre à l’échelle.

coefficient

Coefficient signé de -256 à 256 ; 256 représente 1,0.

Valeur renvoyée

Renvoie le résultat signé de 16 bits, tronqué vers zéro.

Conditions et limites

Utilisez uniquement des coefficients de -256 à 256 ; +/-256 correspond à +/-1. Pour value=-32768 et coefficient=-256, le résultat mathématique est 32768, qui ne tient pas dans un s16.

Exemple d’utilisation

c
result[0]=kq2d_scale_q8(-257,128);
    result[1]=kq2d_scale_q8(300,-256);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.

kq2d_scale_q8: DMG — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.
DMG — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.
kq2d_scale_q8: CGB — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.
CGB — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_surface.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_surface.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:88

Notes de déclaration (texte source)
Truncates toward zero, including negative values; coefficient is -256..256.

kitaqgb/lib/physics2d.c:8

c
s16 kq2d_scale_q8(s16 value, s16 coefficient)
{
    // Eight-bit shift/add product in HL:C, with sign applied after truncation.
    __asm {
        LD_HL_IMM value
        LD_A_HL
        LD_E_A
        INC_HL
        LD_A_HL
        LD_D_A
        OR_E
        JP_Z kqscale_zero
        LD_HL_IMM coefficient
        LD_A_HL
        LD_C_A
        INC_HL
        LD_A_HL
        LD_B_A
        LD_A_C
        OR_A
        JR_NZ kqscale_fraction
        LD_A_B
        OR_A
        JP_Z kqscale_zero
        LD_H_D
        LD_L_E
        AND_IMM 128
        RET_Z
        JP kqscale_negate
kqscale_fraction:
        LD_A_D
        XOR_B
        AND_IMM 128
        PUSH_AF
        LD_A_D
        AND_IMM 128
        JR_Z kqscale_value_positive
        XOR_A
        SUB_E
        LD_E_A
        LD_A_IMM 0
        SBC_D
        LD_D_A
kqscale_value_positive:
        LD_A_B
        AND_IMM 128
        JR_Z kqscale_coefficient_positive
        XOR_A
        SUB_C
        LD_C_A
kqscale_coefficient_positive:
        LD_HL_IMM 0
        // Unroll eight bits: avoid a loop branch on every fixed-point product.
        LD_A_C
        AND_IMM 1
        JR_Z kqscale_shift_0
        ADD_HL_DE
kqscale_shift_0:
        LD_A_H
        RRA
        LD_H_A
        LD_A_L
        RRA
        LD_L_A
        LD_A_C
        RRA
        LD_C_A
        LD_A_C
        AND_IMM 1
        JR_Z kqscale_shift_1
        ADD_HL_DE
kqscale_shift_1:
        LD_A_H
        RRA
        LD_H_A
        LD_A_L
        RRA
        LD_L_A
        LD_A_C
        RRA
        LD_C_A
        LD_A_C
        AND_IMM 1
        JR_Z kqscale_shift_2
        ADD_HL_DE
kqscale_shift_2:
        LD_A_H
        RRA
        LD_H_A
        LD_A_L
        RRA
        LD_L_A
        LD_A_C
        RRA
        LD_C_A
        LD_A_C
        AND_IMM 1
        JR_Z kqscale_shift_3
        ADD_HL_DE
kqscale_shift_3:
        LD_A_H
        RRA
        LD_H_A
        LD_A_L
        RRA
        LD_L_A
        LD_A_C
        RRA
        LD_C_A
        LD_A_C
        AND_IMM 1
        JR_Z kqscale_shift_4
        ADD_HL_DE
kqscale_shift_4:
        LD_A_H
        RRA
        LD_H_A
        LD_A_L
        RRA
        LD_L_A
        LD_A_C
        RRA
        LD_C_A
        LD_A_C
        AND_IMM 1
        JR_Z kqscale_shift_5
        ADD_HL_DE
kqscale_shift_5:
        LD_A_H
        RRA
        LD_H_A
        LD_A_L
        RRA
        LD_L_A
        LD_A_C
        RRA
        LD_C_A
        LD_A_C
        AND_IMM 1
        JR_Z kqscale_shift_6
        ADD_HL_DE
kqscale_shift_6:
        LD_A_H
        RRA
        LD_H_A
        LD_A_L
        RRA
        LD_L_A
        LD_A_C
        RRA
        LD_C_A
        LD_A_C
        AND_IMM 1
        JR_Z kqscale_shift_7
        ADD_HL_DE
kqscale_shift_7:
        LD_A_H
        RRA
        LD_H_A
        LD_A_L
        RRA
        LD_L_A
        LD_A_C
        RRA
        LD_C_A
        POP_AF
        OR_A
        RET_Z
kqscale_negate:
        XOR_A
        SUB_L
        LD_L_A
        LD_A_IMM 0
        SBC_H
        LD_H_A
        RET
kqscale_zero:
        LD_HL_IMM 0
        RET
    }
}
kq2d_step

Intègre les corps dynamiques actifs, puis résout les contacts entre les entrées actives du tableau.

Syntaxe

c
void kq2d_step(KQWorld2D* world);

Paramètres

world

Pointeur vers le monde contenant le tableau de corps et les paramètres de simulation.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

Le monde emprunte son tableau : l’appelant alloue et possède la mémoire des corps et doit la garder valide. Initialiser le monde n’initialise pas les éléments du tableau.

Veillez à ce que sommes, différences, sommes de demi-dimensions et produits de correction des contacts restent dans la plage d’un entier signé de 16 bits. La limitation de vitesse intervient après l’addition et ne peut donc pas empêcher un dépassement pendant celle-ci.

Les contacts sont résolus selon l’axe de pénétration minimale, avec priorité à Y en cas d’égalité. La correction de position utilise les masses inverses, mais deux corps dynamiques reçoivent la moyenne simple de leurs vitesses sur cet axe ; une collision avec un corps statique annule cette composante. Le solveur n’utilise pas restitution_q8. La détection est discrète et peut manquer des traversées rapides.

Les routines d’intégration et de collision des boîtes partagent une zone de travail. Ne les rappelez pas depuis une interruption lorsqu’elles sont déjà en cours d’exécution.

Un monde ou un tableau NULL est ignoré. Même si solver_iterations vaut zéro, une passe de résolution des contacts est effectuée.

Exemple d’utilisation

c
kq2d_step(&world);
    result[22]=bodies[0].x; result[23]=bodies[0].y;
    result[24]=bodies[0].vx; result[25]=bodies[0].vy;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

kq2d_step: DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
kq2d_step: CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body2d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body2d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:43

Notes de déclaration (texte source)
Advance active dynamic bodies, then visit each active unordered pair for
the configured contact passes (zero means one). Static bodies still participate
as obstacles. The world borrows its array and shares non-reentrant ASM scratch.
This is discrete integration; fast bodies can pass through thin obstacles.

kitaqgb/lib/physics2d.c:794

c
void kq2d_step(KQWorld2D* world)
{
    if (world == 0) return;
    if (world->bodies == 0) return;

    KQBody2D* bodies = world->bodies;
    u8 count = world->body_count;

    // Integrate dynamic bodies.
    u8 i;
    for (i = 0; i < count; i++)
    {
        KQBody2D* b = &bodies[(__safe_index u8)i];
        if (b->active == 0) continue;
        if (b->inv_mass_q8 <= 0) continue;

        kq2d_asm_value = b->vx;
        kq2d_asm_operand = world->gravity_x;
        kq2d_add_s16_asm();
        kq2d_asm_limit = world->max_speed;
        kq2d_clamp_abs_s16_asm();
        b->vx = kq2d_asm_value;

        kq2d_asm_value = b->vy;
        kq2d_asm_operand = world->gravity_y;
        kq2d_add_s16_asm();
        kq2d_asm_limit = world->max_speed;
        kq2d_clamp_abs_s16_asm();
        b->vy = kq2d_asm_value;

        kq2d_asm_value = b->x;
        kq2d_asm_operand = b->vx;
        kq2d_add_s16_asm();
        b->x = kq2d_asm_value;

        kq2d_asm_value = b->y;
        kq2d_asm_operand = b->vy;
        kq2d_add_s16_asm();
        b->y = kq2d_asm_value;
    }

    // Solve contacts with a small fixed iteration count.
    u8 iterations = world->solver_iterations;
    if (iterations == 0) iterations = 1;

    u8 it;
    for (it = 0; it < iterations; it++)
    {
        for (i = 0; i < count; i++)
        {
            KQBody2D* a = &bodies[(__safe_index u8)i];
            if (a->active == 0) continue;

            u8 j;
            for (j = (u8)(i + 1); j < count; j++)
            {
                KQBody2D* b = &bodies[(__safe_index u8)j];
                if (b->active == 0) continue;
                kq2d__resolve_pair(a, b);
            }
        }
    }
}
kq2d_surface_toi_q8

Estime l’instant de franchissement à l’intérieur du tick à partir des écarts signés initial et final, en supposant un mouvement linéaire.

Syntaxe

c
u16 kq2d_surface_toi_q8(s16 start_gap, s16 end_gap);

Paramètres

start_gap

Écart signé au début du tick ; une valeur positive indique l’extérieur de la surface.

end_gap

Écart signé à la fin du tick ; une valeur négative indique que la surface a été franchie.

Valeur renvoyée

Renvoie un temps Q8 de 0 à 256 ; 192 représente 75 % du tick.

Conditions et limites

Gardez les écarts dans +/-8191. Un écart initial nul ou négatif renvoie 0 ; un écart final nul ou positif renvoie 256. Le chevauchement initial et l’instant zéro partagent la même valeur de retour, tout comme l’absence de franchissement et un contact exactement à la fin. Aucune position n’est modifiée.

Exemple d’utilisation

c
result[4]=kq2d_surface_toi_q8(6,-2);
    result[5]=kq2d_surface_toi_q8(6,0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.

kq2d_surface_toi_q8: DMG — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.
DMG — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.
kq2d_surface_toi_q8: CGB — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.
CGB — Le corps rouge reste en place. Son vecteur vitesse vert passe de (8,16) à gauche à (2,-8) à droite, montrant le rebond et le frottement tangent sur la surface bleue. Les origines des panneaux sont en (8,48)/(88,48) à l’écran ; le centre du corps est en (24,40) dans chaque panneau. La vitesse d’approche vaut 16 et l’exemple de temps de franchissement renvoie 192/256. L’exemple de limitation de vitesse réduit (300,400) à (147,196). Tous les repères sont noirs sur DMG.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_surface.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_surface.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:98

Notes de déclaration (texte source)
Linear crossing time in Q8 (0..256); positive separation is outside.
Returns 0 for initial overlap, 256 for no crossing. Gaps must fit +/-8191.

kitaqgb/lib/physics2d.c:291

c
u16 kq2d_surface_toi_q8(s16 start_gap, s16 end_gap)
{
    if (start_gap <= 0) return 0;
    if (end_gap >= 0) return 256;
    return kq2d__fraction_q8((u16)start_gap, (u16)(start_gap - end_gap));
}
kq2d_world_init

Associe un tableau à un monde 2D et règle la gravité à (0,32), le nombre d’itérations de contact à quatre et la limite de vitesse par axe à 512.

Syntaxe

c
void kq2d_world_init(KQWorld2D* world, KQBody2D* bodies, u8 body_count);

Paramètres

world

Pointeur vers le monde contenant le tableau de corps et les paramètres de simulation.

bodies

Début d’un tableau de corps appartenant à l’appelant et contenant body_count éléments.

body_count

Nombre d’emplacements du tableau, de 0 à 255, entrées inactives comprises.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

Le monde emprunte son tableau : l’appelant alloue et possède la mémoire des corps et doit la garder valide. Initialiser le monde n’initialise pas les éléments du tableau.

Exemple d’utilisation

c
kq2d_world_init(&world,bodies,2);
    result[0]=world.gravity_y; result[1]=world.solver_iterations; result[2]=world.max_speed;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

kq2d_world_init: DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
DMG — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
kq2d_world_init: CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.
CGB — À gauche, l’état initial ; à droite, après un tick. Une boîte rouge de 16x16, centrée en (24,24) avec une vitesse de (4,16), atteint (28,36) et sa vitesse Y s’annule sur le sol bleu. Les origines des panneaux sont aux coordonnées écran (8,48) et (88,48). Sur DMG, tous les repères sont noirs. Les contrôles RAM couvrent aussi l’initialisation, les fonctions de réglage, l’intégration, les tests de rectangles et de points et la mise à l’échelle signée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body2d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body2d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d.h:38

Notes de déclaration (texte source)
Retain the caller-owned body array without initializing its elements.
Set gravity to (0,32), four contact iterations and a per-axis speed limit of 512.
A null world is ignored; the array must outlive subsequent world operations.

kitaqgb/lib/physics2d.c:564

c
void kq2d_world_init(KQWorld2D* world, KQBody2D* bodies, u8 body_count)
{
    if (world == 0) return;

    world->bodies = bodies;
    world->body_count = body_count;
    world->gravity_x = 0;
    world->gravity_y = 32;
    world->solver_iterations = 4;
    world->max_speed = 512;
}

physics2d_circle.h — Physique des cercles

Gère le rayon des cercles, la masse inverse, la restitution, le frottement tangent, l’amortissement du monde et ses limites. L’appelant initialise tous les champs des corps. friction_q8 et wall_friction_q8 indiquent la part de mouvement tangent supprimée, tandis que linear_damping_q8 indique la part de vitesse conservée. Les coefficients sur un octet sont divisés par 256 : 255 n’est donc pas exactement 1,0.

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

La distance et les normales des cercles sont des approximations entières. Ramener chaque composante à 255 au plus ne garantit pas que la somme des carrés tienne dans 65535. Gardez les écarts entre centres, les sommes de rayons et de masses inverses dans leur plage représentable, et limitez inv_mass_q8 * 255 à 32767 pour le calcul des poids ; l’exemple utilise 64.

kq2dc_overlap_circle

Approxime le chevauchement intérieur à partir de la distance réduite entre centres et de la somme des rayons.

Syntaxe

c
u8 kq2dc_overlap_circle(const KQCircleBody2D* a, const KQCircleBody2D* b);

Paramètres

a

Pointeur valide vers le premier cercle.

b

Pointeur valide vers le second cercle.

Valeur renvoyée

Renvoie 1 si les intérieurs se chevauchent, et 0 si les formes se touchent seulement ou sont séparées.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

La distance et les normales des cercles sont des approximations entières. Ramener chaque composante à 255 au plus ne garantit pas que la somme des carrés tienne dans 65535. Gardez les écarts entre centres, les sommes de rayons et de masses inverses dans leur plage représentable, et limitez inv_mass_q8 * 255 à 32767 pour le calcul des poids ; l’exemple utilise 64.

Nécessite deux pointeurs valides et des rayons positifs. L’activité et la masse sont ignorées. La réduction et les racines carrées entières peuvent donner un résultat différent d’un test de distance géométrique exact.

Exemple d’utilisation

c
result[4]=kq2dc_overlap_circle(&balls[0],&balls[1]);
    balls[1].x=18; result[5]=kq2dc_overlap_circle(&balls[0],&balls[1]);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.

kq2dc_overlap_circle: DMG — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.
DMG — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.
kq2dc_overlap_circle: CGB — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.
CGB — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_circle.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_circle.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d_circle.h:55

Notes de déclaration (texte source)
Compare a reduced integer center distance with the reduced radius sum.
Valid pointers and positive radii are required; activity and mass are ignored.
This approximate test requires representable differences, radius sums and
squared-distance sum. Touching at the computed distance returns false.

kitaqgb/lib/physics2d_circle.c:397

c
u8 kq2dc_overlap_circle(const KQCircleBody2D* a, const KQCircleBody2D* b)
{
    s16 dx;
    s16 dy;
    s16 sdx;
    s16 sdy;
    u8 shift;
    u16 adx;
    u16 ady;
    u16 dist_sq;
    u16 dist_scaled;
    s16 radius_sum;
    u16 radius_sum_scaled;

    dx = (s16)(b->x - a->x);
    dy = (s16)(b->y - a->y);
    sdx = dx;
    sdy = dy;
    shift = kq2dc__reduce_vector(&sdx, &sdy);

    adx = (u16)kq2dc__abs_s16(sdx);
    ady = (u16)kq2dc__abs_s16(sdy);
    dist_sq = (u16)((adx * adx) + (ady * ady));
    dist_scaled = kq2dc__isqrt_u16(dist_sq);

    radius_sum = (s16)(a->radius + b->radius);
    radius_sum_scaled = kq2dc__scale_down_positive(radius_sum, shift);

    if (dist_scaled >= radius_sum_scaled) return 0;
    return 1;
}
kq2dc_set_bounds

Enregistre et active les limites du monde de cercles, sans déplacer immédiatement les corps.

Syntaxe

c
void kq2dc_set_bounds(KQCircleWorld2D* world, s16 min_x, s16 min_y, s16 max_x, s16 max_y);

Paramètres

world

Pointeur vers le monde contenant le tableau de corps et les paramètres de simulation.

min_x

Limite gauche ; le centre du cercle ne peut pas descendre sous min_x + radius.

min_y

Limite supérieure ; le centre du cercle ne peut pas descendre sous min_y + radius.

max_x

Limite droite ; le centre du cercle ne peut pas dépasser max_x - radius.

max_y

Limite inférieure ; le centre du cercle ne peut pas dépasser max_y - radius.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

NULL est ignoré. L’ordre des limites et l’espace disponible ne sont pas vérifiés : fournissez une largeur et une hauteur au moins égales au diamètre du cercle. La correction de position est effectuée lors d’un pas de simulation.

Exemple d’utilisation

c
kq2dc_set_bounds(&world,4,4,60,60);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.

kq2dc_set_bounds: DMG — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.
DMG — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.
kq2dc_set_bounds: CGB — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.
CGB — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_circle.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_circle.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d_circle.h:45

Notes de déclaration (texte source)
Store and enable bounds without validating their order or fitting bodies
immediately. Supply extents large enough for body diameters. Null is ignored.

kitaqgb/lib/physics2d_circle.c:382

c
void kq2dc_set_bounds(KQCircleWorld2D* world, s16 min_x, s16 min_y, s16 max_x, s16 max_y)
{
    if (world == 0) return;

    world->use_bounds = 1;
    world->min_x = min_x;
    world->min_y = min_y;
    world->max_x = max_x;
    world->max_y = max_y;
}
kq2dc_step

Intègre les cercles, résout les limites et les contacts entre cercles, puis applique l’amortissement linéaire.

Syntaxe

c
void kq2dc_step(KQCircleWorld2D* world);

Paramètres

world

Pointeur vers le monde contenant le tableau de corps et les paramètres de simulation.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

Le monde emprunte son tableau : l’appelant alloue et possède la mémoire des corps et doit la garder valide. Initialiser le monde n’initialise pas les éléments du tableau.

La distance et les normales des cercles sont des approximations entières. Ramener chaque composante à 255 au plus ne garantit pas que la somme des carrés tienne dans 65535. Gardez les écarts entre centres, les sommes de rayons et de masses inverses dans leur plage représentable, et limitez inv_mass_q8 * 255 à 32767 pour le calcul des poids ; l’exemple utilise 64.

Enfin, ramène à zéro les composantes de vitesse dans -1..1. Même un amortissement de 255 réduit un peu la vitesse. Des chevauchements entre cercles au repos peuvent subsister. Les cercles statiques sont eux aussi ramenés à l’intérieur des limites actives. Zéro itération signifie une passe ; un monde ou tableau NULL est ignoré. Ce solveur discret et quantifié peut traiter les contacts dans un ordre différent selon l’évolution des vitesses.

Exemple d’utilisation

c
kq2dc_step(&world);
    result[6]=balls[0].x; result[7]=balls[0].y; result[8]=balls[0].vx;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.

kq2dc_step: DMG — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.
DMG — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.
kq2dc_step: CGB — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.
CGB — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_circle.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_circle.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d_circle.h:50

Notes de déclaration (texte source)
Integrate active dynamic bodies, apply bounds, solve contacts, then damp
velocity and snap components in -1..1 to zero. Zero solver iterations means one.
Pairs with both velocities zero are skipped, so resting overlaps can remain.
Bounds can reposition static bodies; null world/array inputs are ignored.

kitaqgb/lib/physics2d_circle.c:433

c
void kq2dc_step(KQCircleWorld2D* world)
{
    KQCircleBody2D* bodies;
    u8 count;
    u8 i;
    u8 iterations;
    u8 it;

    if (world == 0) return;
    if (world->bodies == 0) return;

    bodies = world->bodies;
    count = world->body_count;

    for (i = 0; i < count; i++)
    {
        KQCircleBody2D* body = &bodies[(__safe_index u8)i];
        if (body->active == 0) continue;
        if (body->inv_mass_q8 <= 0)
        {
            if (world->use_bounds != 0) kq2dc__resolve_bounds(world, body);
            continue;
        }

        body->vx = (s16)(body->vx + world->gravity_x);
        body->vy = (s16)(body->vy + world->gravity_y);
        body->vx = kq2dc__clamp_abs(body->vx, world->max_speed);
        body->vy = kq2dc__clamp_abs(body->vy, world->max_speed);

        body->x = (s16)(body->x + body->vx);
        body->y = (s16)(body->y + body->vy);

        if (world->use_bounds != 0) kq2dc__resolve_bounds(world, body);
    }

    iterations = world->solver_iterations;
    if (iterations == 0) iterations = 1;

    for (it = 0; it < iterations; it++)
    {
        for (i = 0; i < count; i++)
        {
            KQCircleBody2D* a = &bodies[(__safe_index u8)i];
            if (a->active == 0) continue;
            if (a->vx == 0 && a->vy == 0) continue;

            if (world->use_bounds != 0) kq2dc__resolve_bounds(world, a);

            {
                u8 j;
                for (j = 0; j < count; j++)
                {
                    KQCircleBody2D* b = &bodies[(__safe_index u8)j];
                    s16 radius_sum;
                    if (j == i) continue;
                    if (b->active == 0) continue;
                    // Avoid revisiting an earlier moving body, but still allow a moving body
                    // to resolve against a stationary slot with a lower index. Velocities are live
                    // solver state, so contact ordering can change which later pairs are visited.
                    if (j < i && (b->vx != 0 || b->vy != 0)) continue;
                    radius_sum = (s16)(a->radius + b->radius);
                    if (kq2dc__abs_s16((s16)(b->x - a->x)) >= radius_sum) continue;
                    if (kq2dc__abs_s16((s16)(b->y - a->y)) >= radius_sum) continue;
                    kq2dc__resolve_pair(a, b);
                }
            }
        }
    }

    for (i = 0; i < count; i++)
    {
        KQCircleBody2D* body = &bodies[(__safe_index u8)i];
        if (body->active == 0) continue;
        if (body->inv_mass_q8 <= 0) continue;

        body->vx = kq2dc__mul_q8(body->vx, world->linear_damping_q8);
        body->vy = kq2dc__mul_q8(body->vy, world->linear_damping_q8);

        if (body->vx >= -1 && body->vx <= 1) body->vx = 0;
        if (body->vy >= -1 && body->vy <= 1) body->vy = 0;

        if (world->use_bounds != 0) kq2dc__resolve_bounds(world, body);
    }
}
kq2dc_world_init

Associe un tableau de cercles et règle la gravité à zéro, le nombre de passes à quatre, la limite par axe à 768 et l’amortissement à 252/256.

Syntaxe

c
void kq2dc_world_init(KQCircleWorld2D* world, KQCircleBody2D* bodies, u8 body_count);

Paramètres

world

Pointeur vers le monde contenant le tableau de corps et les paramètres de simulation.

bodies

Début d’un tableau de corps appartenant à l’appelant et contenant body_count éléments.

body_count

Nombre d’emplacements du tableau, de 0 à 255, entrées inactives comprises.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

Le monde emprunte son tableau : l’appelant alloue et possède la mémoire des corps et doit la garder valide. Initialiser le monde n’initialise pas les éléments du tableau.

Les limites sont initialement désactivées, avec les valeurs (0,0)..(159,143) ; la restitution des murs vaut 240 et leur frottement 16. Il n’existe pas de fonction d’initialisation des cercles : l’appelant doit renseigner tous les champs. Un monde NULL est ignoré.

Exemple d’utilisation

c
kq2dc_world_init(&world,balls,1);
    result[0]=world.gravity_y; result[1]=world.solver_iterations;
    result[2]=world.max_speed; result[3]=world.linear_damping_q8;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.

kq2dc_world_init: DMG — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.
DMG — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.
kq2dc_world_init: CGB — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.
CGB — Un cercle rouge de rayon 6 passe du centre (24,24) à gauche à (54,24) à droite. Les limites locales vont de (4,4) à (60,60). Le mur droit borne le centre à 54 et fait passer la vitesse X de 32 à -15 : restitution du mur de 128/256, puis amortissement de 255/256. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Sur DMG, le cercle et les limites sont noirs.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_circle.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_circle.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics2d_circle.h:42

Notes de déclaration (texte source)
Retain a caller-owned array without initializing bodies. Set zero gravity,
four contact passes, per-axis limit 768 and damping 252/256; bounds start disabled.
A null world is ignored. Keep the array alive for subsequent steps.

kitaqgb/lib/physics2d_circle.c:360

c
void kq2dc_world_init(KQCircleWorld2D* world, KQCircleBody2D* bodies, u8 body_count)
{
    if (world == 0) return;

    world->bodies = bodies;
    world->body_count = body_count;
    world->gravity_x = 0;
    world->gravity_y = 0;
    world->solver_iterations = 4;
    world->max_speed = 768;
    world->linear_damping_q8 = 252;
    world->use_bounds = 0;
    world->min_x = 0;
    world->min_y = 0;
    world->max_x = 159;
    world->max_y = 143;
    world->wall_restitution_q8 = 240;
    world->wall_friction_q8 = 16;
}

physics3d.h — Physique des AABB en 3D

Physique pour des boîtes 3D sans rotation, représentées par un centre et des demi-dimensions par axe. Masse et masse inverse pondèrent les contacts, restitution_q8 règle le rebond et ax/ay/az fournissent une accélération persistante. Le rendu est séparé. L’exemple affiche les vues de face et de dessus du même corps pour montrer le déplacement en profondeur et le rebond sur un mur.

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

physics3d.c réside dans la banque ROM 2. L’exemple utilise une ROM MBC5 de 128 Ko, inclut d’abord cette implémentation et place main dans la banque 0. Ne modifiez pas le mappage ROM depuis l’extérieur pendant un appel.

last_impact_speed mémorise la vitesse maximale de rapprochement sur un axe de contact. L’intégration la remet à zéro pour les corps dynamiques actifs ; les corps statiques ou inactifs la conservent. Ni break_speed ni KQ3D_BODY_BROKEN ne déclenche une destruction automatique. Le jeu décide quand casser un corps et modifie lui-même flags/active.

kq3d_body_init

Initialise le centre 3D, les demi-dimensions et la masse ; remet à zéro vitesse, accélération, impact et indicateurs, puis active le corps.

Syntaxe

c
void kq3d_body_init(KQBody3D* body, s16 x, s16 y, s16 z, s16 half_x, s16 half_y, s16 half_z, s16 mass_q8);

Paramètres

body

Pointeur vers le corps à modifier. Les champs non utilisés par cette opération sont conservés.

x

Coordonnée X du centre ou du point, en pixels dans l’exemple.

y

Coordonnée Y du centre ou du point ; le sens positif va vers le bas dans l’exemple.

z

Coordonnée Z du centre, représentée verticalement dans la vue de dessus de l’exemple.

half_x

Demi-dimension selon X ; la largeur totale de la boîte vaut deux fois cette valeur.

half_y

Demi-dimension selon Y ; la hauteur totale de la boîte vaut deux fois cette valeur.

half_z

Demi-dimension selon Z ; la profondeur totale vaut deux fois cette valeur.

mass_q8

Masse, avec 256 pour 1,0 ; une valeur nulle ou négative crée un corps statique.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

physics3d.c réside dans la banque ROM 2. L’exemple utilise une ROM MBC5 de 128 Ko, inclut d’abord cette implémentation et place main dans la banque 0. Ne modifiez pas le mappage ROM depuis l’extérieur pendant un appel.

La restitution vaut 224 et break_speed zéro. La masse suit les règles de kq3d_body_set_mass. NULL est ignoré ; l’appelant doit fournir des demi-dimensions valides.

Exemple d’utilisation

c
kq3d_body_init(&temp,10,20,30,8,8,8,256);
    result[3]=temp.inv_mass_q8; result[4]=temp.restitution_q8; result[5]=temp.active;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

kq3d_body_init: DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
kq3d_body_init: CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body3d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics3d.h:50

Notes de déclaration (texte source)
Initialize an active centered box with zero velocity/acceleration,
restitution 224, cleared impact/flags and mass set through the weight helper.
The caller supplies valid half extents. Null body is ignored.

kitaqgb/lib/physics3d.c:330

c
void kq3d_body_init(KQBody3D* body, s16 x, s16 y, s16 z, s16 half_x, s16 half_y, s16 half_z, s16 mass_q8)
{
    if (body == 0) return;

    body->x = x;
    body->y = y;
    body->z = z;
    body->vx = 0;
    body->vy = 0;
    body->vz = 0;
    body->ax = 0;
    body->ay = 0;
    body->az = 0;
    body->half_x = half_x;
    body->half_y = half_y;
    body->half_z = half_z;
    body->restitution_q8 = 224;
    body->break_speed = 0;
    body->last_impact_speed = 0;
    body->active = 1;
    body->flags = 0;
    kq3d_body_set_mass(body, mass_q8);
}
kq3d_body_set_mass

Enregistre la masse demandée et calcule un poids de masse inverse pour la correction et le rebond.

Syntaxe

c
void kq3d_body_set_mass(KQBody3D* body, s16 mass_q8);

Paramètres

body

Pointeur vers le corps à modifier. Les champs non utilisés par cette opération sont conservés.

mass_q8

Masse, avec 256 pour 1,0 ; une valeur nulle ou négative crée un corps statique.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

physics3d.c réside dans la banque ROM 2. L’exemple utilise une ROM MBC5 de 128 Ko, inclut d’abord cette implémentation et place main dans la banque 0. Ne modifiez pas le mappage ROM depuis l’extérieur pendant un appel.

Une masse nulle ou négative donne une masse inverse nulle, donc un corps statique. Pour une masse positive, le calcul entier est 32767/max(mass,64), avec un minimum de 1. La masse stockée conserve la valeur demandée : le poids obtenu n’est pas un inverse Q8 exact. Une masse de 256 donne une masse inverse de 127. Vitesse et activité restent inchangées ; NULL est ignoré.

Exemple d’utilisation

c
kq3d_body_set_mass(&temp,32); result[6]=temp.mass_q8; result[7]=temp.inv_mass_q8;
    kq3d_body_set_mass(&temp,0); result[8]=temp.inv_mass_q8;
    kq3d_body_set_mass(&temp,256);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

kq3d_body_set_mass: DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
kq3d_body_set_mass: CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body3d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics3d.h:55

Notes de déclaration (texte source)
Store the requested mass; nonpositive mass makes the body static.
For positive mass compute inverse weight as max(1,32767/max(mass,64)).
The stored mass retains the original input; this is a relative solver weight,
not an exact Q8 reciprocal. Null body is ignored.

kitaqgb/lib/physics3d.c:311

c
void kq3d_body_set_mass(KQBody3D* body, s16 mass_q8)
{
    if (body == 0) return;

    body->mass_q8 = mass_q8;
    if (mass_q8 <= 0)
    {
        body->inv_mass_q8 = 0;
        return;
    }

    if (mass_q8 < 64) mass_q8 = 64;
    body->inv_mass_q8 = (s16)(32767 / mass_q8);
    if (body->inv_mass_q8 <= 0) body->inv_mass_q8 = 1;
}
kq3d_dot_q8_8

Divise chacun des trois produits signés par 256, tronque chaque terme vers zéro, puis additionne les termes.

Syntaxe

c
s16 kq3d_dot_q8_8(s16 x, s16 y, s16 z, s8 ax, s8 ay, s8 az);

Paramètres

x

Composante signée de 16 bits à multiplier par le coefficient correspondant ; elle peut représenter une position ou une vitesse.

y

Composante signée de 16 bits à multiplier par le coefficient correspondant ; elle peut représenter une position ou une vitesse.

z

Composante signée de 16 bits à multiplier par le coefficient correspondant ; elle peut représenter une position ou une vitesse.

ax

Coefficient signé sur un octet pour cet axe (-128..127), appliqué à l’échelle 1/256.

ay

Coefficient signé sur un octet pour cet axe (-128..127), appliqué à l’échelle 1/256.

az

Coefficient signé sur un octet pour cet axe (-128..127), appliqué à l’échelle 1/256.

Valeur renvoyée

Renvoie la somme des trois termes quantifiés en s16.

Conditions et limites

physics3d.c réside dans la banque ROM 2. L’exemple utilise une ROM MBC5 de 128 Ko, inclut d’abord cette implémentation et place main dans la banque 0. Ne modifiez pas le mappage ROM depuis l’extérieur pendant un appel.

Tronquer chaque terme vers zéro avant la somme peut donner un résultat différent d’un unique décalage de la somme totale. Un coefficient ne peut pas contenir 1,0=256. La somme finale n’est pas saturée.

Exemple d’utilisation

c
result[13]=kq3d_dot_q8_8(256,128,0,64,-64,127);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

kq3d_dot_q8_8: DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
kq3d_dot_q8_8: CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body3d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics3d.h:74

Notes de déclaration (texte source)
Sum three signed products, shifting each by eight bits before addition.
Coefficients are signed bytes scaled by 1/256; the 16-bit sum is not saturated.

kitaqgb/lib/physics3d.c:576

c
s16 kq3d_dot_q8_8(s16 x, s16 y, s16 z, s8 ax, s8 ay, s8 az)
{
    return __sdot3_q8_8(x, y, z, ax, ay, az);
}
kq3d_integrate_body

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Remet à zéro l’impact d’un corps dynamique actif, ajoute la gravité du monde et l’accélération du corps, borne chaque composante de vitesse puis avance sa position.

Syntaxe

c
void kq3d_integrate_body(KQWorld3D* world, KQBody3D* body);

Paramètres

world

Pointeur vers le monde contenant le tableau de corps et les paramètres de simulation.

body

Pointeur vers le corps à modifier. Les champs non utilisés par cette opération sont conservés.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

Veillez à ce que sommes, différences, sommes de demi-dimensions et produits de correction des contacts restent dans la plage d’un entier signé de 16 bits. La limitation de vitesse intervient après l’addition et ne peut donc pas empêcher un dépassement pendant celle-ci.

Les routines d’intégration et de collision des boîtes partagent une zone de travail. Ne les rappelez pas depuis une interruption lorsqu’elles sont déjà en cours d’exécution.

physics3d.c réside dans la banque ROM 2. L’exemple utilise une ROM MBC5 de 128 Ko, inclut d’abord cette implémentation et place main dans la banque 0. Ne modifiez pas le mappage ROM depuis l’extérieur pendant un appel.

last_impact_speed mémorise la vitesse maximale de rapprochement sur un axe de contact. L’intégration la remet à zéro pour les corps dynamiques actifs ; les corps statiques ou inactifs la conservent. Ni break_speed ni KQ3D_BODY_BROKEN ne déclenche une destruction automatique. Le jeu décide quand casser un corps et modifie lui-même flags/active.

ax/ay/az persistent et s’appliquent à nouveau à l’intégration suivante. Cette fonction seule ne résout pas les contacts. NULL, les corps inactifs et les corps statiques ne sont pas modifiés.

Exemple d’utilisation

c
kq3d_integrate_body(&world,&temp);
    result[9]=temp.x; result[10]=temp.y; result[11]=temp.z; result[12]=temp.last_impact_speed;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

kq3d_integrate_body: DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
kq3d_integrate_body: CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body3d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics3d.h:66

Notes de déclaration (texte source)
Reset impact for one active dynamic body, add gravity and persistent body
acceleration, clamp velocity per axis and advance position. Static/inactive
bodies retain impact state. Null inputs are ignored; no contacts are solved.
Use a nonnegative speed limit and avoid overflow before clamping.

kitaqgb/lib/physics3d.c:436

c
void kq3d_integrate_body(KQWorld3D* world, KQBody3D* body)
{
    if (world == 0) return;
    if (body == 0) return;
    if (body->active == 0) return;
    if (body->inv_mass_q8 <= 0) return;

    body->last_impact_speed = 0;
    kq3d_asm_value = body->vx;
    kq3d_asm_operand = world->gravity_x;
    kq3d_add_s16_asm();
    kq3d_asm_operand = body->ax;
    kq3d_add_s16_asm();
    kq3d_asm_limit = world->max_speed;
    kq3d_clamp_abs_s16_asm();
    body->vx = kq3d_asm_value;

    kq3d_asm_value = body->vy;
    kq3d_asm_operand = world->gravity_y;
    kq3d_add_s16_asm();
    kq3d_asm_operand = body->ay;
    kq3d_add_s16_asm();
    kq3d_asm_limit = world->max_speed;
    kq3d_clamp_abs_s16_asm();
    body->vy = kq3d_asm_value;

    kq3d_asm_value = body->vz;
    kq3d_asm_operand = world->gravity_z;
    kq3d_add_s16_asm();
    kq3d_asm_operand = body->az;
    kq3d_add_s16_asm();
    kq3d_asm_limit = world->max_speed;
    kq3d_clamp_abs_s16_asm();
    body->vz = kq3d_asm_value;

    kq3d_asm_value = body->x;
    kq3d_asm_operand = body->vx;
    kq3d_add_s16_asm();
    body->x = kq3d_asm_value;

    kq3d_asm_value = body->y;
    kq3d_asm_operand = body->vy;
    kq3d_add_s16_asm();
    body->y = kq3d_asm_value;

    kq3d_asm_value = body->z;
    kq3d_asm_operand = body->vz;
    kq3d_add_s16_asm();
    body->z = kq3d_asm_value;
}
kq3d_overlap_aabb

Teste le chevauchement strict de deux boîtes définies par leur centre sur les trois axes.

Syntaxe

c
u8 kq3d_overlap_aabb(const KQBody3D* a, const KQBody3D* b);

Paramètres

a

Pointeur valide vers un corps. La requête ignore l’activité, la masse et les indicateurs.

b

Pointeur valide vers un corps. La requête ignore l’activité, la masse et les indicateurs.

Valeur renvoyée

Renvoie 1 si les intérieurs se chevauchent, et 0 si les formes se touchent seulement ou sont séparées.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

Veillez à ce que sommes, différences, sommes de demi-dimensions et produits de correction des contacts restent dans la plage d’un entier signé de 16 bits. La limitation de vitesse intervient après l’addition et ne peut donc pas empêcher un dépassement pendant celle-ci.

physics3d.c réside dans la banque ROM 2. L’exemple utilise une ROM MBC5 de 128 Ko, inclut d’abord cette implémentation et place main dans la banque 0. Ne modifiez pas le mappage ROM depuis l’extérieur pendant un appel.

Exemple d’utilisation

c
result[14]=kq3d_overlap_aabb(&bodies[0],&bodies[1]);
    bodies[1].z=32; result[15]=kq3d_overlap_aabb(&bodies[0],&bodies[1]);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

kq3d_overlap_aabb: DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
kq3d_overlap_aabb: CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body3d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics3d.h:70

Notes de déclaration (texte source)
Test strict overlap on all three axes; face-only contact returns false.
Valid pointers are required and flags are ignored. Center differences and
extent sums must fit the signed 16-bit magnitude calculations.

kitaqgb/lib/physics3d.c:357

c
u8 kq3d_overlap_aabb(const KQBody3D* a, const KQBody3D* b)
{
    s16 dx = kq3d__abs_s16((s16)(b->x - a->x));
    s16 dy = kq3d__abs_s16((s16)(b->y - a->y));
    s16 dz = kq3d__abs_s16((s16)(b->z - a->z));

    s16 sx = (s16)(a->half_x + b->half_x);
    s16 sy = (s16)(a->half_y + b->half_y);
    s16 sz = (s16)(a->half_z + b->half_z);

    if (dx >= sx) return 0;
    if (dy >= sy) return 0;
    if (dz >= sz) return 0;
    return 1;
}
kq3d_step

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Intègre les corps dynamiques actifs et traite la correction des contacts, les rebonds et les enregistrements d’impact entre les entrées actives du monde.

Syntaxe

c
void kq3d_step(KQWorld3D* world);

Paramètres

world

Pointeur vers le monde contenant le tableau de corps et les paramètres de simulation.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

Le monde emprunte son tableau : l’appelant alloue et possède la mémoire des corps et doit la garder valide. Initialiser le monde n’initialise pas les éléments du tableau.

Veillez à ce que sommes, différences, sommes de demi-dimensions et produits de correction des contacts restent dans la plage d’un entier signé de 16 bits. La limitation de vitesse intervient après l’addition et ne peut donc pas empêcher un dépassement pendant celle-ci.

Les routines d’intégration et de collision des boîtes partagent une zone de travail. Ne les rappelez pas depuis une interruption lorsqu’elles sont déjà en cours d’exécution.

physics3d.c réside dans la banque ROM 2. L’exemple utilise une ROM MBC5 de 128 Ko, inclut d’abord cette implémentation et place main dans la banque 0. Ne modifiez pas le mappage ROM depuis l’extérieur pendant un appel.

Les contacts utilisent l’axe de pénétration minimale, avec priorité à X, puis Y, puis Z en cas d’égalité. Seul un mouvement de rapprochement produit un rebond, calculé avec les masses inverses et la restitution moyenne bornée à 0..256. Les traversées rapides, la rotation, le moment cinétique et le frottement ne sont pas gérés.

last_impact_speed mémorise la vitesse maximale de rapprochement sur un axe de contact. L’intégration la remet à zéro pour les corps dynamiques actifs ; les corps statiques ou inactifs la conservent. Ni break_speed ni KQ3D_BODY_BROKEN ne déclenche une destruction automatique. Le jeu décide quand casser un corps et modifie lui-même flags/active.

Un monde ou un tableau NULL est ignoré. Même si solver_iterations vaut zéro, une passe de résolution des contacts est effectuée.

Les produits intermédiaires impact*(256+restitution) et correction*inverse-mass sont eux aussi en s16. Gardez-les à 32767 au plus ; par exemple, avec restitution à 256, limitez impact à 63.

Exemple d’utilisation

c
kq3d_step(&world);
    result[16]=bodies[0].x; result[17]=bodies[0].y; result[18]=bodies[0].z;
    result[19]=bodies[0].vx; result[20]=bodies[0].vz;
    result[21]=bodies[0].last_impact_speed; result[22]=bodies[0].flags;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

kq3d_step: DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
kq3d_step: CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body3d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics3d.h:61

Notes de déclaration (texte source)
Integrate active dynamic bodies and reset their impact values, then solve
each active unordered pair for the configured passes (zero means one).
Static bodies retain previous impact maxima until the game clears them.
Acceleration persists; flags and break thresholds remain game-owned.
This discrete solver shares non-reentrant ASM scratch and can miss fast crossings.

kitaqgb/lib/physics3d.c:492

c
void kq3d_step(KQWorld3D* world)
{
    if (world == 0) return;
    if (world->bodies == 0) return;

    KQBody3D* bodies = world->bodies;
    u8 count = world->body_count;

    u8 i;
    for (i = 0; i < count; i++)
    {
        KQBody3D* b = &bodies[(__safe_index u8)i];
        if (b->active == 0) continue;
        if (b->inv_mass_q8 <= 0) continue;

        b->last_impact_speed = 0;
        kq3d_asm_value = b->vx;
        kq3d_asm_operand = world->gravity_x;
        kq3d_add_s16_asm();
        kq3d_asm_operand = b->ax;
        kq3d_add_s16_asm();
        kq3d_asm_limit = world->max_speed;
        kq3d_clamp_abs_s16_asm();
        b->vx = kq3d_asm_value;

        kq3d_asm_value = b->vy;
        kq3d_asm_operand = world->gravity_y;
        kq3d_add_s16_asm();
        kq3d_asm_operand = b->ay;
        kq3d_add_s16_asm();
        kq3d_asm_limit = world->max_speed;
        kq3d_clamp_abs_s16_asm();
        b->vy = kq3d_asm_value;

        kq3d_asm_value = b->vz;
        kq3d_asm_operand = world->gravity_z;
        kq3d_add_s16_asm();
        kq3d_asm_operand = b->az;
        kq3d_add_s16_asm();
        kq3d_asm_limit = world->max_speed;
        kq3d_clamp_abs_s16_asm();
        b->vz = kq3d_asm_value;

        kq3d_asm_value = b->x;
        kq3d_asm_operand = b->vx;
        kq3d_add_s16_asm();
        b->x = kq3d_asm_value;

        kq3d_asm_value = b->y;
        kq3d_asm_operand = b->vy;
        kq3d_add_s16_asm();
        b->y = kq3d_asm_value;

        kq3d_asm_value = b->z;
        kq3d_asm_operand = b->vz;
        kq3d_add_s16_asm();
        b->z = kq3d_asm_value;
    }

    u8 iterations = world->solver_iterations;
    if (iterations == 0) iterations = 1;

    u8 it;
    for (it = 0; it < iterations; it++)
    {
        for (i = 0; i < count; i++)
        {
            KQBody3D* a = &bodies[(__safe_index u8)i];
            if (a->active == 0) continue;

            u8 j;
            for (j = (u8)(i + 1); j < count; j++)
            {
                KQBody3D* b = &bodies[(__safe_index u8)j];
                if (b->active == 0) continue;
                kq3d__resolve_pair(a, b);
            }
        }
    }
}
kq3d_world_init

Associe un tableau de corps à un monde 3D avec une gravité de (0,24,0), quatre passes et une limite de vitesse par axe de 512.

Syntaxe

c
void kq3d_world_init(KQWorld3D* world, KQBody3D* bodies, u8 body_count);

Paramètres

world

Pointeur vers le monde contenant le tableau de corps et les paramètres de simulation.

bodies

Début d’un tableau de corps appartenant à l’appelant et contenant body_count éléments.

body_count

Nombre d’emplacements du tableau, de 0 à 255, entrées inactives comprises.

Valeur renvoyée

Aucune valeur de retour. Cette rubrique décrit les champs modifiés et le moment où les changements prennent effet.

Conditions et limites

Utilisez des unités entières cohérentes pour les positions, rayons, demi-dimensions, vitesses et la gravité. Un pas correspond à un tick de simulation. Les exemples utilisent une unité par pixel. Ces routines ne convertissent pas automatiquement les positions en Q8.8 et n’effectuent aucun rendu.

Le monde emprunte son tableau : l’appelant alloue et possède la mémoire des corps et doit la garder valide. Initialiser le monde n’initialise pas les éléments du tableau.

physics3d.c réside dans la banque ROM 2. L’exemple utilise une ROM MBC5 de 128 Ko, inclut d’abord cette implémentation et place main dans la banque 0. Ne modifiez pas le mappage ROM depuis l’extérieur pendant un appel.

Exemple d’utilisation

c
kq3d_world_init(&world,bodies,2);
    result[0]=world.gravity_y; result[1]=world.solver_iterations; result[2]=world.max_speed;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

kq3d_world_init: DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
DMG — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
kq3d_world_init: CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.
CGB — À gauche, la vue de face X/Y ; à droite, la vue de dessus X/Z. Les contours verts indiquent la position initiale (24,24,16), les boîtes rouges la position (36,24,24) après un tick, et les zones bleues l’obstacle statique. La vitesse X passe de 16 à -14 par rebond, tandis que la vitesse Z reste à 8. L’impact vaut 16, mais flags reste à zéro malgré break_speed=1. Les origines des panneaux sont en (8,48)/(88,48) à l’écran. Tous les repères sont noirs sur DMG.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\physics_body3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\physics_body3d.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=128k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/physics3d.h:46

Notes de déclaration (texte source)
Borrow the body array without initializing it. Set gravity (0,24,0), four
contact passes and a per-axis speed limit of 512. Null world is ignored;
the caller retains ownership and must keep the array alive.

kitaqgb/lib/physics3d.c:294

c
void kq3d_world_init(KQWorld3D* world, KQBody3D* bodies, u8 body_count)
{
    if (world == 0) return;

    world->bodies = bodies;
    world->body_count = body_count;
    world->gravity_x = 0;
    world->gravity_y = 24;
    world->gravity_z = 0;
    world->solver_iterations = 4;
    world->max_speed = 512;
}

raster.h — Tables de défilement par bandes et lignes

La bibliothèque Raster propose une table de huit bandes et un moteur LineX qui modifie X sur les 144 lignes visibles. Les bandes conviennent aux HUD fixes, à la parallaxe, aux changements de fenêtre et aux régions colorées CGB. LineX convient aux titres ondulants et aux effets d’écran. Choisissez un seul pilote ; ne les exécutez pas ensemble.

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Vague par lignes de balayage et apparition animée du titre

En modifiant la position X du fond à chaque ligne de l’écran, on fait onduler les piliers et les lettres. Cet effet convient à une téléportation, à l’arrivée d’un boss ou à un titre. L’aperçu ci-dessous fait défiler huit captures ; dans la ROM, la phase de l’onde avance à chaque image.

Les opérations Raster_Push programment jusqu’à huit bandes. Utilisez Raster_LineXRunFrame pour donner un décalage horizontal distinct à chaque ligne. Les sprites et la fenêtre ne sont pas déformés. Le rendu monopolise le CPU et masque les interruptions pendant les 144 lignes visibles ; mettez donc à jour la logique du jeu et l’audio entre les appels.

Capture CGB : chaque ligne courbe les bords des piliers. Une onde de 64 lignes traverse la scène, avec un déplacement maximal de 24 pixels dans chaque direction.
Capture CGB : chaque ligne courbe les bords des piliers. Une onde de 64 lignes traverse la scène, avec un déplacement maximal de 24 pixels dans chaque direction.

Exemple d’onde continue

Exemple d’apparition du titre

Le titre arrive de la droite avec une grande ondulation, passe à une petite oscillation puis se stabilise. Le programme inclut raster_wave.c du même répertoire ; gardez donc les deux sources ensemble. Les entrées API ci-dessous donnent les commandes de compilation et les conseils d’utilisation propres à chaque fonction.

La bibliothèque Raster propose une table de huit bandes et un moteur LineX qui modifie X sur les 144 lignes visibles. Les bandes conviennent aux HUD fixes, à la parallaxe, aux changements de fenêtre et aux régions colorées CGB. LineX convient aux titres ondulants et aux effets d’écran. Choisissez un seul pilote ; ne les exécutez pas ensemble.

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Raster_BuildHudBottom

Construit une zone de jeu supérieure défilante et un HUD inférieur fixe. LY=0 utilise les coordonnées caméra ; hud_y revient au fond (0,0).

Syntaxe

c
u8 Raster_BuildHudBottom(u8 hud_y, u8 camera_x, u8 camera_y);

Paramètres

hud_y

Ligne de séparation, de 1 à 143. Zéro et les valeurs à partir de 144 renvoient BAD_RANGE.

camera_x

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

camera_y

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

Valeur renvoyée

Renvoie KQ_RASTER_OK (0) en cas de succès, ou un état d’erreur de 1 à 4. Consultez les contraintes de la fonction et Raster_GetLastError.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

Des paramètres valides arrêtent les divisions existantes, vident la table et ajoutent les nouvelles bandes. Des paramètres invalides préservent la table et son compteur, tout en mémorisant BAD_RANGE. Même après une construction réussie, Raster_Commit reste nécessaire.

Exemple d’utilisation

c
Raster_BuildHudBottom(96,8,8);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Les lignes à partir de 96 restent fixes. La caméra (8,8) place les rectangles supérieurs en (24,8) et (24,72), tandis que celui du bas reste en (32,112). FIXED BOTTOM HUD demeure en bas.

Raster_BuildHudBottom: DMG — Les lignes à partir de 96 restent fixes. La caméra (8,8) place les rectangles supérieurs en (24,8) et (24,72), tandis que celui du bas reste en (32,112). FIXED BOTTOM HUD demeure en bas.
DMG — Les lignes à partir de 96 restent fixes. La caméra (8,8) place les rectangles supérieurs en (24,8) et (24,72), tandis que celui du bas reste en (32,112). FIXED BOTTOM HUD demeure en bas.
Raster_BuildHudBottom: CGB — Les lignes à partir de 96 restent fixes. La caméra (8,8) place les rectangles supérieurs en (24,8) et (24,72), tandis que celui du bas reste en (32,112). FIXED BOTTOM HUD demeure en bas.
CGB — Les lignes à partir de 96 restent fixes. La caméra (8,8) place les rectangles supérieurs en (24,8) et (24,72), tandis que celui du bas reste en (32,112). FIXED BOTTOM HUD demeure en bas.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_hud_bottom.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:73

Notes de déclaration (texte source)
Build a scrolling upper playfield and fixed bottom HUD after validating the split.

kitaqgb/lib/raster.c:183

c
u8 Raster_BuildHudBottom(u8 hud_y, u8 camera_x, u8 camera_y)
{
    u8 r;

    if (hud_y == 0) return Raster_SetError(KQ_RASTER_BAD_RANGE);
    if (hud_y >= 144) return Raster_SetError(KQ_RASTER_BAD_RANGE);

    Raster_Clear();
    r = Raster_Push(0, camera_x, camera_y);
    if (r != KQ_RASTER_OK) return r;
    return Raster_Push(hud_y, 0, 0);
}
Raster_BuildHudTop

Construit deux bandes de fond pour un HUD supérieur fixe : (0,0) à LY=0, puis les coordonnées caméra à hud_height. Cela divise le défilement du fond sans utiliser la fenêtre.

Syntaxe

c
u8 Raster_BuildHudTop(u8 hud_height, u8 camera_x, u8 camera_y);

Paramètres

hud_height

Ligne de séparation, de 1 à 143. Zéro et les valeurs à partir de 144 renvoient BAD_RANGE.

camera_x

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

camera_y

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

Valeur renvoyée

Renvoie KQ_RASTER_OK (0) en cas de succès, ou un état d’erreur de 1 à 4. Consultez les contraintes de la fonction et Raster_GetLastError.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

Des paramètres valides arrêtent les divisions existantes, vident la table et ajoutent les nouvelles bandes. Des paramètres invalides préservent la table et son compteur, tout en mémorisant BAD_RANGE. Même après une construction réussie, Raster_Commit reste nécessaire.

Exemple d’utilisation

c
Raster_BuildHudTop(32,8,8);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Les 32 premières lignes restent fixes. Le rectangle supérieur reste en (32,16) ; la caméra (8,8) déplace les deux autres en (24,72) et (24,104). FIXED TOP HUD demeure en haut.

Raster_BuildHudTop: DMG — Les 32 premières lignes restent fixes. Le rectangle supérieur reste en (32,16) ; la caméra (8,8) déplace les deux autres en (24,72) et (24,104). FIXED TOP HUD demeure en haut.
DMG — Les 32 premières lignes restent fixes. Le rectangle supérieur reste en (32,16) ; la caméra (8,8) déplace les deux autres en (24,72) et (24,104). FIXED TOP HUD demeure en haut.
Raster_BuildHudTop: CGB — Les 32 premières lignes restent fixes. Le rectangle supérieur reste en (32,16) ; la caméra (8,8) déplace les deux autres en (24,72) et (24,104). FIXED TOP HUD demeure en haut.
CGB — Les 32 premières lignes restent fixes. Le rectangle supérieur reste en (32,16) ; la caméra (8,8) déplace les deux autres en (24,72) et (24,104). FIXED TOP HUD demeure en haut.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_hud_top.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:71

Notes de déclaration (texte source)
Validate the HUD height, then replace pending splits with a fixed top band
and scrolling playfield. The new table still requires an explicit commit.

kitaqgb/lib/raster.c:169

c
u8 Raster_BuildHudTop(u8 hud_height, u8 camera_x, u8 camera_y)
{
    u8 r;

    if (hud_height == 0) return Raster_SetError(KQ_RASTER_BAD_RANGE);
    if (hud_height >= 144) return Raster_SetError(KQ_RASTER_BAD_RANGE);

    Raster_Clear();
    r = Raster_Push(0, 0, 0);
    if (r != KQ_RASTER_OK) return r;
    return Raster_Push(hud_height, camera_x, camera_y);
}
Raster_BuildParallax2

Construit deux bandes de fond avec des décalages horizontaux distincts : far_scx à LY=0 et near_scx à partir de split_y, avec le même défilement Y.

Syntaxe

c
u8 Raster_BuildParallax2(u8 split_y, u8 far_scx, u8 near_scx, u8 scy);

Paramètres

split_y

Ligne de séparation, de 1 à 143. Zéro et les valeurs à partir de 144 renvoient BAD_RANGE.

far_scx

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

near_scx

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

scy

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

Valeur renvoyée

Renvoie KQ_RASTER_OK (0) en cas de succès, ou un état d’erreur de 1 à 4. Consultez les contraintes de la fonction et Raster_GetLastError.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

Des paramètres valides arrêtent les divisions existantes, vident la table et ajoutent les nouvelles bandes. Des paramètres invalides préservent la table et son compteur, tout en mémorisant BAD_RANGE. Même après une construction réussie, Raster_Commit reste nécessaire.

Exemple d’utilisation

c
Raster_BuildParallax2(64,0,16,0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

X passe de 0 à 16 à la ligne programmée 64. Les rectangles apparaissent en (32,16), (16,80) et (16,112) ; seule la région inférieure se décale de seize pixels vers la gauche.

Raster_BuildParallax2: DMG — X passe de 0 à 16 à la ligne programmée 64. Les rectangles apparaissent en (32,16), (16,80) et (16,112) ; seule la région inférieure se décale de seize pixels vers la gauche.
DMG — X passe de 0 à 16 à la ligne programmée 64. Les rectangles apparaissent en (32,16), (16,80) et (16,112) ; seule la région inférieure se décale de seize pixels vers la gauche.
Raster_BuildParallax2: CGB — X passe de 0 à 16 à la ligne programmée 64. Les rectangles apparaissent en (32,16), (16,80) et (16,112) ; seule la région inférieure se décale de seize pixels vers la gauche.
CGB — X passe de 0 à 16 à la ligne programmée 64. Les rectangles apparaissent en (32,16), (16,80) et (16,112) ; seule la région inférieure se décale de seize pixels vers la gauche.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_parallax2.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:76

Notes de déclaration (texte source)
Build two horizontal-scroll bands sharing one vertical scroll value.

kitaqgb/lib/raster.c:197

c
u8 Raster_BuildParallax2(u8 split_y, u8 far_scx, u8 near_scx, u8 scy)
{
    u8 r;

    if (split_y == 0) return Raster_SetError(KQ_RASTER_BAD_RANGE);
    if (split_y >= 144) return Raster_SetError(KQ_RASTER_BAD_RANGE);

    Raster_Clear();
    r = Raster_Push(0, far_scx, scy);
    if (r != KQ_RASTER_OK) return r;
    return Raster_Push(split_y, near_scx, scy);
}
Raster_BuildParallax3

Enregistre scx0, scx1 et scx2 pour les bandes commençant à LY=0, y1 et y2. Attribue des décalages horizontaux distincts aux plans lointain, intermédiaire et proche, tout en partageant le défilement Y.

Syntaxe

c
u8 Raster_BuildParallax3(u8 y1, u8 y2, u8 scx0, u8 scx1, u8 scx2, u8 scy);

Paramètres

y1

Lignes de séparation, avec 1 <= y1 < y2 <= 143.

y2

Lignes de séparation, avec 1 <= y1 < y2 <= 143.

scx0

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

scx1

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

scx2

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

scy

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

Valeur renvoyée

Renvoie KQ_RASTER_OK (0) en cas de succès, ou un état d’erreur de 1 à 4. Consultez les contraintes de la fonction et Raster_GetLastError.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

Des paramètres valides arrêtent les divisions existantes, vident la table et ajoutent les nouvelles bandes. Des paramètres invalides préservent la table et son compteur, tout en mémorisant BAD_RANGE. Même après une construction réussie, Raster_Commit reste nécessaire.

Exemple d’utilisation

c
Raster_BuildParallax3(64,104,0,8,16,0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Les lignes programmées 64 et 104 délimitent les décalages X de 0, 8 et 16. Les rectangles en (32,16), (24,80) et (16,112) montrent le déplacement croissant entre les trois bandes.

Raster_BuildParallax3: DMG — Les lignes programmées 64 et 104 délimitent les décalages X de 0, 8 et 16. Les rectangles en (32,16), (24,80) et (16,112) montrent le déplacement croissant entre les trois bandes.
DMG — Les lignes programmées 64 et 104 délimitent les décalages X de 0, 8 et 16. Les rectangles en (32,16), (24,80) et (16,112) montrent le déplacement croissant entre les trois bandes.
Raster_BuildParallax3: CGB — Les lignes programmées 64 et 104 délimitent les décalages X de 0, 8 et 16. Les rectangles en (32,16), (24,80) et (16,112) montrent le déplacement croissant entre les trois bandes.
CGB — Les lignes programmées 64 et 104 délimitent les décalages X de 0, 8 et 16. Les rectangles en (32,16), (24,80) et (16,112) montrent le déplacement croissant entre les trois bandes.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_parallax3.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:79

Notes de déclaration (texte source)
Build three horizontal-scroll bands at ordered visible split lines. Invalid
parameters leave the previous pending table intact and set the error status.

kitaqgb/lib/raster.c:212

c
u8 Raster_BuildParallax3(u8 y1, u8 y2, u8 scx0, u8 scx1, u8 scx2, u8 scy)
{
    u8 r;

    if (y1 == 0) return Raster_SetError(KQ_RASTER_BAD_RANGE);
    if (y2 >= 144) return Raster_SetError(KQ_RASTER_BAD_RANGE);
    if (y2 <= y1) return Raster_SetError(KQ_RASTER_BAD_RANGE);

    Raster_Clear();
    r = Raster_Push(0, scx0, scy);
    if (r != KQ_RASTER_OK) return r;
    r = Raster_Push(y1, scx1, scy);
    if (r != KQ_RASTER_OK) return r;
    return Raster_Push(y2, scx2, scy);
}
Raster_Clear

Arrête immédiatement la programmation des divisions et réinitialise le compteur, l’ordre et l’état d’erreur avant de reconstruire une table dans la même scène. Ne met pas à zéro tous les octets de stockage de la table.

Syntaxe

c
void Raster_Clear();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

L’arrêt des divisions ne remet pas SCX, SCY, WX ou WY à zéro. Définissez l’état de base souhaité avec les fonctions habituelles, telles que Scroll_SetBg. Ces fonctions ne restaurent pas non plus les anciens bits IE VBlank/STAT ni IME.

Exemple d’utilisation

c
Raster_Clear();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Raster_Clear: DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
Raster_Clear: CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_bands.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:39

Notes de déclaration (texte source)
Stop splits immediately and clear bookkeeping. Build and commit a new table to restart.

kitaqgb/lib/raster.c:65

c
void Raster_Clear()
{
    Scroll_SplitReset();
    Raster_CountValue = 0;
    Raster_LastLyValue = 0;
    Raster_HasLastLy = 0;
    Raster_LastErrorValue = KQ_RASTER_OK;
}
Raster_Commit

Active la table partagée construite. Même si un ajout a échoué, les entrées ajoutées avec succès auparavant sont activées ; l’appelant doit vérifier chaque ajout.

Syntaxe

c
u8 Raster_Commit();

Valeur renvoyée

Renvoie la dernière erreur mémorisée. Zéro ne prouve pas que tous les ajouts précédents ont réussi.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

Une table non vide active les bits IE VBlank/STAT et exécute EI pour autoriser les interruptions ; les autres bits IE sont conservés. Une table vide désactive la programmation des divisions sans restaurer la configuration globale des interruptions.

Exemple d’utilisation

c
result[2]=Raster_Commit();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Raster_Commit: DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
Raster_Commit: CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_bands.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:67

Notes de déclaration (texte source)
Publish pending splits and return the stored status. This commits even if an
earlier append failed; callers should inspect errors while building the table.

kitaqgb/lib/raster.c:161

c
u8 Raster_Commit()
{
    Scroll_SplitCommit();
    return Raster_LastErrorValue;
}
Raster_Disable

Efface puis valide une table vide pour désactiver les bandes raster. Utilisez cet arrêt explicite en entrant dans une scène sans défilement divisé.

Syntaxe

c
void Raster_Disable();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

L’arrêt des divisions ne remet pas SCX, SCY, WX ou WY à zéro. Définissez l’état de base souhaité avec les fonctions habituelles, telles que Scroll_SetBg. Ces fonctions ne restaurent pas non plus les anciens bits IE VBlank/STAT ni IME.

Exemple d’utilisation

c
Raster_Disable();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Raster_Disable: DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
Raster_Disable: CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_bands.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:41

Notes de déclaration (texte source)
Commit an empty split table so no raster bands remain active.

kitaqgb/lib/raster.c:75

c
void Raster_Disable()
{
    Raster_Clear();
    Scroll_SplitCommit();
}
Raster_GetCount

Lit le nombre de bandes ajoutées par la couche Raster. Clear/Disable le remet à zéro ; une simple validation le conserve.

Syntaxe

c
u8 Raster_GetCount();

Valeur renvoyée

Renvoie le nombre d’entrées, de 0 à 8. Soustrayez-le de huit pour connaître la capacité restante. La lecture ne modifie pas l’état.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

Exemple d’utilisation

c
result[0]=Raster_GetCount();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Raster_GetCount: DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
Raster_GetCount: CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_bands.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:44

Notes de déclaration (texte source)
Read the number of bands currently recorded by this wrapper.

kitaqgb/lib/raster.c:82

c
u8 Raster_GetCount()
{
    return Raster_CountValue;
}
Raster_GetLastError

Lit le dernier état Raster mémorisé sans l’effacer. Ce n’est pas un historique cumulatif de tous les échecs précédents.

Syntaxe

c
u8 Raster_GetLastError();

Valeur renvoyée

Renvoie l’état mémorisé, de 0 à 4. La validation renvoie cette valeur, mais n’annule pas automatiquement un échec et ne jette pas la table.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

Exemple d’utilisation

c
result[1]=Raster_GetLastError();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Raster_GetLastError: DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
Raster_GetLastError: CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_bands.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:46

Notes de déclaration (texte source)
Read the last stored status without clearing it.

kitaqgb/lib/raster.c:88

c
u8 Raster_GetLastError()
{
    return Raster_LastErrorValue;
}
Raster_Init

Vide la table de bandes partagée, arrête les divisions et initialise le compteur, la validité du dernier LY et l’état d’erreur. Contrairement à Scroll_Init, ne réinitialise pas les coordonnées du fond et de la fenêtre.

Syntaxe

c
void Raster_Init();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

L’arrêt des divisions ne remet pas SCX, SCY, WX ou WY à zéro. Définissez l’état de base souhaité avec les fonctions habituelles, telles que Scroll_SetBg. Ces fonctions ne restaurent pas non plus les anciens bits IE VBlank/STAT ni IME.

Exemple d’utilisation

c
Raster_Init();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Raster_Init: DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
Raster_Init: CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_bands.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:37

Notes de déclaration (texte source)
Stop split scheduling, empty the shared table and clear error/count state.

kitaqgb/lib/raster.c:59

c
void Raster_Init()
{
    Raster_Clear();
}
Raster_LineXGetOffset

Calcule SCX pour la ligne demandée sans modifier l’état, l’affichage ni la phase.

Syntaxe

c
u8 Raster_LineXGetOffset(const RasterLineX* effect, u8 ly);

Paramètres

effect

Pointeur vers un RasterLineX initialisé, qui reste valide pendant tout l’appel.

ly

Coordonnée de ligne à consulter (0..255) ; les lignes visibles vont de 0 à 143. La recherche boucle sur la période de l’onde au lieu de signaler une erreur de plage.

Valeur renvoyée

SCX sur huit bits égal au X de base plus le déplacement de cette ligne. Dans l’exemple, la recherche à la phase 8, ligne 0 renvoie 17.

Conditions et limites

SCX est une valeur sur huit bits et le fond boucle sur 256 pixels. Les déplacements négatifs sont représentés par des octets modulo 256. Remplissez aussi la carte au-delà de la zone visible.

L’effet modifie le défilement horizontal du fond ; les sprites et la fenêtre ne se déforment pas. RunFrame monopolise le CPU et masque les interruptions pendant les 144 lignes visibles. Mettez à jour la logique du jeu et l’audio entre les appels, et ne combinez pas ce moteur avec un pilote raster par interruption STAT.

Les images proviennent d’exécutions DMG et CGB dans KOKURA. Chaque pixel de la scène 160×144, piliers et texte compris, est comparé aux coordonnées attendues ligne par ligne. Le minutage sur matériel réel n’a pas été testé.

Placez kitaqgb, kokura et kitaq-docs dans un même dossier parent et ouvrez PowerShell dans ce dossier. La ROM prend en charge DMG et CGB ; choisissez dmg ou cgb avec KOKURA --hardware.

Exemple d’utilisation

c
wave_lookup = Raster_LineXGetOffset(&wave, 0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.

Raster_LineXGetOffset: DMG / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
DMG / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
Raster_LineXGetOffset: CGB / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
CGB / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_wave.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_wave.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
.\kokura\kokura-cli.exe .\out\raster_wave.gb --hardware cgb --run-frames 120 --png .\out\raster_wave.png
Implémentation et source

kitaqgb/lib/raster.h:91

Notes de déclaration (texte source)
Look up the selected periodic profile at LY + phase and add base X modulo
256. An unknown profile returns the unmodified base X.

kitaqgb/lib/raster.c:264

c
u8 Raster_LineXGetOffset(const RasterLineX* effect, u8 ly)
{
    u8 index;

    if (effect->profile == KQ_RASTER_LINE_X_TITLE) {
        index = (u8)((ly + effect->phase) & 15);
        return (u8)(effect->base_x + Raster_LineXXTitle[(__safe_index u8)index]);
    }

    if (effect->profile == KQ_RASTER_LINE_TRAVEL_GATE) {
        index = (u8)((ly + effect->phase) & 63);
        return (u8)(effect->base_x + Raster_LineXTravelGate[(__safe_index u8)index]);
    }

    return effect->base_x;
}
Raster_LineXInit

Initialise le profil et le X de base, avec une phase nulle et un pas de phase par image. Cet appel ne dessine rien et n’écrit pas les registres de défilement.

Syntaxe

c
void Raster_LineXInit(RasterLineX* effect, u8 profile, u8 base_x);

Paramètres

effect

Pointeur vers un espace RasterLineX inscriptible ; aucune initialisation préalable n’est nécessaire.

profile

0 (FLAT) n’applique aucun déplacement ; 1 (X_TITLE) répète des décalages de −4 à +3 pixels toutes les 16 lignes ; 2 (TRAVEL_GATE) répète une onde de ±24 pixels toutes les 64 lignes. Les autres valeurs n’appliquent aucun déplacement.

base_x

X du fond ajouté au déplacement de l’onde, en pixels (0..255).

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

SCX est une valeur sur huit bits et le fond boucle sur 256 pixels. Les déplacements négatifs sont représentés par des octets modulo 256. Remplissez aussi la carte au-delà de la zone visible.

L’effet modifie le défilement horizontal du fond ; les sprites et la fenêtre ne se déforment pas. RunFrame monopolise le CPU et masque les interruptions pendant les 144 lignes visibles. Mettez à jour la logique du jeu et l’audio entre les appels, et ne combinez pas ce moteur avec un pilote raster par interruption STAT.

Les images proviennent d’exécutions DMG et CGB dans KOKURA. Chaque pixel de la scène 160×144, piliers et texte compris, est comparé aux coordonnées attendues ligne par ligne. Le minutage sur matériel réel n’a pas été testé.

Placez kitaqgb, kokura et kitaq-docs dans un même dossier parent et ouvrez PowerShell dans ce dossier. La ROM prend en charge DMG et CGB ; choisissez dmg ou cgb avec KOKURA --hardware.

Exemple d’utilisation

c
Raster_LineXInit(&wave, KQ_RASTER_LINE_TRAVEL_GATE, 0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.

Raster_LineXInit: DMG / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
DMG / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
Raster_LineXInit: CGB / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
CGB / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_wave.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_wave.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
.\kokura\kokura-cli.exe .\out\raster_wave.gb --hardware cgb --run-frames 120 --png .\out\raster_wave.png
Implémentation et source

kitaqgb/lib/raster.h:82

Notes de déclaration (texte source)
Initialize a scanline-wave state with phase zero and one phase step per frame.

kitaqgb/lib/raster.c:229

c
void Raster_LineXInit(RasterLineX* effect, u8 profile, u8 base_x)
{
    effect->profile = profile;
    effect->base_x = base_x;
    effect->phase = 0;
    effect->phase_step = 1;
    effect->frame_divider = 1;
    effect->frame_counter = 0;
}
Raster_LineXRunFrame

Attend VBlank et rend les 144 lignes visibles suivantes avec un X de fond propre à chaque ligne. Avance ensuite le compteur de division et met à jour la phase selon l’intervalle choisi.

Syntaxe

c
void Raster_LineXRunFrame(RasterLineX* effect);

Paramètres

effect

Pointeur vers un RasterLineX initialisé, qui reste valide pendant tout l’appel.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Si le LCD est éteint, revient immédiatement sans modifier l’effet. Sinon, bloque jusqu’à la mise à jour de SCX pour les 144 lignes, restaure l’état d’activation des interruptions et synchronise les fonctions Scroll avec le SCX final. Le retour ne garantit pas que VBlank soit actif. Avant d’écrire directement en VRAM, attendez VBlank ou utilisez une routine de transfert qui gère les périodes d’accès autorisées.

SCX est une valeur sur huit bits et le fond boucle sur 256 pixels. Les déplacements négatifs sont représentés par des octets modulo 256. Remplissez aussi la carte au-delà de la zone visible.

L’effet modifie le défilement horizontal du fond ; les sprites et la fenêtre ne se déforment pas. RunFrame monopolise le CPU et masque les interruptions pendant les 144 lignes visibles. Mettez à jour la logique du jeu et l’audio entre les appels, et ne combinez pas ce moteur avec un pilote raster par interruption STAT.

Les images proviennent d’exécutions DMG et CGB dans KOKURA. Chaque pixel de la scène 160×144, piliers et texte compris, est comparé aux coordonnées attendues ligne par ligne. Le minutage sur matériel réel n’a pas été testé.

Placez kitaqgb, kokura et kitaq-docs dans un même dossier parent et ouvrez PowerShell dans ce dossier. La ROM prend en charge DMG et CGB ; choisissez dmg ou cgb avec KOKURA --hardware.

Exemple d’utilisation

c
Raster_LineXRunFrame(&wave);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.

Raster_LineXRunFrame: DMG / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
DMG / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
Raster_LineXRunFrame: CGB / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
CGB / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_wave.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_wave.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
.\kokura\kokura-cli.exe .\out\raster_wave.gb --hardware cgb --run-frames 120 --png .\out\raster_wave.png
Implémentation et source

kitaqgb/lib/raster.h:96

Notes de déclaration (texte source)
Render all 144 visible lines with one SCX write per line, then advance phase.
This foreground renderer masks interrupts during the visible frame. Do game
and audio work between calls; do not combine it with a STAT raster driver.
Returns without changing the effect when the LCD is off.

kitaqgb/lib/raster.c:298

c
void Raster_LineXRunFrame(RasterLineX* effect)
{
    u8 interrupt_state;
    if ((Raster_LineXLcdc & 0x80) == 0) return;
    Raster_LineXTable = Raster_LineXFlat;
    Raster_LineXMask = 15;
    if (effect->profile == KQ_RASTER_LINE_X_TITLE) {
        Raster_LineXTable = Raster_LineXXTitle;
    }
    if (effect->profile == KQ_RASTER_LINE_TRAVEL_GATE) {
        Raster_LineXTable = Raster_LineXTravelGate;
        Raster_LineXMask = 63;
    }
    Raster_LineXPhase = effect->phase;
    Raster_LineXBase = effect->base_x;
    interrupt_state = __critical_enter();
    __asm {
        PUSH_AF
        PUSH_BC
        PUSH_DE
        PUSH_HL
        // Use the current VBlank when the preceding frame ended there.
        // Waiting for another VBlank edge would leave every second frame flat.
raster_linex_vblank:
        LDH_A_MEM 0x44
        CP_IMM 144
        JR_C raster_linex_vblank
        LD_B_IMM 0
        LD_A_MEM Raster_LineXPhase
        LD_C_A
        LD_A_MEM Raster_LineXMask
        LD_D_A
        LD_A_MEM Raster_LineXBase
        LD_E_A
raster_linex_line:
        LD_A_B
        ADD_C
        AND_D
        LD_L_A
        LD_H_IMM 0
        PUSH_DE
        LD_A_MEM Raster_LineXTable
        LD_E_A
        LD_A_MEM Raster_LineXTable+1
        LD_D_A
        ADD_HL_DE
        POP_DE
        LD_A_HL
        ADD_E
        PUSH_AF
raster_linex_wait:
        LDH_A_MEM 0x44
        CP_B
        JR_NZ raster_linex_wait
        POP_AF
        LDH_MEM_A 0x43
        INC_B
        LD_A_B
        CP_IMM 144
        JR_NZ raster_linex_line
        POP_HL
        POP_DE
        POP_BC
        POP_AF
    }
    // Synchronize the scroll helper's tracked state with the last hardware write.
    __scroll_bg_x_set(Raster_LineXScx);
    __critical_leave(interrupt_state);
    effect->frame_counter++;
    if (effect->frame_counter >= effect->frame_divider) {
        effect->frame_counter = 0;
        effect->phase = (u8)(effect->phase + effect->phase_step);
    }
}
Raster_LineXSetPhase

Fixe directement la position de l’onde, en conservant le X de base, la vitesse et le compteur de division.

Syntaxe

c
void Raster_LineXSetPhase(RasterLineX* effect, u8 phase);

Paramètres

effect

Pointeur vers un RasterLineX initialisé, qui reste valide pendant tout l’appel.

phase

Valeur de phase sur huit bits ; l’onde choisie se répète tous les 16 ou 64 pas.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

SCX est une valeur sur huit bits et le fond boucle sur 256 pixels. Les déplacements négatifs sont représentés par des octets modulo 256. Remplissez aussi la carte au-delà de la zone visible.

L’effet modifie le défilement horizontal du fond ; les sprites et la fenêtre ne se déforment pas. RunFrame monopolise le CPU et masque les interruptions pendant les 144 lignes visibles. Mettez à jour la logique du jeu et l’audio entre les appels, et ne combinez pas ce moteur avec un pilote raster par interruption STAT.

Les images proviennent d’exécutions DMG et CGB dans KOKURA. Chaque pixel de la scène 160×144, piliers et texte compris, est comparé aux coordonnées attendues ligne par ligne. Le minutage sur matériel réel n’a pas été testé.

Placez kitaqgb, kokura et kitaq-docs dans un même dossier parent et ouvrez PowerShell dans ce dossier. La ROM prend en charge DMG et CGB ; choisissez dmg ou cgb avec KOKURA --hardware.

Exemple d’utilisation

c
Raster_LineXSetPhase(&wave, 8);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.

Raster_LineXSetPhase: DMG / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
DMG / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
Raster_LineXSetPhase: CGB / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
CGB / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_wave.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_wave.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
.\kokura\kokura-cli.exe .\out\raster_wave.gb --hardware cgb --run-frames 120 --png .\out\raster_wave.png
Implémentation et source

kitaqgb/lib/raster.h:88

Notes de déclaration (texte source)
Set the byte phase directly without resetting the frame-divider counter.

kitaqgb/lib/raster.c:257

c
void Raster_LineXSetPhase(RasterLineX* effect, u8 phase)
{
    effect->phase = phase;
}
Raster_LineXSetProfile

Sélectionne un profil et remet à zéro la phase et le compteur de division des images. Conserve le X de base et la vitesse.

Syntaxe

c
void Raster_LineXSetProfile(RasterLineX* effect, u8 profile);

Paramètres

effect

Pointeur vers un RasterLineX initialisé, qui reste valide pendant tout l’appel.

profile

0 (FLAT) n’applique aucun déplacement ; 1 (X_TITLE) répète des décalages de −4 à +3 pixels toutes les 16 lignes ; 2 (TRAVEL_GATE) répète une onde de ±24 pixels toutes les 64 lignes. Les autres valeurs n’appliquent aucun déplacement.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

SCX est une valeur sur huit bits et le fond boucle sur 256 pixels. Les déplacements négatifs sont représentés par des octets modulo 256. Remplissez aussi la carte au-delà de la zone visible.

L’effet modifie le défilement horizontal du fond ; les sprites et la fenêtre ne se déforment pas. RunFrame monopolise le CPU et masque les interruptions pendant les 144 lignes visibles. Mettez à jour la logique du jeu et l’audio entre les appels, et ne combinez pas ce moteur avec un pilote raster par interruption STAT.

Les images proviennent d’exécutions DMG et CGB dans KOKURA. Chaque pixel de la scène 160×144, piliers et texte compris, est comparé aux coordonnées attendues ligne par ligne. Le minutage sur matériel réel n’a pas été testé.

Placez kitaqgb, kokura et kitaq-docs dans un même dossier parent et ouvrez PowerShell dans ce dossier. La ROM prend en charge DMG et CGB ; choisissez dmg ou cgb avec KOKURA --hardware.

Exemple d’utilisation

c
Raster_LineXSetProfile(&wave, KQ_RASTER_LINE_X_TITLE);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le titre original ORBIT GUARD entre par la droite avec une forte ondulation. Après 48 images rendues, celle-ci devient un léger frémissement ; à partir de l’image 96, le titre est immobile. L’entrée se répète après 160 images. Les images montrent successivement l’arrivée, la petite ondulation et le titre stabilisé.

Raster_LineXSetProfile: DMG / image 16 — Le titre original ORBIT GUARD entre par la droite avec une forte ondulation. Après 48 images rendues, celle-ci devient un léger frémissement ; à partir de l’image 96, le titre est immobile. L’entrée se répète après 160 images. Les images montrent successivement l’arrivée, la petite ondulation et le titre stabilisé.
DMG / image 16 — Le titre original ORBIT GUARD entre par la droite avec une forte ondulation. Après 48 images rendues, celle-ci devient un léger frémissement ; à partir de l’image 96, le titre est immobile. L’entrée se répète après 160 images. Les images montrent successivement l’arrivée, la petite ondulation et le titre stabilisé.
Raster_LineXSetProfile: DMG / image 60 — Le titre original ORBIT GUARD entre par la droite avec une forte ondulation. Après 48 images rendues, celle-ci devient un léger frémissement ; à partir de l’image 96, le titre est immobile. L’entrée se répète après 160 images. Les images montrent successivement l’arrivée, la petite ondulation et le titre stabilisé.
DMG / image 60 — Le titre original ORBIT GUARD entre par la droite avec une forte ondulation. Après 48 images rendues, celle-ci devient un léger frémissement ; à partir de l’image 96, le titre est immobile. L’entrée se répète après 160 images. Les images montrent successivement l’arrivée, la petite ondulation et le titre stabilisé.
Raster_LineXSetProfile: DMG / image 120 — Le titre original ORBIT GUARD entre par la droite avec une forte ondulation. Après 48 images rendues, celle-ci devient un léger frémissement ; à partir de l’image 96, le titre est immobile. L’entrée se répète après 160 images. Les images montrent successivement l’arrivée, la petite ondulation et le titre stabilisé.
DMG / image 120 — Le titre original ORBIT GUARD entre par la droite avec une forte ondulation. Après 48 images rendues, celle-ci devient un léger frémissement ; à partir de l’image 96, le titre est immobile. L’entrée se répète après 160 images. Les images montrent successivement l’arrivée, la petite ondulation et le titre stabilisé.
Raster_LineXSetProfile: CGB / image 16 — Le titre original ORBIT GUARD entre par la droite avec une forte ondulation. Après 48 images rendues, celle-ci devient un léger frémissement ; à partir de l’image 96, le titre est immobile. L’entrée se répète après 160 images. Les images montrent successivement l’arrivée, la petite ondulation et le titre stabilisé.
CGB / image 16 — Le titre original ORBIT GUARD entre par la droite avec une forte ondulation. Après 48 images rendues, celle-ci devient un léger frémissement ; à partir de l’image 96, le titre est immobile. L’entrée se répète après 160 images. Les images montrent successivement l’arrivée, la petite ondulation et le titre stabilisé.
Raster_LineXSetProfile: CGB / image 60 — Le titre original ORBIT GUARD entre par la droite avec une forte ondulation. Après 48 images rendues, celle-ci devient un léger frémissement ; à partir de l’image 96, le titre est immobile. L’entrée se répète après 160 images. Les images montrent successivement l’arrivée, la petite ondulation et le titre stabilisé.
CGB / image 60 — Le titre original ORBIT GUARD entre par la droite avec une forte ondulation. Après 48 images rendues, celle-ci devient un léger frémissement ; à partir de l’image 96, le titre est immobile. L’entrée se répète après 160 images. Les images montrent successivement l’arrivée, la petite ondulation et le titre stabilisé.
Raster_LineXSetProfile: CGB / image 120 — Le titre original ORBIT GUARD entre par la droite avec une forte ondulation. Après 48 images rendues, celle-ci devient un léger frémissement ; à partir de l’image 96, le titre est immobile. L’entrée se répète après 160 images. Les images montrent successivement l’arrivée, la petite ondulation et le titre stabilisé.
CGB / image 120 — Le titre original ORBIT GUARD entre par la droite avec une forte ondulation. Après 48 images rendues, celle-ci devient un léger frémissement ; à partir de l’image 96, le titre est immobile. L’entrée se répète après 160 images. Les images montrent successivement l’arrivée, la petite ondulation et le titre stabilisé.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_title_entry.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_title_entry.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
.\kokura\kokura-cli.exe .\out\raster_title_entry.gb --hardware cgb --run-frames 120 --png .\out\raster_title_entry.png
Implémentation et source

kitaqgb/lib/raster.h:84

Notes de déclaration (texte source)
Change the wave profile and restart its phase/divider counter.

kitaqgb/lib/raster.c:240

c
void Raster_LineXSetProfile(RasterLineX* effect, u8 profile)
{
    effect->profile = profile;
    effect->phase = 0;
    effect->frame_counter = 0;
}
Raster_LineXSetSpeed

Règle l’incrément de phase et l’intervalle de mise à jour. Réinitialise le compteur de division tout en conservant la phase actuelle.

Syntaxe

c
void Raster_LineXSetSpeed(RasterLineX* effect, u8 phase_step, u8 frame_divider);

Paramètres

effect

Pointeur vers un RasterLineX initialisé, qui reste valide pendant tout l’appel.

phase_step

Incrément de phase par mise à jour (0..255). Zéro fige l’onde. La valeur 255 recule d’un pas grâce au bouclage sur huit bits.

frame_divider

Nombre d’appels RunFrame ayant rendu une image par mise à jour de phase (1..255). Zéro sélectionne un. Les appels qui reviennent parce que le LCD est éteint ne comptent pas.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

SCX est une valeur sur huit bits et le fond boucle sur 256 pixels. Les déplacements négatifs sont représentés par des octets modulo 256. Remplissez aussi la carte au-delà de la zone visible.

L’effet modifie le défilement horizontal du fond ; les sprites et la fenêtre ne se déforment pas. RunFrame monopolise le CPU et masque les interruptions pendant les 144 lignes visibles. Mettez à jour la logique du jeu et l’audio entre les appels, et ne combinez pas ce moteur avec un pilote raster par interruption STAT.

Les images proviennent d’exécutions DMG et CGB dans KOKURA. Chaque pixel de la scène 160×144, piliers et texte compris, est comparé aux coordonnées attendues ligne par ligne. Le minutage sur matériel réel n’a pas été testé.

Placez kitaqgb, kokura et kitaq-docs dans un même dossier parent et ouvrez PowerShell dans ce dossier. La ROM prend en charge DMG et CGB ; choisissez dmg ou cgb avec KOKURA --hardware.

Exemple d’utilisation

c
Raster_LineXSetSpeed(&wave, 1, 1);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.

Raster_LineXSetSpeed: DMG / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
DMG / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
Raster_LineXSetSpeed: CGB / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.
CGB / image 60 — Les piliers et les lettres ondulent horizontalement jusqu’à 24 pixels. Une onde couvre 64 lignes et sa phase avance d’une ligne par image. Sur CGB, piliers et lettres sont bleus. Observez les décalages horizontaux différents d’une ligne à l’autre, plutôt qu’un déplacement uniforme de tout l’écran.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_wave.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_wave.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
.\kokura\kokura-cli.exe .\out\raster_wave.gb --hardware cgb --run-frames 120 --png .\out\raster_wave.png
Implémentation et source

kitaqgb/lib/raster.h:86

Notes de déclaration (texte source)
Configure the phase increment and frame interval; clamp a zero interval to one.

kitaqgb/lib/raster.c:248

c
void Raster_LineXSetSpeed(RasterLineX* effect, u8 phase_step, u8 frame_divider)
{
    effect->phase_step = phase_step;
    if (frame_divider == 0) frame_divider = 1;
    effect->frame_divider = frame_divider;
    effect->frame_counter = 0;
}
Raster_Push

Ajoute une bande qui modifie SCX/SCY du fond au LY programmé. Cette opération réservée au fond ne change ni la fenêtre ni les couleurs.

Syntaxe

c
u8 Raster_Push(u8 ly, u8 scx, u8 scy);

Paramètres

ly

Ligne visible programmée, de 0 à 143, strictement supérieure à l’entrée précédente. Une première entrée à LY=0 est appliquée par le traitement VBlank pour établir l’état de début d’image.

scx

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

scy

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

Valeur renvoyée

Renvoie KQ_RASTER_OK (0) en cas de succès, ou un état d’erreur de 1 à 4. Consultez les contraintes de la fonction et Raster_GetLastError.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

Exemple d’utilisation

c
Raster_Push(0,0,0);Raster_Push(64,8,0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Raster_Push: DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
Raster_Push: CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_bands.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:50

Notes de déclaration (texte source)
Append a validated background-scroll band and advance the monotonic-LY
bookkeeping. A successful append clears the previous error.

kitaqgb/lib/raster.c:95

c
u8 Raster_Push(u8 ly, u8 scx, u8 scy)
{
    u8 r;

    r = Raster_CheckPush(ly);
    if (r != KQ_RASTER_OK) return r;

    Scroll_SplitPush(ly, scx, scy);

    Raster_LastLyValue = ly;
    Raster_HasLastLy = 1;
    Raster_CountValue++;
    Raster_LastErrorValue = KQ_RASTER_OK;
    return KQ_RASTER_OK;
}
Raster_PushBgColor0

Ajoute une bande qui change la couleur zéro de la palette de fond CGB zéro pendant l’image. Ne sélectionne pas une autre palette et ne modifie pas ses trois autres couleurs. L’enregistrement sur DMG ne produit aucun effet de couleur.

Syntaxe

c
u8 Raster_PushBgColor0(u8 ly, u16 rgb15);

Paramètres

ly

Ligne visible programmée, de 0 à 143, strictement supérieure à l’entrée précédente. Une première entrée à LY=0 est appliquée par le traitement VBlank pour établir l’état de début d’image.

rgb15

RGB15 : rouge dans les bits 0..4, vert dans 5..9 et bleu dans 10..14. 0x001F donne du rouge, 0x03E0 du vert et 0x7C00 du bleu. La plage de l’entrée n’est pas vérifiée.

Valeur renvoyée

Renvoie KQ_RASTER_OK (0) en cas de succès, ou un état d’erreur de 1 à 4. Consultez les contraintes de la fonction et Raster_GetLastError.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

Les changements de couleur utilisent BCPS/BCPD et ne conservent pas l’ancien index BCPS. Si le code principal écrit aussi les palettes, réglez explicitement cet index. Le gestionnaire attend un mode LCD accessible ; la séparation visible des couleurs peut donc survenir après la ligne LY programmée.

Exemple d’utilisation

c
Raster_PushBgColor0(0,0x7C00);Raster_PushBgColor0(64,0x001F);Raster_PushBgColor0(112,0x03E0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Dans la capture CGB vérifiée à vitesse normale, les lignes 0..65 sont bleues, 66..113 rouges et 114..143 vertes. Les LY programmés sont 0, 64 et 112 ; les délais d’interruption et d’accès à la palette contribuent au décalage des limites visibles. Il n’existe pas de version couleur DMG.

Raster_PushBgColor0: CGB — Dans la capture CGB vérifiée à vitesse normale, les lignes 0..65 sont bleues, 66..113 rouges et 114..143 vertes. Les LY programmés sont 0, 64 et 112 ; les délais d’interruption et d’accès à la palette contribuent au décalage des limites visibles. Il n’existe pas de version couleur DMG.
CGB — Dans la capture CGB vérifiée à vitesse normale, les lignes 0..65 sont bleues, 66..113 rouges et 114..143 vertes. Les LY programmés sont 0, 64 et 112 ; les délais d’interruption et d’accès à la palette contribuent au décalage des limites visibles. Il n’existe pas de version couleur DMG.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_color.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:63

Notes de déclaration (texte source)
Pack a 15-bit color into the extended band's two scroll-byte fields and select
the color-zero operation, which interprets those fields as color data.

kitaqgb/lib/raster.c:154

c
u8 Raster_PushBgColor0(u8 ly, u16 rgb15)
{
    return Raster_PushEx(ly, (u8)rgb15, (u8)(rgb15 >> 8), 0, 0, KQ_RASTER_BG_COLOR0);
}
Raster_PushBgWindowScreen

Modifie le défilement du fond et les coordonnées de la fenêtre dans une même bande. La fonction ajoute BG et WIN et convertit le X écran de la fenêtre en WX.

Syntaxe

c
u8 Raster_PushBgWindowScreen(u8 ly, u8 scx, u8 scy, u8 screen_x, u8 screen_y, u8 flags);

Paramètres

ly

Ligne visible programmée, de 0 à 143, strictement supérieure à l’entrée précédente. Une première entrée à LY=0 est appliquée par le traitement VBlank pour établir l’état de début d’image.

scx

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

scy

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

screen_x

Coordonnée X écran du bord gauche de la fenêtre. La fonction ajoute sept pour obtenir WX. Utilisez normalement 0..159. Les valeurs à partir de 249 débordent lors de l’addition sur un octet ; ne les utilisez pas pour masquer la fenêtre.

screen_y

WY de la fenêtre, en pixels depuis le bord supérieur. Contrairement à X, Y ne nécessite pas l’ajout de sept. À partir de 144, WY ne désigne aucune ligne de départ dans la zone visible.

flags

Passez normalement WIN_SHOW ou WIN_HIDE. La fonction ajoute WIN ; zéro suffit donc pour modifier les coordonnées sans changer la visibilité. Les autres bits pris en charge sont transmis ; évitez les opérations BG ou de couleur involontaires.

Valeur renvoyée

Renvoie KQ_RASTER_OK (0) en cas de succès, ou un état d’erreur de 1 à 4. Consultez les contraintes de la fonction et Raster_GetLastError.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

Exemple d’utilisation

c
Raster_PushBgWindowScreen(0,8,0,24,48,KQ_RASTER_WIN_SHOW);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Un X de fond à 8 déplace le rectangle rouge en (24,16). L’origine de la fenêtre reste en (24,48), donc son rectangle bleu demeure en (32,56). Cela montre l’indépendance des deux systèmes de coordonnées.

Raster_PushBgWindowScreen: DMG — Un X de fond à 8 déplace le rectangle rouge en (24,16). L’origine de la fenêtre reste en (24,48), donc son rectangle bleu demeure en (32,56). Cela montre l’indépendance des deux systèmes de coordonnées.
DMG — Un X de fond à 8 déplace le rectangle rouge en (24,16). L’origine de la fenêtre reste en (24,48), donc son rectangle bleu demeure en (32,56). Cela montre l’indépendance des deux systèmes de coordonnées.
Raster_PushBgWindowScreen: CGB — Un X de fond à 8 déplace le rectangle rouge en (24,16). L’origine de la fenêtre reste en (24,48), donc son rectangle bleu demeure en (32,56). Cela montre l’indépendance des deux systèmes de coordonnées.
CGB — Un X de fond à 8 déplace le rectangle rouge en (24,16). L’origine de la fenêtre reste en (24,48), donc son rectangle bleu demeure en (32,56). Cela montre l’indépendance des deux systèmes de coordonnées.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_bg_window.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:60

Notes de déclaration (texte source)
Queue both background and window updates, converting window screen X to WX.

kitaqgb/lib/raster.c:145

c
u8 Raster_PushBgWindowScreen(u8 ly, u8 scx, u8 scy, u8 screen_x, u8 screen_y, u8 flags)
{
    flags = (u8)(flags | KQ_RASTER_BG | KQ_RASTER_WIN);
    return Raster_PushEx(ly, scx, scy, (u8)(screen_x + 7), screen_y, flags);
}
Raster_PushEx

Ajoute une bande étendue exécutant les opérations de fond, de fenêtre, de visibilité ou de couleur choisies par les indicateurs. Pour modifier seulement le fond, utilisez Raster_Push, qui prend moins d’arguments.

Syntaxe

c
u8 Raster_PushEx(u8 ly, u8 scx, u8 scy, u8 wx, u8 wy, u8 flags);

Paramètres

ly

Ligne visible programmée, de 0 à 143, strictement supérieure à l’entrée précédente. Une première entrée à LY=0 est appliquée par le traitement VBlank pour établir l’état de début d’image.

scx

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

scy

Octet de défilement du fond, de 0 à 255. SCX/SCY indiquent où lire la carte de fond, pas une position à l’écran. Les coordonnées bouclent sur le fond de 256 pixels.

wx

Valeur matérielle brute de WX. Ajoutez sept à la coordonnée X écran habituelle ; WX=7 place la fenêtre au bord gauche. La fonction ne borne ni ne valide WX.

wy

WY de la fenêtre, en pixels depuis le bord supérieur. Contrairement à X, Y ne nécessite pas l’ajout de sept. À partir de 144, WY ne désigne aucune ligne de départ dans la zone visible.

flags

Indicateurs : BG=1 modifie le défilement du fond, WIN=2 modifie WX/WY, WIN_SHOW=4 affiche la fenêtre, WIN_HIDE=8 la masque et BG_COLOR0=16 modifie la couleur zéro du fond CGB. Les bits supérieurs inconnus sont ignorés. Si SHOW et HIDE sont tous deux présents, SHOW s’applique en dernier. Les changements de couleur réutilisent les champs SCX/SCY ; ne les combinez pas avec un défilement ordinaire du fond.

Valeur renvoyée

Renvoie KQ_RASTER_OK (0) en cas de succès, ou un état d’erreur de 1 à 4. Consultez les contraintes de la fonction et Raster_GetLastError.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

Exemple d’utilisation

c
Raster_PushEx(104,16,0,7,0,KQ_RASTER_BG|KQ_RASTER_WIN_HIDE);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Raster_PushEx: DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
DMG — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
Raster_PushEx: CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.
CGB — Des rectangles rouges de 24x16 pixels, noirs sur DMG, apparaissent en (32,16), (24,80) et (16,112). Les bandes inférieures sont davantage décalées vers la gauche. Les résultats internes indiquent un compteur de 3, une erreur de 0 et un résultat de validation de 0.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_bands.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:52

Notes de déclaration (texte source)
Append a validated extended band after masking flags to supported operations.

kitaqgb/lib/raster.c:112

c
u8 Raster_PushEx(u8 ly, u8 scx, u8 scy, u8 wx, u8 wy, u8 flags)
{
    u8 r;

    r = Raster_CheckPush(ly);
    if (r != KQ_RASTER_OK) return r;

    // Masking removes unknown bits but does not reject conflicting supported operations.
    flags = (u8)(flags & KQ_RASTER_FLAG_MASK);
    Scroll_SplitPushEx(ly, scx, scy, wx, wy, flags);

    Raster_LastLyValue = ly;
    Raster_HasLastLy = 1;
    Raster_CountValue++;
    Raster_LastErrorValue = KQ_RASTER_OK;
    return KQ_RASTER_OK;
}
Raster_PushWindowRaw

Ajoute une bande de fenêtre avec les valeurs matérielles brutes WX/WY. Ajoute automatiquement WIN et fournit zéro pour les deux octets de données du fond.

Syntaxe

c
u8 Raster_PushWindowRaw(u8 ly, u8 wx, u8 wy, u8 flags);

Paramètres

ly

Ligne visible programmée, de 0 à 143, strictement supérieure à l’entrée précédente. Une première entrée à LY=0 est appliquée par le traitement VBlank pour établir l’état de début d’image.

wx

Valeur matérielle brute de WX. Ajoutez sept à la coordonnée X écran habituelle ; WX=7 place la fenêtre au bord gauche. La fonction ne borne ni ne valide WX.

wy

WY de la fenêtre, en pixels depuis le bord supérieur. Contrairement à X, Y ne nécessite pas l’ajout de sept. À partir de 144, WY ne désigne aucune ligne de départ dans la zone visible.

flags

Passez normalement WIN_SHOW ou WIN_HIDE. La fonction ajoute WIN ; zéro suffit donc pour modifier les coordonnées sans changer la visibilité. Les autres bits pris en charge sont transmis ; évitez les opérations BG ou de couleur involontaires.

Valeur renvoyée

Renvoie KQ_RASTER_OK (0) en cas de succès, ou un état d’erreur de 1 à 4. Consultez les contraintes de la fonction et Raster_GetLastError.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

Exemple d’utilisation

c
Raster_PushWindowRaw(0,31,48,KQ_RASTER_WIN_SHOW);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

WX=31 et WY=48 placent l’origine de la fenêtre en (24,48) à l’écran. Son rectangle bleu de 16x16 en position locale (8,8) apparaît en (32,56). Le rectangle rouge du fond supérieur reste en (32,16). Les deux sont noirs sur DMG.

Raster_PushWindowRaw: DMG — WX=31 et WY=48 placent l’origine de la fenêtre en (24,48) à l’écran. Son rectangle bleu de 16x16 en position locale (8,8) apparaît en (32,56). Le rectangle rouge du fond supérieur reste en (32,16). Les deux sont noirs sur DMG.
DMG — WX=31 et WY=48 placent l’origine de la fenêtre en (24,48) à l’écran. Son rectangle bleu de 16x16 en position locale (8,8) apparaît en (32,56). Le rectangle rouge du fond supérieur reste en (32,16). Les deux sont noirs sur DMG.
Raster_PushWindowRaw: CGB — WX=31 et WY=48 placent l’origine de la fenêtre en (24,48) à l’écran. Son rectangle bleu de 16x16 en position locale (8,8) apparaît en (32,56). Le rectangle rouge du fond supérieur reste en (32,16). Les deux sont noirs sur DMG.
CGB — WX=31 et WY=48 placent l’origine de la fenêtre en (24,48) à l’écran. Son rectangle bleu de 16x16 en position locale (8,8) apparaît en (32,56). Le rectangle rouge du fond supérieur reste en (32,16). Les deux sont noirs sur DMG.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_window_raw.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:55

Notes de déclaration (texte source)
Enable window updates and pass hardware WX/WY values without coordinate conversion.

kitaqgb/lib/raster.c:131

c
u8 Raster_PushWindowRaw(u8 ly, u8 wx, u8 wy, u8 flags)
{
    flags = (u8)(flags | KQ_RASTER_WIN);
    return Raster_PushEx(ly, 0, 0, wx, wy, flags);
}
Raster_PushWindowScreen

Ajoute une bande de fenêtre en coordonnées écran. Ajoute sept à X avant d’appeler la variante brute, afin de positionner la fenêtre sans confondre X écran et WX.

Syntaxe

c
u8 Raster_PushWindowScreen(u8 ly, u8 screen_x, u8 screen_y, u8 flags);

Paramètres

ly

Ligne visible programmée, de 0 à 143, strictement supérieure à l’entrée précédente. Une première entrée à LY=0 est appliquée par le traitement VBlank pour établir l’état de début d’image.

screen_x

Coordonnée X écran du bord gauche de la fenêtre. La fonction ajoute sept pour obtenir WX. Utilisez normalement 0..159. Les valeurs à partir de 249 débordent lors de l’addition sur un octet ; ne les utilisez pas pour masquer la fenêtre.

screen_y

WY de la fenêtre, en pixels depuis le bord supérieur. Contrairement à X, Y ne nécessite pas l’ajout de sept. À partir de 144, WY ne désigne aucune ligne de départ dans la zone visible.

flags

Passez normalement WIN_SHOW ou WIN_HIDE. La fonction ajoute WIN ; zéro suffit donc pour modifier les coordonnées sans changer la visibilité. Les autres bits pris en charge sont transmis ; évitez les opérations BG ou de couleur involontaires.

Valeur renvoyée

Renvoie KQ_RASTER_OK (0) en cas de succès, ou un état d’erreur de 1 à 4. Consultez les contraintes de la fonction et Raster_GetLastError.

Conditions et limites

Incluez raster.h et compilez raster.c ainsi que scroll.c. Une table partagée contient jusqu’à huit bandes. Pendant sa construction avec Raster_*, n’intercalez pas d’appels directs à Scroll_Split* ou __scroll_split_* : ils contournent le suivi du nombre d’entrées et de la dernière ligne par la couche Raster.

Reconstruisez pendant VBlank ou à un moment où vous maîtrisez l’effet sur l’affichage : effacez, ajoutez les entrées, puis validez. L’effacement arrête aussi les divisions actives ; vous ne modifiez pas un tampon arrière indépendant. LY programme une interruption, et les écritures de registres prennent un temps supplémentaire. Pour une ondulation ligne par ligne, utilisez la famille distincte Raster_LineX* ; n’exécutez pas les deux pilotes ensemble.

Les codes d’état sont 0 OK, 1 FULL, 2 BAD_LY, 3 UNSORTED et 4 BAD_RANGE. Les ajouts vérifient dans cet ordre la plage LY, la capacité, puis l’ordre des lignes. Une entrée refusée n’agrandit pas la table. Un ajout réussi ultérieur ou un effacement remet l’erreur à zéro : vérifiez chaque valeur de retour au moment de l’appel.

Exemple d’utilisation

c
Raster_PushWindowScreen(0,24,48,KQ_RASTER_WIN_SHOW);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Passer directement les coordonnées écran (24,48) produit le même rectangle bleu de fenêtre en (32,56) que l’exemple brut. La bibliothèque ajoute sept à X. Le rectangle rouge du fond supérieur est en (32,16).

Raster_PushWindowScreen: DMG — Passer directement les coordonnées écran (24,48) produit le même rectangle bleu de fenêtre en (32,56) que l’exemple brut. La bibliothèque ajoute sept à X. Le rectangle rouge du fond supérieur est en (32,16).
DMG — Passer directement les coordonnées écran (24,48) produit le même rectangle bleu de fenêtre en (32,56) que l’exemple brut. La bibliothèque ajoute sept à X. Le rectangle rouge du fond supérieur est en (32,16).
Raster_PushWindowScreen: CGB — Passer directement les coordonnées écran (24,48) produit le même rectangle bleu de fenêtre en (32,56) que l’exemple brut. La bibliothèque ajoute sept à X. Le rectangle rouge du fond supérieur est en (32,16).
CGB — Passer directement les coordonnées écran (24,48) produit le même rectangle bleu de fenêtre en (32,56) que l’exemple brut. La bibliothèque ajoute sept à X. Le rectangle rouge du fond supérieur est en (32,16).

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\raster_bands_window_screen.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\raster_bands.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/raster.h:58

Notes de déclaration (texte source)
Convert screen X to hardware WX by adding seven, then queue a window band.
The byte addition wraps if callers supply an excessive X coordinate.

kitaqgb/lib/raster.c:139

c
u8 Raster_PushWindowScreen(u8 ly, u8 screen_x, u8 screen_y, u8 flags)
{
    return Raster_PushWindowRaw(ly, (u8)(screen_x + 7), screen_y, flags);
}

rpg.h — Nombres aléatoires, texte, cartes, sauvegardes et services RPG/ADV/SLG

Les fonctions de texte à position absolue dessinent directement sur la carte du fond. text_window ouvre une zone encadrée, text_clear_rect remplit une région et text_print_xy écrit les octets de tuiles sans décoder les contrôles. text_print_u8, text_print_u16 et text_print_s16 convertissent les nombres en décimal en n’utilisant que les cases nécessaires. Réservez et effacez un champ complet pour remplacer des valeurs de longueurs différentes.

Les fonctions RNG déclarées dans rpg.h sont implémentées dans lib/rng.c. Elles partagent le générateur GB du compilateur : rng_seed le réinitialise, rng8/rng_next8 consomment un octet, rng16/rng_next16 en consomment deux, et rand_range/rng_range, rng_chance et weighted_choice adaptent les tirages aux choix du jeu. Compilez rng.c avec le programme si vous appelez ces fonctions. Pour des tests reproductibles, fixez la graine et l’ordre des appels ; les choix par modulo ne garantissent pas des probabilités exactes.

Le décodage RLE utilise des paires d’octets count/value et un compte nul terminal. rle_decode lit un pointeur ordinaire vers la RAM ; rle_decode_far lit un pointeur associé à une banque ROM vers la RAM ; __rle_decode_vram décompresse directement en VRAM avec des écritures adaptées au LCD. Les fonctions RAM sont dans lib/rle.c ; l’opération VRAM directe est générée par le compilateur. Toutes trois renvoient le nombre d’octets produits et exigent un flux valide ainsi qu’un espace de destination suffisant.

Le stockage d’état de jeu déclaré dans rpg.h est implémenté par lib/flags.c. Les trois fonctions d’indicateurs agissent sur 2048 bits booléens indépendants ; quest_state et quest_set_state agissent sur 64 octets indépendants pour les étapes définies par le jeu. Compilez flags.c, respectez les limites d’ID et utilisez un système de sauvegarde distinct si la progression doit survivre à l’extinction.

Le dialogue fenêtré partage un rectangle actif, un curseur et un réglage de vitesse. text_open initialise la zone, text_close l’efface, text_set_speed règle les attentes VBlank par caractère. text_print et text_print_far interprètent les flux ; text_choice exécute un sélecteur vertical bloquant. Chargez les tuiles, dimensionnez la zone et prévoyez la gestion de ces appels bloquants dans le jeu.

Fournit le dessin de cartes et métatuiles, les scripts, les sauvegardes SRAM et la recherche de chemins. Les cases ordinaires mesurent 8×8 pixels, les métatuiles 16×16. Chargement/dessin, masques de déplacement et d’attaque sont distincts ; le jeu coordonne le chargement graphique et l’exécution des événements.

La recherche utilise environ 4 Kio d’espace de travail partagé non réentrant. Limitez les cartes à 1024 cases et les distances explorées à 254. La distance 0xFF signifie « non atteint » : un trajet de 255 pas n’est donc pas représentable. Les sorties de coût et de masque nécessitent width*height octets accessibles en écriture.

Par défaut, quatre emplacements de 512 octets contiennent chacun un en-tête de six octets et jusqu’à 506 octets de données. L’exemple utilise MBC5 avec 8 Kio de SRAM. Les appels se terminent avec la RAM désactivée, sans restaurer sa banque ni son état d’activation précédent.

Les menus proposent une sélection bloquante ou des appels séparés de traitement des entrées et de dessin, pilotés par la boucle de jeu. Le menu d’inventaire affiche les noms des objets et leurs quantités.

camera_center

Centre une case de carte ordinaire dans une zone visible de 20×18 tuiles, avec limitation aux bords de la carte.

Syntaxe

c
void camera_center(u8 x, u8 y);

Paramètres

x

Coordonnée X de la case.

y

Coordonnée Y de la case.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

L’origine part de max(x−10,0), max(y−9,0), est limitée aux bords de la carte, puis les octets faibles d’origine*8 sont écrits dans SCX/SCY. Cette opération ne s’applique pas en mode métatuile. Elle ne charge pas de nouvelles lignes ou colonnes en VRAM.

Exemple d’utilisation

c
camera_center(5,4);result[9]=*((u8*)0xFF43);result[10]=*((u8*)0xFF42);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La grille de gauche montre les coûts de déplacement en trois pas au plus ; celle de droite, un plus court chemin de S à G. Des astérisques verts tracent neuf pas autour d’un mur rouge de trois cases ; les chiffres bleus donnent les coûts. Le DMG utilise la même disposition en noir. Les contrôles RAM montrent aussi que le masque d’attaque ignore les murs.

camera_center: DMG
DMG
camera_center: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_map_path.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_map_path.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:297

Notes de déclaration (texte source)
Center an ordinary-map tile coordinate within a 20-by-18 viewport and clamp
the scroll origin to its edges. This adjusts scroll registers only; it does
not stream newly exposed map rows into VRAM.

kitaqgb/lib/map.c:105

c
void camera_center(u8 x, u8 y)
{
    u8 tile_x = 0;
    u8 tile_y = 0;
    u8 max_x = 0;
    u8 max_y = 0;

    map_camera_x = x;
    map_camera_y = y;

    if (map_loaded == 0) return;

    if (map_current.width > 20) max_x = (u8)(map_current.width - 20);
    if (map_current.height > 18) max_y = (u8)(map_current.height - 18);

    if (x > 10) tile_x = (u8)(x - 10);
    if (y > 9) tile_y = (u8)(y - 9);

    if (tile_x > max_x) tile_x = max_x;
    if (tile_y > max_y) tile_y = max_y;

    __scroll_bg_set((u8)(tile_x << 3), (u8)(tile_y << 3));
}
far_read16

Lit un mot petit-boutiste au moyen d’un pointeur indiquant sa banque.

Syntaxe

c
#define far_read16(p) __farpeek16((p).bank, (p).ptr)

Paramètres

p

far_ptr_t contenant bank et ptr, où ptr est une adresse visible par le CPU.

Valeur renvoyée

Le mot sous forme de u16.

Conditions et limites

La macro lit p.bank et p.ptr séparément ; ne passez pas d’expression à effets de bord. La fonction intrinsèque sélectionne temporairement la banque ROM puis la restaure. Évitez les changements de banque concurrents depuis les interruptions.

Exemple d’utilisation

c
result[1]=far_read16(far);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Lisez les octets hexadécimaux 34 12 AB depuis une autre banque ROM : premier octet 52, mot petit-boutiste 4660 et dernier octet copié 171.

far_read16: DMG
DMG
far_read16: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_far.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_far.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:172

far_read8

Lit un octet au moyen d’un pointeur indiquant sa banque.

Syntaxe

c
#define far_read8(p) __farpeek8((p).bank, (p).ptr)

Paramètres

p

far_ptr_t contenant bank et ptr, où ptr est une adresse visible par le CPU.

Valeur renvoyée

L’octet sous forme de u8.

Conditions et limites

La macro lit p.bank et p.ptr séparément ; ne passez pas d’expression à effets de bord. La fonction intrinsèque sélectionne temporairement la banque ROM puis la restaure. Évitez les changements de banque concurrents depuis les interruptions.

Exemple d’utilisation

c
far.bank=1;far.ptr=bank_bytes;result[0]=far_read8(far);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Lisez les octets hexadécimaux 34 12 AB depuis une autre banque ROM : premier octet 52, mot petit-boutiste 4660 et dernier octet copié 171.

far_read8: DMG
DMG
far_read8: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_far.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_far.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:171

far_read_block

Copie des octets consécutifs vers la RAM depuis un pointeur indiquant sa banque.

Syntaxe

c
#define far_read_block(dst, p, len) __farmemcpy((dst), (p).bank, (p).ptr, (len))

Paramètres

dst

Début d’une zone RAM de len octets accessible en écriture.

p

far_ptr_t contenant bank et ptr, où ptr est une adresse visible par le CPU.

len

Nombre d’octets ; gardez toute la source dans sa banque.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Macro qui appelle __farmemcpy. Elle ne franchit pas automatiquement les limites de banque ROM et ne gère pas un déplacement de zones mémoire qui se chevauchent.

Exemple d’utilisation

c
far_read_block(copy,far,3);result[2]=copy[2];

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Lisez les octets hexadécimaux 34 12 AB depuis une autre banque ROM : premier octet 52, mot petit-boutiste 4660 et dernier octet copié 171.

far_read_block: DMG
DMG
far_read_block: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_far.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_far.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:173

flag_clear

Remet un indicateur de jeu à 0 sans effacer les indicateurs voisins. Utilisez cette fonction lorsqu’une condition d’événement est annulée ou pour initialiser explicitement un indicateur. Un indicateur déjà nul reste à zéro.

Syntaxe

c
void flag_clear(u16 id);

Paramètres

id

Numéro d’indicateur de 0 à 2047, passé en u16. Le décalage en octets est id / 8 et le bit dans cet octet est id % 8, à partir du bit de poids faible. Le type de paramètre plus large n’agrandit pas le stockage fixe de 2048 indicateurs.

Valeur renvoyée

Aucune (void).

Conditions et limites

La fonction ne valide pas l’ID. Gardez les ID d’indicateurs inférieurs à 2048 et les ID de quêtes inférieurs à 64 ; un accès hors limites peut lire ou écraser de la RAM sans rapport. Les exemples initialisent explicitement les valeurs au lieu de dépendre du contenu au démarrage.

flags.c possède 256 octets de RAM pour les indicateurs et 64 octets distincts pour les quêtes. Ces fonctions n’accèdent pas à la RAM de sauvegarde de la cartouche et ne conservent pas les données après extinction. Pour préserver la progression, le jeu doit sérialiser les valeurs d’indicateurs et de quêtes via son système de sauvegarde, puis les restaurer au chargement.

Incluez rpg.h et compilez lib/flags.c avec le jeu. Les tableaux sont privés à ce fichier source ; accédez-y par les API d’indicateurs et de quêtes. Tous les appelants partagent ce stockage : coordonnez vous-même les écritures de la boucle principale et des gestionnaires d’interruption.

Exemple d’utilisation

c
flag_clear(9);flag_clear(9); // Mark it closed; clearing twice still leaves 0.
cleared=flag_get(9);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple désactive l’indicateur de porte 9 après l’avoir activé. DOOR CLOSED affiche 000 même si l’effacement est appelé deux fois. L’observation précédente DOOR OPEN reste visible à 001 pour comparer les deux valeurs relevées.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG et bleu sur CGB. FAILED doit valoir 000. Les captures montrent uniquement le comportement des états en RAM ; elles ne démontrent pas la sauvegarde d’une partie.

La vérification sur l’émulateur DMG a couvert tous les ID d’indicateurs de 0 à 2047, les activations et effacements répétés, les entrées voisines et les 256 valeurs d’état de chacune des 64 quêtes. Un motif final de 256 octets d’indicateurs et les 64 octets de quêtes ont été comparés aux données attendues. Les deux écrans pédagogiques ont été vérifiés après 240 images. Le matériel réel et la persistance des sauvegardes n’ont pas été testés.

flag_clear: DMG
DMG
flag_clear: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\flags_quests.c .\kitaqgb\lib\flags.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\flags_quests.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:372

Notes de déclaration (texte source)
Clear a flag bit; id must be below 2048.

kitaqgb/lib/flags.c:21

c
void flag_clear(u16 id)
{
    __bit_clear(flags_bits, id);
}
flag_get

Lit un indicateur de jeu binaire dans le tableau de bits RAM de la bibliothèque. Utilisez-le pour savoir si une porte est ouverte, si un objet a été ramassé ou si un autre événement défini par le jeu s’est produit. La lecture ne modifie pas l’indicateur.

Syntaxe

c
u8 flag_get(u16 id);

Paramètres

id

Numéro d’indicateur de 0 à 2047, passé en u16. Le décalage en octets est id / 8 et le bit dans cet octet est id % 8, à partir du bit de poids faible. Le type de paramètre plus large n’agrandit pas le stockage fixe de 2048 indicateurs.

Valeur renvoyée

Booléen u8 normalisé : 0 si l’indicateur est désactivé, 1 s’il est activé. Cette bibliothèque GB appelle l’intrinsèque GB __bit_test, qui normalise le résultat.

Conditions et limites

La fonction ne valide pas l’ID. Gardez les ID d’indicateurs inférieurs à 2048 et les ID de quêtes inférieurs à 64 ; un accès hors limites peut lire ou écraser de la RAM sans rapport. Les exemples initialisent explicitement les valeurs au lieu de dépendre du contenu au démarrage.

flags.c possède 256 octets de RAM pour les indicateurs et 64 octets distincts pour les quêtes. Ces fonctions n’accèdent pas à la RAM de sauvegarde de la cartouche et ne conservent pas les données après extinction. Pour préserver la progression, le jeu doit sérialiser les valeurs d’indicateurs et de quêtes via son système de sauvegarde, puis les restaurer au chargement.

Incluez rpg.h et compilez lib/flags.c avec le jeu. Les tableaux sont privés à ce fichier source ; accédez-y par les API d’indicateurs et de quêtes. Tous les appelants partagent ce stockage : coordonnez vous-même les écritures de la boucle principale et des gestionnaires d’interruption.

Exemple d’utilisation

c
before=flag_get(9); // Door-open flag: 0 after explicit initialization.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple affecte l’indicateur 9 à une porte. Après sa remise à zéro explicite, BEFORE affiche 000. L’activation puis la désactivation affichent ensuite DOOR OPEN 001 et DOOR CLOSED 000, montrant que les lectures reflètent la condition mémorisée.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG et bleu sur CGB. FAILED doit valoir 000. Les captures montrent uniquement le comportement des états en RAM ; elles ne démontrent pas la sauvegarde d’une partie.

La vérification sur l’émulateur DMG a couvert tous les ID d’indicateurs de 0 à 2047, les activations et effacements répétés, les entrées voisines et les 256 valeurs d’état de chacune des 64 quêtes. Un motif final de 256 octets d’indicateurs et les 64 octets de quêtes ont été comparés aux données attendues. Les deux écrans pédagogiques ont été vérifiés après 240 images. Le matériel réel et la persistance des sauvegardes n’ont pas été testés.

flag_get: DMG
DMG
flag_get: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\flags_quests.c .\kitaqgb\lib\flags.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\flags_quests.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:368

Notes de déclaration (texte source)
Read a bit from the flag array. Callers must keep id below 2048.

kitaqgb/lib/flags.c:9

c
u8 flag_get(u16 id)
{
    return __bit_test(flags_bits, id);
}
flag_set

Met un indicateur de jeu à 1 en conservant les sept autres bits de son octet. Un indicateur déjà activé reste actif ; utilisez cette fonction pour mémoriser un événement unique, comme l’ouverture d’une porte.

Syntaxe

c
void flag_set(u16 id);

Paramètres

id

Numéro d’indicateur de 0 à 2047, passé en u16. Le décalage en octets est id / 8 et le bit dans cet octet est id % 8, à partir du bit de poids faible. Le type de paramètre plus large n’agrandit pas le stockage fixe de 2048 indicateurs.

Valeur renvoyée

Aucune (void).

Conditions et limites

La fonction ne valide pas l’ID. Gardez les ID d’indicateurs inférieurs à 2048 et les ID de quêtes inférieurs à 64 ; un accès hors limites peut lire ou écraser de la RAM sans rapport. Les exemples initialisent explicitement les valeurs au lieu de dépendre du contenu au démarrage.

flags.c possède 256 octets de RAM pour les indicateurs et 64 octets distincts pour les quêtes. Ces fonctions n’accèdent pas à la RAM de sauvegarde de la cartouche et ne conservent pas les données après extinction. Pour préserver la progression, le jeu doit sérialiser les valeurs d’indicateurs et de quêtes via son système de sauvegarde, puis les restaurer au chargement.

Incluez rpg.h et compilez lib/flags.c avec le jeu. Les tableaux sont privés à ce fichier source ; accédez-y par les API d’indicateurs et de quêtes. Tous les appelants partagent ce stockage : coordonnez vous-même les écritures de la boucle principale et des gestionnaires d’interruption.

Exemple d’utilisation

c
flag_set(9); // Mark the door as open; setting an already set flag is harmless.
flag_set(9);
opened=flag_get(9);neighbor=flag_get(8); // 1 and 0: adjacent flag is unchanged.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple active deux fois l’indicateur de porte 9. DOOR OPEN affiche 001 et l’indicateur voisin 8 reste à NEIGHBOR 000. Les deux occupent le même octet ; la valeur voisine montre donc que l’activation d’un indicateur préserve l’autre.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG et bleu sur CGB. FAILED doit valoir 000. Les captures montrent uniquement le comportement des états en RAM ; elles ne démontrent pas la sauvegarde d’une partie.

La vérification sur l’émulateur DMG a couvert tous les ID d’indicateurs de 0 à 2047, les activations et effacements répétés, les entrées voisines et les 256 valeurs d’état de chacune des 64 quêtes. Un motif final de 256 octets d’indicateurs et les 64 octets de quêtes ont été comparés aux données attendues. Les deux écrans pédagogiques ont été vérifiés après 240 images. Le matériel réel et la persistance des sauvegardes n’ont pas été testés.

flag_set: DMG
DMG
flag_set: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\flags_quests.c .\kitaqgb\lib\flags.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\flags_quests.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:370

Notes de déclaration (texte source)
Set a flag bit without disturbing adjacent flags; id must be below 2048.

kitaqgb/lib/flags.c:15

c
void flag_set(u16 id)
{
    __bit_set(flags_bits, id);
}
map_current_height

Lit la hauteur de la carte active.

Syntaxe

c
u8 map_current_height();

Valeur renvoyée

Renvoie la hauteur en cases, ou zéro si aucune carte n’est chargée.

Conditions et limites

Les coordonnées désignent les cases de la carte active : 8×8 pixels pour les tuiles ordinaires, 16×16 pour les métatuiles.

Exemple d’utilisation

c
result[1]=map_current_height();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La grille de gauche montre les coûts de déplacement en trois pas au plus ; celle de droite, un plus court chemin de S à G. Des astérisques verts tracent neuf pas autour d’un mur rouge de trois cases ; les chiffres bleus donnent les coûts. Le DMG utilise la même disposition en noir. Les contrôles RAM montrent aussi que le masque d’attaque ignore les murs.

map_current_height: DMG
DMG
map_current_height: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_map_path.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_map_path.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:391

Notes de déclaration (texte source)
Return the active map height in its own cell units, or zero when no map is loaded.

kitaqgb/lib/map.c:25

c
u8 map_current_height()
{
    if (map_meta_loaded != 0) return map_meta_current.height;
    if (map_loaded == 0) return 0;
    return map_current.height;
}
map_current_width

Lit la largeur de la carte active.

Syntaxe

c
u8 map_current_width();

Valeur renvoyée

Renvoie la largeur en cases, ou zéro si aucune carte n’est chargée.

Conditions et limites

Les coordonnées désignent les cases de la carte active : 8×8 pixels pour les tuiles ordinaires, 16×16 pour les métatuiles.

Exemple d’utilisation

c
result[0]=map_current_width();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La grille de gauche montre les coûts de déplacement en trois pas au plus ; celle de droite, un plus court chemin de S à G. Des astérisques verts tracent neuf pas autour d’un mur rouge de trois cases ; les chiffres bleus donnent les coûts. Le DMG utilise la même disposition en noir. Les contrôles RAM montrent aussi que le masque d’attaque ignore les murs.

map_current_width: DMG
DMG
map_current_width: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_map_path.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_map_path.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:389

Notes de déclaration (texte source)
Return the active map width in its own cell units, or zero when no map is loaded.

kitaqgb/lib/map.c:17

c
u8 map_current_width()
{
    if (map_meta_loaded != 0) return map_meta_current.width;
    if (map_loaded == 0) return 0;
    return map_current.width;
}
map_draw_visible

Dessine 10×9 métatuiles depuis l’origine demandée et mémorise cette position de caméra pour les rafraîchissements après modification.

Syntaxe

c
void map_draw_visible(u8 camera_tx, u8 camera_ty);

Paramètres

camera_tx

X de la case la plus à gauche ; limitez-le à 246 pour éviter un rebouclage d’octet pendant le parcours.

camera_ty

Y de la case la plus haute ; limitez-le à 247.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Les cases extérieures dessinent la métatuile d’identifiant zéro ; fournissez donc toujours la définition zéro. L’appel laisse inchangées les cases hors de la zone de 20×18 tuiles et les attributs CGB.

Exemple d’utilisation

c
map_draw_visible(1,0);result[9]=*((u8*)0x9800);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Modifiez un identifiant de métatuile en RAM, signalez la modification puis appliquez-la. La caméra (1,0) montre un carré vert de 16×16 en haut à gauche. L’exemple applique explicitement les métadonnées de palette aux attributs CGB. Le DMG affiche un carré noir.

map_draw_visible: DMG
DMG
map_draw_visible: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_metatile.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_metatile.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:304

Notes de déclaration (texte source)
Draw a 10-by-9 metatile viewport as 20-by-18 individual background tiles.
Out-of-range cells use definition zero; palette attributes are not written.
Remember the camera and clear the dirty flag after the full redraw.

kitaqgb/lib/map.c:212

c
void map_draw_visible(u8 camera_tx, u8 camera_ty)
{
    u8 my;

    if (map_meta_loaded == 0) return;

    map_camera_x = camera_tx;
    map_camera_y = camera_ty;

    my = 0;
    while (my < 9) {
        u8 mx = 0;
        while (mx < 10) {
            u8 tx = (u8)(camera_tx + mx);
            u8 ty = (u8)(camera_ty + my);
            u8 sx = (u8)(mx << 1);
            u8 sy = (u8)(my << 1);
            metatile_t meta;
            u8 id = map_get_metatile(tx, ty);
            map_read_metatile(id, &meta);
            __settile_xy(sx, sy, meta.tile_tl);
            __settile_xy((u8)(sx + 1), sy, meta.tile_tr);
            __settile_xy(sx, (u8)(sy + 1), meta.tile_bl);
            __settile_xy((u8)(sx + 1), (u8)(sy + 1), meta.tile_br);
            mx++;
        }
        my++;
    }
    map_dirty = 0;
}
map_flush_dirty

Si une modification est signalée, redessine la zone visible depuis l’origine de caméra mémorisée et efface le drapeau de modification.

Syntaxe

c
void map_flush_dirty();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Ne fait rien sans modification signalée. Le rafraîchissement couvre toutes les 10×9 métatuiles, pas uniquement la case modifiée.

Exemple d’utilisation

c
map_flush_dirty();result[11]=*((u8*)0x9800);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Modifiez un identifiant de métatuile en RAM, signalez la modification puis appliquez-la. La caméra (1,0) montre un carré vert de 16×16 en haut à gauche. L’exemple applique explicitement les métadonnées de palette aux attributs CGB. Le DMG affiche un carré noir.

map_flush_dirty: DMG
DMG
map_flush_dirty: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_metatile.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_metatile.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:321

Notes de déclaration (texte source)
Redraw the remembered metatile viewport only when the shared dirty flag is set.

kitaqgb/lib/map.c:254

c
void map_flush_dirty()
{
    if (map_dirty == 0) return;
    map_draw_visible(map_camera_x, map_camera_y);
}
map_get_attr

Lit les métadonnées de palette dans la définition de métatuile de la case.

Syntaxe

c
u8 map_get_attr(u8 tx, u8 ty);

Paramètres

tx

Coordonnée X de métatuile.

ty

Coordonnée Y de métatuile.

Valeur renvoyée

Renvoie l’octet de palette. Les cases extérieures utilisent la définition zéro ; sans mode métatuile, renvoie zéro.

Conditions et limites

Les coordonnées désignent les cases de la carte active : 8×8 pixels pour les tuiles ordinaires, 16×16 pour les métatuiles.

Exemple d’utilisation

c
result[3]=map_get_attr(0,0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Modifiez un identifiant de métatuile en RAM, signalez la modification puis appliquez-la. La caméra (1,0) montre un carré vert de 16×16 en haut à gauche. L’exemple applique explicitement les métadonnées de palette aux attributs CGB. Le DMG affiche un carré noir.

map_get_attr: DMG
DMG
map_get_attr: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_metatile.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_metatile.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:310

Notes de déclaration (texte source)
Return the selected definition's palette byte. An out-of-range coordinate
uses the metatile-zero fallback; this function does not write CGB attributes.

kitaqgb/lib/map.c:172

c
u8 map_get_attr(u8 tx, u8 ty)
{
    metatile_t meta;
    u8 id;
    if (map_meta_loaded == 0) return 0;
    id = map_get_metatile(tx, ty);
    map_read_metatile(id, &meta);
    return meta.palette;
}
map_get_event

Lit un identifiant d’événement de métatuile ; les cartes ordinaires indiquent la présence d’un événement.

Syntaxe

c
u8 map_get_event(u8 tx, u8 ty);

Paramètres

tx

Coordonnée X de métatuile.

ty

Coordonnée Y de métatuile.

Valeur renvoyée

Renvoie l’octet d’événement de métatuile ou le booléen de carte ordinaire ; les cases absentes ou extérieures donnent zéro.

Conditions et limites

Les coordonnées désignent les cases de la carte active : 8×8 pixels pour les tuiles ordinaires, 16×16 pour les métatuiles.

Exemple d’utilisation

c
result[7]=map_get_event(0,0);result[8]=map_get_event(3,0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Modifiez un identifiant de métatuile en RAM, signalez la modification puis appliquez-la. La caméra (1,0) montre un carré vert de 16×16 en haut à gauche. L’exemple applique explicitement les métadonnées de palette aux attributs CGB. Le DMG affiche un carré noir.

map_get_event: DMG
DMG
map_get_event: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_metatile.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_metatile.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:316

Notes de déclaration (texte source)
Return a metatile event ID, or the ordinary-map Boolean trigger result.
Missing/out-of-range metatile cells have no event.

kitaqgb/lib/map.c:197

c
u8 map_get_event(u8 tx, u8 ty)
{
    metatile_t meta;
    u8 id;
    if (map_meta_loaded == 0) return map_trigger_at(tx, ty);
    if (tx >= map_meta_current.width || ty >= map_meta_current.height) return 0;
    id = map_get_metatile(tx, ty);
    map_read_metatile(id, &meta);
    return meta.event;
}
map_get_metatile

Lit l’identifiant de métatuile d’une case.

Syntaxe

c
u8 map_get_metatile(u8 tx, u8 ty);

Paramètres

tx

Coordonnée X de métatuile.

ty

Coordonnée Y de métatuile.

Valeur renvoyée

Renvoie l’identifiant, ou zéro hors de la carte ou sans mode métatuile.

Conditions et limites

Les coordonnées désignent les cases de la carte active : 8×8 pixels pour les tuiles ordinaires, 16×16 pour les métatuiles.

Exemple d’utilisation

c
result[1]=map_get_metatile(0,0);result[2]=map_get_metatile(3,0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Modifiez un identifiant de métatuile en RAM, signalez la modification puis appliquez-la. La caméra (1,0) montre un carré vert de 16×16 en haut à gauche. L’exemple applique explicitement les métadonnées de palette aux attributs CGB. Le DMG affiche un carré noir.

map_get_metatile: DMG
DMG
map_get_metatile: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_metatile.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_metatile.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:307

Notes de déclaration (texte source)
Read a row-major metatile ID, returning ID zero for inactive or out-of-range
lookups. Callers must provide a usable definition for metatile zero.

kitaqgb/lib/map.c:159

c
u8 map_get_metatile(u8 tx, u8 ty)
{
    u16 index;

    if (map_meta_loaded == 0) return 0;
    if (tx >= map_meta_current.width || ty >= map_meta_current.height) return 0;

    index = __map_index(tx, ty, map_meta_current.width);
    return __farpeek8(map_meta_data_bank(), map_meta_current.metatile_ids + index);
}
map_is_blocked

Teste si une case de destination bloque le déplacement ; le mode métatuile utilise le champ collision de sa définition.

Syntaxe

c
u8 map_is_blocked(u8 x, u8 y);

Paramètres

x

Coordonnée X de la case.

y

Coordonnée Y de la case.

Valeur renvoyée

Renvoie 1 pour un mur, des coordonnées extérieures ou une carte absente, et 0 pour une case franchissable. Un tableau de collision NULL sur une carte ordinaire rend toutes ses cases intérieures franchissables.

Conditions et limites

Les coordonnées désignent les cases de la carte active : 8×8 pixels pour les tuiles ordinaires, 16×16 pour les métatuiles.

Exemple d’utilisation

c
result[4]=map_is_blocked(2,2);result[5]=map_is_blocked(6,2);result[6]=map_is_blocked(1,2);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La grille de gauche montre les coûts de déplacement en trois pas au plus ; celle de droite, un plus court chemin de S à G. Des astérisques verts tracent neuf pas autour d’un mur rouge de trois cases ; les chiffres bleus donnent les coûts. Le DMG utilise la même disposition en noir. Les contrôles RAM montrent aussi que le masque d’attaque ignore les murs.

map_is_blocked: DMG
DMG
map_is_blocked: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_map_path.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_map_path.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:290

Notes de déclaration (texte source)
Use metatile collision when that mode is active; otherwise read one packed
collision bit. Missing maps/out-of-range cells block movement, but a valid
ordinary map without a collision array is entirely passable.

kitaqgb/lib/map.c:68

c
u8 map_is_blocked(u8 x, u8 y)
{
    u16 index;
    u8 value;

    if (map_meta_loaded != 0) return map_is_solid(x, y);
    if (map_loaded == 0) return 1;
    if (x >= map_current.width || y >= map_current.height) return 1;
    if (map_current.collision_bits == 0) return 0;

    index = __map_index(x, y, map_current.width);
    // Collision uses least-significant bit first within each row-major group of eight cells.
    value = __farpeek8(map_bank, map_current.collision_bits + (index >> 3));
    if ((value & (u8)(1 << (index & 7))) != 0) return 1;
    return 0;
}
map_is_solid

Teste la solidité et délègue aux bits de collision en mode carte ordinaire.

Syntaxe

c
u8 map_is_solid(u8 tx, u8 ty);

Paramètres

tx

Coordonnée X de métatuile.

ty

Coordonnée Y de métatuile.

Valeur renvoyée

Renvoie 1 pour une collision non nulle ou une case extérieure, sinon 0.

Conditions et limites

Les coordonnées désignent les cases de la carte active : 8×8 pixels pour les tuiles ordinaires, 16×16 pour les métatuiles.

Exemple d’utilisation

c
result[4]=map_is_solid(0,0);result[5]=map_is_solid(1,0);result[6]=map_is_solid(3,0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Modifiez un identifiant de métatuile en RAM, signalez la modification puis appliquez-la. La caméra (1,0) montre un carré vert de 16×16 en haut à gauche. L’exemple applique explicitement les métadonnées de palette aux attributs CGB. Le DMG affiche un carré noir.

map_is_solid: DMG
DMG
map_is_solid: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_metatile.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_metatile.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:313

Notes de déclaration (texte source)
Treat out-of-range metatile cells as solid; otherwise inspect the definition
collision flag. In ordinary-map mode, delegate to its packed collision bits.

kitaqgb/lib/map.c:184

c
u8 map_is_solid(u8 tx, u8 ty)
{
    metatile_t meta;
    u8 id;
    if (map_meta_loaded == 0) return map_is_blocked(tx, ty);
    if (tx >= map_meta_current.width || ty >= map_meta_current.height) return 1;
    id = map_get_metatile(tx, ty);
    map_read_metatile(id, &meta);
    return (u8)(meta.collision != 0);
}
map_load

Charge un descripteur de carte ordinaire et dessine jusqu’à 20×18 tuiles depuis son coin supérieur gauche dans la carte de fond choisie.

Syntaxe

c
void map_load(u8 bank, const map_t* map);

Paramètres

bank

Banque ROM du descripteur, des bits de collision et des événements.

map

map_t compact de neuf octets. tiles contient width*height identifiants de tuile ; collision_bits range les cases en commençant par le bit de poids faible ; events stocke un octet par case. La lecture des tuiles utilise bank_tiles.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Une seule carte active est partagée. Le descripteur est copié, mais ses tableaux doivent rester lisibles aussi longtemps que nécessaire. Chargez séparément les graphismes de tuiles en VRAM.

Les coordonnées désignent les cases de la carte active : 8×8 pixels pour les tuiles ordinaires, 16×16 pour les métatuiles.

Les cases situées hors d’une petite carte ne sont pas effacées. Pour les cartes ordinaires, bank_tiles=0 signifie banque zéro ; la banque du descripteur n’est pas héritée.

Exemple d’utilisation

c
map_load(0,maps);result[2]=map_current_width();result[3]=map_current_height();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La grille de gauche montre les coûts de déplacement en trois pas au plus ; celle de droite, un plus court chemin de S à G. Des astérisques verts tracent neuf pas autour d’un mur rouge de trois cases ; les chiffres bleus donnent les coûts. Le DMG utilise la même disposition en noir. Les contrôles RAM montrent aussi que le masque d’attaque ignore les murs.

map_load: DMG
DMG
map_load: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_map_path.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_map_path.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:286

Notes de déclaration (texte source)
Load the nine-byte ordinary-map descriptor and draw up to 20 by 18 tiles
from its top-left corner. Drawing does not upload tile graphics or clear
background cells beyond smaller map dimensions.

kitaqgb/lib/map.c:35

c
void map_load(u8 bank, const map_t* map)
{
    u8 row;
    u8 h;
    u8 w;

    // The literal copy size depends on the packed map_t layout; changing that layout requires updating this copy.
    __farmemcpy(&map_current, bank, map, 9);
    map_bank = bank;
    map_loaded = 1;
    map_meta_loaded = 0;

    w = map_current.width;
    h = map_current.height;
    if (w > 20) w = 20;
    if (h > 18) h = 18;

    row = 0;
    while (row < h) {
        u8 x = 0;
        u16 base_index = __map_index(0, row, map_current.width);
        while (x < w) {
            map_row[x] = __farpeek8(map_current.bank_tiles, map_current.tiles + base_index + x);
            x++;
        }
        __settile_row(0, row, map_row, w);
        row++;
    }
}
map_load_metatile

Sélectionne une carte de métatuiles et développe une zone visible de 10×9 cases, caméra en (0,0), en 20×18 tuiles.

Syntaxe

c
void map_load_metatile(u8 bank, const metatile_map_t* map);

Paramètres

bank

Banque ROM contenant le descripteur.

map

Pointeur vers metatile_map_t. Les dimensions comptent les cases de 16×16 pixels. Il référence un tableau d’identifiants et une table de définitions metatile_t de sept octets.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Une seule carte active est partagée. Le descripteur est copié, mais ses tableaux doivent rester lisibles aussi longtemps que nécessaire. Chargez séparément les graphismes de tuiles en VRAM.

bank_tiles=0 hérite de la banque du descripteur ; une valeur non nulle choisit la banque des identifiants comme des définitions. Une définition stocke les tuiles supérieure gauche, supérieure droite, inférieure gauche et inférieure droite, puis collision, palette et événement. Le dessin n’applique pas automatiquement les métadonnées de palette.

Exemple d’utilisation

c
map_load_metatile(0,&level);result[0]=*((u8*)0x9800);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Modifiez un identifiant de métatuile en RAM, signalez la modification puis appliquez-la. La caméra (1,0) montre un carré vert de 16×16 en haut à gauche. L’exemple applique explicitement les métadonnées de palette aux attributs CGB. Le DMG affiche un carré noir.

map_load_metatile: DMG
DMG
map_load_metatile: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_metatile.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_metatile.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:300

Notes de déclaration (texte source)
Select metatile mode, copy its descriptor and draw the initial viewport
with the camera at cell (0,0).

kitaqgb/lib/map.c:145

c
void map_load_metatile(u8 bank, const metatile_map_t* map)
{
    map_meta_bank = bank;
    __farmemcpy(&map_meta_current, bank, map, sizeof(metatile_map_t));
    map_meta_loaded = 1;
    map_loaded = 0;
    map_dirty = 0;
    map_camera_x = 0;
    map_camera_y = 0;
    map_draw_visible(0, 0);
}
map_mark_dirty

Marque la zone visible pour un nouveau dessin lorsqu’une coordonnée de métatuile valide est fournie.

Syntaxe

c
void map_mark_dirty(u8 tx, u8 ty);

Paramètres

tx

Coordonnée X de métatuile.

ty

Coordonnée Y de métatuile.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Active un unique drapeau de modification partagé au lieu de mettre à jour chaque case dans une file. Les coordonnées extérieures sont ignorées. L’appelant modifie séparément les identifiants ou les définitions avant de signaler la modification.

Exemple d’utilisation

c
ids[1]=1;map_mark_dirty(1,0);result[10]=*((u8*)0x9800);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Modifiez un identifiant de métatuile en RAM, signalez la modification puis appliquez-la. La caméra (1,0) montre un carré vert de 16×16 en haut à gauche. L’exemple applique explicitement les métadonnées de palette aux attributs CGB. Le DMG affiche un carré noir.

map_mark_dirty: DMG
DMG
map_mark_dirty: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_metatile.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_metatile.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:319

Notes de déclaration (texte source)
Mark the viewport for a full redraw when a valid metatile cell changes.
The coordinate is validated but no per-cell dirty list is retained.

kitaqgb/lib/map.c:246

c
void map_mark_dirty(u8 tx, u8 ty)
{
    if (map_meta_loaded == 0) return;
    if (tx >= map_meta_current.width || ty >= map_meta_current.height) return;
    map_dirty = 1;
}
map_trigger_at

Vérifie si une case contient un événement, sans l’exécuter.

Syntaxe

c
u8 map_trigger_at(u8 x, u8 y);

Paramètres

x

Coordonnée X de la case.

y

Coordonnée Y de la case.

Valeur renvoyée

Renvoie 1 si un événement est présent, sinon 0 ; ne renvoie ni l’octet d’événement stocké ni l’identifiant d’événement de métatuile.

Conditions et limites

Les coordonnées désignent les cases de la carte active : 8×8 pixels pour les tuiles ordinaires, 16×16 pour les métatuiles.

Exemple d’utilisation

c
result[7]=map_trigger_at(5,4);result[8]=map_trigger_at(6,4);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La grille de gauche montre les coûts de déplacement en trois pas au plus ; celle de droite, un plus court chemin de S à G. Des astérisques verts tracent neuf pas autour d’un mur rouge de trois cases ; les chiffres bleus donnent les coûts. Le DMG utilise la même disposition en noir. Les contrôles RAM montrent aussi que le masque d’attaque ignore les murs.

map_trigger_at: DMG
DMG
map_trigger_at: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_map_path.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_map_path.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:293

Notes de déclaration (texte source)
Report whether an event exists at the cell. Ordinary maps expose a Boolean
byte-presence test; metatile maps reduce their event ID to a Boolean here.

kitaqgb/lib/map.c:87

c
u8 map_trigger_at(u8 x, u8 y)
{
    u16 index;
    u8 value;

    if (map_meta_loaded != 0) return (u8)(map_get_event(x, y) != 0);
    if (map_loaded == 0) return 0;
    if (x >= map_current.width || y >= map_current.height) return 0;
    if (map_current.events == 0) return 0;

    index = __map_index(x, y, map_current.width);
    value = __farpeek8(map_bank, ((const u8*)map_current.events) + index);
    return (u8)((value != 0) ? 1 : 0);
}
menu_draw

Dessine la bordure, les libellés et le curseur courant à partir de l’état du menu.

Syntaxe

c
void menu_draw(menu_state_t* state);

Paramètres

state

Pointeur vers un état de menu initialisé.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Un pointeur nul rend l’appel sans effet. Chaque appel rouvre la fenêtre avec text_open(), ce qui met aussi à jour l’état partagé de la fenêtre de texte. Aucune entrée n’est lue. Chargez au préalable les tuiles de bordure, de curseur et de texte. L’appelant doit conserver le tableau des éléments et leurs chaînes. Le texte n’est ni renvoyé automatiquement à la ligne ni tronqué aux limites de la fenêtre ; choisissez des positions, un nombre d’éléments et des longueurs de libellé qui tiennent dans la fenêtre.

Exemple d’utilisation

c
menu_draw(&menu_state);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple dessine le menu au départ puis le redessine après une entrée. Après DOWN, le curseur se trouve à côté de SHIELD.

menu_draw: DMG
DMG
menu_draw: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_menu_state.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_menu_state.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/rpg.h:273

Notes de déclaration (texte source)
Draw the current menu and cursor without waiting or sampling input. The
caller schedules suitable display timing and keeps item text within bounds.

kitaqgb/lib/menu.c:94

c
void menu_draw(menu_state_t* state)
{
    u8 i;
    if (state == 0) return;

    text_open(state->x, state->y, state->w, state->h);
    i = 0;
    while (i < state->count) {
        u8 py = (u8)(state->y + 1 + i);
        const u8* s = state->items[i];
        u8 px = (u8)(state->x + 2);
        __settile_xy((u8)(state->x + 1), py, (i == state->cursor) ? TEXT_TILE_CURSOR : TEXT_TILE_FILL);
        while (*s != 0) {
            __settile_xy(px, py, *s);
            px++;
            s++;
        }
        i++;
    }
}
menu_get_selected

Lit la sélection conservée par un menu traité progressivement.

Syntaxe

c
u8 menu_get_selected(menu_state_t* state);

Paramètres

state

Pointeur vers un état de menu initialisé.

Valeur renvoyée

Renvoie l’indice choisi, à partir de zéro, ou 255 si la sélection est en attente, annulée ou si le pointeur est nul.

Conditions et limites

La lecture n’efface pas le résultat. Arrêtez les mises à jour une fois l’interaction terminée et appelez menu_init_state() avant d’en commencer une nouvelle.

Exemple d’utilisation

c
result[0]=menu_get_selected(&menu_state);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple lit la sélection 1 pour SHIELD et vérifie qu’un pointeur nul donne 255.

menu_get_selected: DMG
DMG
menu_get_selected: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_menu_state.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_menu_state.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/rpg.h:279

Notes de déclaration (texte source)
Read the latched selection without clearing it; null state returns 0xFF.

kitaqgb/lib/menu.c:148

c
u8 menu_get_selected(menu_state_t* state)
{
    if (state == 0) return 0xFF;
    return state->selected;
}
menu_init_state

Initialise un menu dont le traitement sera réparti entre les passages de la boucle de jeu.

Syntaxe

c
void menu_init_state(menu_state_t* state, u8 x, u8 y, u8 w, u8 h, const u8* const* items, u8 count);

Paramètres

state

menu_state_t accessible en écriture et non nul, à initialiser.

x

Colonne de tuiles du bord gauche de la fenêtre.

y

Ligne de tuiles du bord supérieur de la fenêtre.

w

Largeur en tuiles, bordure comprise.

h

Hauteur en tuiles, bordure comprise.

items

Tableau de pointeurs vers les libellés des éléments, terminés par un octet nul.

count

Nombre d’éléments, limité au nombre de lignes disponibles à l’intérieur de la fenêtre.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Met le curseur et l’état précédent des boutons à zéro, la sélection à 255 et l’annulation à zéro. Ne dessine rien et n’attend aucune entrée. Chargez au préalable les tuiles de bordure, de curseur et de texte. L’appelant doit conserver le tableau des éléments et leurs chaînes. Le texte n’est ni renvoyé automatiquement à la ligne ni tronqué aux limites de la fenêtre ; choisissez des positions, un nombre d’éléments et des longueurs de libellé qui tiennent dans la fenêtre.

Exemple d’utilisation

c
menu_init_state(&menu_state,1,2,18,5,choices,3);result[2]=menu_state.selected;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple prépare un menu de trois éléments en (1,2), de 18×5 tuiles, avec une sélection initiale de 255.

menu_init_state: DMG
DMG
menu_init_state: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_menu_state.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_menu_state.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/rpg.h:270

Notes de déclaration (texte source)
Initialize a nonblocking menu state that borrows the item pointer table.
Selection starts unset (0xFF), and the cancellation flag starts clear.

kitaqgb/lib/menu.c:78

c
void menu_init_state(menu_state_t* state, u8 x, u8 y, u8 w, u8 h, const u8* const* items, u8 count)
{
    state->x = x;
    state->y = y;
    state->w = w;
    state->h = h;
    state->items = items;
    state->count = count;
    state->cursor = 0;
    state->prev_keys = 0;
    state->selected = 0xFF;
    state->cancelled = 0;
}
menu_inventory

Affiche les noms des objets de l’inventaire et leurs quantités sur deux chiffres, puis laisse le joueur choisir un objet.

Syntaxe

c
u8 menu_inventory(const item_t* items, u8 count);

Paramètres

items

Tableau item_t accessible en lecture, contenant les identifiants, quantités et noms.

count

Nombre d’objets : de 1 à 15 pour une liste visible, zéro pour une liste vide.

Valeur renvoyée

Renvoie l’indice de tableau choisi, et non l’identifiant de l’objet, ou 255 en cas d’annulation ou de liste vide.

Conditions et limites

Les objets et leurs quantités ne sont pas modifiés. Utilisez des quantités de 0 à 99 et au plus 15 objets visibles. La fenêtre est en (1,1), de largeur 18 et de hauteur égale au nombre d’objets plus 2. Les noms commencent à la colonne 3 et les quantités occupent les colonnes 15–16 ; des noms trop longs peuvent les écraser. UP/DOWN revient à l’autre extrémité de la liste et A est prioritaire sur B en cas d’appui simultané. Chargez au préalable les tuiles de bordure, de curseur et de texte. L’appelant doit conserver le tableau des éléments et leurs chaînes. Le texte n’est ni renvoyé automatiquement à la ligne ni tronqué aux limites de la fenêtre ; choisissez des positions, un nombre d’éléments et des longueurs de libellé qui tiennent dans la fenêtre.

Exemple d’utilisation

c
result[0]=menu_inventory(items,3);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La fenêtre affiche SWORD 07, SHIELD 42 et POTION 99. Choisir SHIELD renvoie l’indice 1 et laisse sa quantité à 42.

menu_inventory: DMG
DMG
menu_inventory: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_menu_inventory.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_menu_inventory.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/rpg.h:267

Notes de déclaration (texte source)
Run a blocking item menu, drawing names and two-digit quantities. Return
the selected index or 0xFF on empty input/B; this does not consume an item.

kitaqgb/lib/menu.c:176

c
u8 menu_inventory(const item_t* items, u8 count)
{
    u8 cursor;
    u8 prev;
    u8 i;

    if (count == 0) return 0xFF;

    text_open(1, 1, 18, (u8)(count + 2));
    cursor = 0;
    prev = 0;

    while (1) {
        for (i = 0; i < count; i++) {
            u8 py = (u8)(2 + i);
            const u8* s = items[i].name;
            u8 px = 3;
            __settile_xy(2, py, (i == cursor) ? TEXT_TILE_CURSOR : TEXT_TILE_FILL);
            while (*s != 0) {
                __settile_xy(px, py, *s);
                px++;
                s++;
            }
            menu_draw_ascii_qty(15, py, items[i].qty);
        }

        __wait_vblank();
        {
            u16 kt = __readpadex(prev);
            u8 trigger;
            prev = (u8)kt;
            trigger = (u8)(kt >> 8);

            if ((trigger & PAD_KEY_UP) != 0) {
                if (cursor == 0) cursor = (u8)(count - 1);
                else cursor--;
            }
            if ((trigger & PAD_KEY_DOWN) != 0) {
                cursor++;
                if (cursor >= count) cursor = 0;
            }
            if ((trigger & PAD_KEY_A) != 0) return cursor;
            if ((trigger & PAD_KEY_B) != 0) return 0xFF;
        }
    }
}
menu_run

Affiche un menu de sélection et attend une confirmation ou une annulation.

Syntaxe

c
u8 menu_run(const menu_t* menu);

Paramètres

menu

menu_t non nul définissant la position, la taille, les éléments, leur nombre et le curseur initial. Une position initiale hors limites est remplacée par zéro.

Valeur renvoyée

Renvoie l’indice choisi, à partir de zéro, ou 255 en cas d’annulation avec B ou de liste vide.

Conditions et limites

Chaque nouvel appui sur UP/DOWN déplace le curseur et revient à l’autre extrémité de la liste ; maintenir un bouton n’entraîne pas de répétition. A est prioritaire sur B en cas d’appui simultané. Les boutons déjà enfoncés à l’entrée sont considérés comme de nouveaux appuis. menu->cursor fournit la position initiale et ne reçoit pas le résultat. La fenêtre reste affichée après le retour. Chargez au préalable les tuiles de bordure, de curseur et de texte. L’appelant doit conserver le tableau des éléments et leurs chaînes. Le texte n’est ni renvoyé automatiquement à la ligne ni tronqué aux limites de la fenêtre ; choisissez des positions, un nombre d’éléments et des longueurs de libellé qui tiennent dans la fenêtre.

Exemple d’utilisation

c
result[0]=menu_run(&menu);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Dans la liste SWORD/SHIELD/POTION, DOWN puis A choisit SHIELD, d’indice 1. La position initiale du curseur enregistrée reste à zéro.

menu_run: DMG
DMG
menu_run: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_menu_run.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_menu_run.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/rpg.h:262

Notes de déclaration (texte source)
Run a blocking menu loop with wraparound up/down selection, A to accept
and B to cancel. Return 0xFF for an empty menu or cancellation. Item strings
and menu dimensions must fit the visible tile area.

kitaqgb/lib/menu.c:25

c
u8 menu_run(const menu_t* menu)
{
    u8 cursor;
    u8 prev;

    if (menu->count == 0) return 0xFF;

    text_open(menu->x, menu->y, menu->w, menu->h);
    cursor = menu->cursor;
    if (cursor >= menu->count) cursor = 0;
    prev = 0;

    while (1) {
        u8 i;
        for (i = 0; i < menu->count; i++) {
            u8 py = (u8)(menu->y + 1 + i);
            __settile_xy((u8)(menu->x + 1), py, (i == cursor) ? TEXT_TILE_CURSOR : TEXT_TILE_FILL);
            {
                const u8* s = menu->items[i];
                u8 px = (u8)(menu->x + 2);
                while (*s != 0) {
                    __settile_xy(px, py, *s);
                    px++;
                    s++;
                }
            }
        }

        __wait_vblank();
        {
            u16 kt = __readpadex(prev);
            u8 trigger;
            prev = (u8)kt;
            trigger = (u8)(kt >> 8);

            if ((trigger & PAD_KEY_UP) != 0) {
                if (cursor == 0) cursor = (u8)(menu->count - 1);
                else cursor--;
            }
            if ((trigger & PAD_KEY_DOWN) != 0) {
                cursor++;
                if (cursor >= menu->count) cursor = 0;
            }
            if ((trigger & PAD_KEY_A) != 0) return cursor;
            if ((trigger & PAD_KEY_B) != 0) return 0xFF;
        }
    }
}
menu_update

Lit une transition des boutons de la manette et met à jour le curseur, la sélection et l’état d’annulation.

Syntaxe

c
void menu_update(menu_state_t* state);

Paramètres

state

État de menu initialisé dont l’historique des entrées et les résultats seront mis à jour.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Un pointeur nul ou une liste vide rend l’appel sans effet. La fonction n’attend pas de trame et ne dessine rien ; appelez-la environ une fois par trame de la boucle de jeu. UP/DOWN revient à l’autre extrémité de la liste, sans répétition si le bouton reste enfoncé. B est traité après A : un appui simultané sur A/B annule donc la sélection.

Exemple d’utilisation

c
menu_update(&menu_state);menu_draw(&menu_state);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La boucle attend VBlank, met à jour le menu puis le dessine, jusqu’à une sélection ou une annulation. DOWN puis A donne une sélection de 1 et un drapeau d’annulation à 0.

menu_update: DMG
DMG
menu_update: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_menu_state.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_menu_state.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/rpg.h:277

Notes de déclaration (texte source)
Sample new button presses and update cursor/selection state without drawing.
Selected and cancelled results remain latched; a B press in the same update
as A clears selection and leaves cancellation set.

kitaqgb/lib/menu.c:118

c
void menu_update(menu_state_t* state)
{
    u16 kt;
    u8 trigger;

    if (state == 0) return;
    if (state->count == 0) return;

    kt = __readpadex(state->prev_keys);
    state->prev_keys = (u8)kt;
    trigger = (u8)(kt >> 8);

    if ((trigger & PAD_KEY_UP) != 0) {
        if (state->cursor == 0) state->cursor = (u8)(state->count - 1);
        else state->cursor--;
    }
    if ((trigger & PAD_KEY_DOWN) != 0) {
        state->cursor++;
        if (state->cursor >= state->count) state->cursor = 0;
    }
    if ((trigger & PAD_KEY_A) != 0) {
        state->selected = state->cursor;
    }
    if ((trigger & PAD_KEY_B) != 0) {
        state->cancelled = 1;
        state->selected = 0xFF;
    }
}
menu_was_cancelled

Indique si un menu traité progressivement a été annulé avec B.

Syntaxe

c
u8 menu_was_cancelled(menu_state_t* state);

Paramètres

state

Pointeur vers un état de menu initialisé.

Valeur renvoyée

Renvoie 1 en cas d’annulation, sinon 0, y compris pour un pointeur nul.

Conditions et limites

La lecture n’efface pas le drapeau. Réinitialisez avant réutilisation. Consultez-le avec la sélection : la valeur 255 seule ne distingue pas une attente d’entrée d’une annulation.

Exemple d’utilisation

c
result[1]=menu_was_cancelled(&menu_state);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Une confirmation avec A laisse le drapeau à zéro. Un test d’entrée distinct annule avec B et vérifie qu’il vaut un.

menu_was_cancelled: DMG
DMG
menu_was_cancelled: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_menu_state.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_menu_state.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/rpg.h:281

Notes de déclaration (texte source)
Read the latched cancellation flag; null state returns false.

kitaqgb/lib/menu.c:155

c
u8 menu_was_cancelled(menu_state_t* state)
{
    if (state == 0) return 0;
    return state->cancelled;
}
menu_yesno

Affiche un menu YES/NO à un emplacement fixe et attend une entrée.

Syntaxe

c
u8 menu_yesno();

Valeur renvoyée

Renvoie 0 pour YES, 1 pour NO ou 255 en cas d’annulation avec B.

Conditions et limites

La fenêtre commence à la tuile (6,10) et mesure 8×4 tuiles. La sélection utilise text_choice(). Après le retour, l’appelant exécute l’action de jeu choisie. Chargez au préalable les tuiles de bordure, de curseur et de texte. L’appelant doit conserver le tableau des éléments et leurs chaînes. Le texte n’est ni renvoyé automatiquement à la ligne ni tronqué aux limites de la fenêtre ; choisissez des positions, un nombre d’éléments et des longueurs de libellé qui tiennent dans la fenêtre.

Exemple d’utilisation

c
result[0]=menu_yesno();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

DOWN puis A choisit NO. Le curseur apparaît à gauche de NO et SELECTED affiche 00001.

menu_yesno: DMG
DMG
menu_yesno: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_menu_yesno.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_menu_yesno.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/rpg.h:264

Notes de déclaration (texte source)
Open a two-choice dialog and return the text-choice result (YES first, NO second).

kitaqgb/lib/menu.c:162

c
u8 menu_yesno()
{
    const u8* items[2];

    items[0] = menu_yes;
    items[1] = menu_no;
    text_open(6, 10, 8, 4);
    return text_choice(items, 2);
}
path_find_bfs

Trouve un plus court chemin par déplacements cardinaux et écrit ses directions du départ vers l’arrivée.

Syntaxe

c
u8 path_find_bfs(u8 sx, u8 sy, u8 gx, u8 gy, u8* out_path, u8 max_len);

Paramètres

sx

X de la case de départ, dans les limites.

sy

Y de la case de départ.

gx

X de la case d’arrivée ; une arrivée bloquée distincte de l’origine est refusée.

gy

Y de la case d’arrivée.

out_path

Tableau accessible en écriture d’au moins max_len octets ; 0=haut, 1=droite, 2=bas, 3=gauche.

max_len

Capacité de sortie ; un chemin trop long provoque un échec au lieu d’être tronqué.

Valeur renvoyée

Renvoie la longueur du chemin ; zéro signifie inaccessible, coordonnées invalides, max_len insuffisant ou arrivée déjà atteinte.

Conditions et limites

Les coordonnées désignent les cases de la carte active : 8×8 pixels pour les tuiles ordinaires, 16×16 pour les métatuiles.

La recherche utilise environ 4 Kio d’espace de travail partagé non réentrant. Limitez les cartes à 1024 cases et les distances explorées à 254. La distance 0xFF signifie « non atteint » : un trajet de 255 pas n’est donc pas représentable. Les sorties de coût et de masque nécessitent width*height octets accessibles en écriture.

max_len limite la sortie, pas le rayon de recherche. N’utilisez pas la sortie comme nouvelle route après un échec.

Exemple d’utilisation

c
result[49]=path_find_bfs(0,2,5,2,route,30);x=0;y=2;for(i=0;i<result[49];i++){if(route[i]==0)y--;if(route[i]==1)x++;if(route[i]==2)y++;if(route[i]==3)x--;}result[50]=x;result[51]=y;result[52]=path_find_bfs(0,2,5,2,route,2);result[53]=path_find_bfs(0,2,2,2,route,30);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La grille de gauche montre les coûts de déplacement en trois pas au plus ; celle de droite, un plus court chemin de S à G. Des astérisques verts tracent neuf pas autour d’un mur rouge de trois cases ; les chiffres bleus donnent les coûts. Le DMG utilise la même disposition en noir. Les contrôles RAM montrent aussi que le masque d’attaque ignore les murs.

path_find_bfs: DMG
DMG
path_find_bfs: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_map_path.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_map_path.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:361

Notes de déclaration (texte source)
Find a shortest cardinal path with BFS and write direction codes 0=up,
1=right, 2=down, 3=left. Return its byte length, or zero for failure or an
already-reached goal. The caller supplies max_len output bytes and respects
the shared workspace/distance limits; excessive paths are not truncated.

kitaqgb/lib/slg_path.c:78

c
u8 path_find_bfs(u8 sx, u8 sy, u8 gx, u8 gy, u8* out_path, u8 max_len)
{
    u8 w = map_current_width();
    u8 h = map_current_height();
    u16 total;
    u16 head = 0;
    u16 tail = 0;
    u16 start;
    u16 goal;
    u8 found = 0;

    if (w == 0 || h == 0) return 0;
    if (sx >= w || sy >= h || gx >= w || gy >= h) return 0;
    if ((sx != gx || sy != gy) && map_is_blocked(gx, gy) != 0) return 0;

    total = (u16)((u16)w * (u16)h);
    __memset(path_dist, 0xFF, total);

    start = __map_index(sx, sy, w);
    goal = __map_index(gx, gy, w);

    path_dist[start] = 0;
    path_queue[tail++] = start;

    while (head < tail) {
        u16 cur = path_queue[head++];
        u8 cost = path_dist[cur];
        u8 y = (u8)(cur / w);
        u8 x = (u8)(cur - ((u16)y * (u16)w));

        if (cur == goal) {
            found = 1;
            break;
        }

        if (y > 0) {
            u16 next = (u16)(cur - w);
            if (path_dist[next] == 0xFF && map_is_blocked(x, (u8)(y - 1)) == 0) {
                path_dist[next] = (u8)(cost + 1);
                path_queue[tail++] = next;
            }
        }
        if ((u8)(x + 1) < w) {
            u16 next = (u16)(cur + 1);
            if (path_dist[next] == 0xFF && map_is_blocked((u8)(x + 1), y) == 0) {
                path_dist[next] = (u8)(cost + 1);
                path_queue[tail++] = next;
            }
        }
        if ((u8)(y + 1) < h) {
            u16 next = (u16)(cur + w);
            if (path_dist[next] == 0xFF && map_is_blocked(x, (u8)(y + 1)) == 0) {
                path_dist[next] = (u8)(cost + 1);
                path_queue[tail++] = next;
            }
        }
        if (x > 0) {
            u16 next = (u16)(cur - 1);
            if (path_dist[next] == 0xFF && map_is_blocked((u8)(x - 1), y) == 0) {
                path_dist[next] = (u8)(cost + 1);
                path_queue[tail++] = next;
            }
        }
    }

    // Reject unreachable or oversized paths before reconstructing output.
    if (found == 0) return 0;
    if (path_dist[goal] > max_len) return 0;

    {
        // Walk backward through decreasing costs, recording forward directions in
        // reverse order. The fixed neighbor order makes tied routes deterministic.
        u8 len = 0;
        u16 cur = goal;

        while (cur != start) {
            u8 cur_cost = path_dist[cur];
            u8 y = (u8)(cur / w);
            u8 x = (u8)(cur - ((u16)y * (u16)w));

            if (y > 0 && path_dist[(u16)(cur - w)] == (u8)(cur_cost - 1)) {
                path_rev[len++] = 2;
                cur = (u16)(cur - w);
                continue;
            }
            if ((u8)(x + 1) < w && path_dist[(u16)(cur + 1)] == (u8)(cur_cost - 1)) {
                path_rev[len++] = 3;
                cur = (u16)(cur + 1);
                continue;
            }
            if ((u8)(y + 1) < h && path_dist[(u16)(cur + w)] == (u8)(cur_cost - 1)) {
                path_rev[len++] = 0;
                cur = (u16)(cur + w);
                continue;
            }
            if (x > 0 && path_dist[(u16)(cur - 1)] == (u8)(cur_cost - 1)) {
                path_rev[len++] = 1;
                cur = (u16)(cur - 1);
                continue;
            }
            return 0;
        }

        // Reverse the recovered directions so the first output step starts at the origin.
        while (len != 0) {
            len--;
            out_path[path_dist[goal] - 1 - len] = path_rev[len];
        }

        return path_dist[goal];
    }
}
quest_set_state

Remplace tout l’octet d’état d’une quête. Le jeu définit le sens de chaque valeur : par exemple, 1 pour acceptée et 3 pour terminée. La fonction ne vérifie pas si cette transition est autorisée et ne déclenche ni récompense ni rappel.

Syntaxe

c
void quest_set_state(u8 quest_id, u8 state);

Paramètres

quest_id

Numéro de quête de 0 à 63, passé en u8. Il indexe directement l’un des 64 octets d’état ; c’est un ID défini par le jeu, pas un pointeur ni un nombre de quêtes terminées.

state

Nouvel état u8, de 0 à 255. Les huit bits remplacent la valeur précédente. La bibliothèque n’attribue aucun sens prédéfini aux valeurs et ne réserve ni 0 ni 255.

Valeur renvoyée

Aucune (void).

Conditions et limites

La fonction ne valide pas l’ID. Gardez les ID d’indicateurs inférieurs à 2048 et les ID de quêtes inférieurs à 64 ; un accès hors limites peut lire ou écraser de la RAM sans rapport. Les exemples initialisent explicitement les valeurs au lieu de dépendre du contenu au démarrage.

flags.c possède 256 octets de RAM pour les indicateurs et 64 octets distincts pour les quêtes. Ces fonctions n’accèdent pas à la RAM de sauvegarde de la cartouche et ne conservent pas les données après extinction. Pour préserver la progression, le jeu doit sérialiser les valeurs d’indicateurs et de quêtes via son système de sauvegarde, puis les restaurer au chargement.

Incluez rpg.h et compilez lib/flags.c avec le jeu. Les tableaux sont privés à ce fichier source ; accédez-y par les API d’indicateurs et de quêtes. Tous les appelants partagent ce stockage : coordonnez vous-même les écritures de la boucle principale et des gestionnaires d’interruption.

Exemple d’utilisation

c
quest_set_state(2,1); // In this game, 1 means accepted.
started=quest_state(2);
quest_set_state(2,3); // In this game, 3 means completed; replace the whole byte.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple stocke 1 pour la quête 2, puis le remplace par 3. ACCEPTED montre la première observation, 001, et COMPLETED la nouvelle valeur, 003. LAST QUEST vaut 255 après stockage de 255 dans la quête d’ID 63, dernière entrée valide.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG et bleu sur CGB. FAILED doit valoir 000. Les captures montrent uniquement le comportement des états en RAM ; elles ne démontrent pas la sauvegarde d’une partie.

La vérification sur l’émulateur DMG a couvert tous les ID d’indicateurs de 0 à 2047, les activations et effacements répétés, les entrées voisines et les 256 valeurs d’état de chacune des 64 quêtes. Un motif final de 256 octets d’indicateurs et les 64 octets de quêtes ont été comparés aux données attendues. Les deux écrans pédagogiques ont été vérifiés après 240 images. Le matériel réel et la persistance des sauvegardes n’ont pas été testés.

quest_set_state: DMG
DMG
quest_set_state: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\flags_quests.c .\kitaqgb\lib\flags.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\flags_quests.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:377

Notes de déclaration (texte source)
Replace a quest-state byte without validating its game-specific meaning.
The caller must keep quest_id below 64.

kitaqgb/lib/flags.c:34

c
void quest_set_state(u8 quest_id, u8 state)
{
    quest_states[quest_id] = state;
}
quest_state

Lit l’octet mémorisé pour une quête. Contrairement à un indicateur d’un bit, cet octet peut distinguer plusieurs étapes, comme non commencée, acceptée et terminée. La fonction lit uniquement le stockage ; elle n’exécute aucune logique de quête et ne fait pas avancer l’étape.

Syntaxe

c
u8 quest_state(u8 quest_id);

Paramètres

quest_id

Numéro de quête de 0 à 63, passé en u8. Il indexe directement l’un des 64 octets d’état ; c’est un ID défini par le jeu, pas un pointeur ni un nombre de quêtes terminées.

Valeur renvoyée

Valeur u8 mémorisée, de 0 à 255. C’est un octet d’état complet, pas un booléen normalisé ; comparez-le aux étapes définies par votre jeu.

Conditions et limites

La fonction ne valide pas l’ID. Gardez les ID d’indicateurs inférieurs à 2048 et les ID de quêtes inférieurs à 64 ; un accès hors limites peut lire ou écraser de la RAM sans rapport. Les exemples initialisent explicitement les valeurs au lieu de dépendre du contenu au démarrage.

flags.c possède 256 octets de RAM pour les indicateurs et 64 octets distincts pour les quêtes. Ces fonctions n’accèdent pas à la RAM de sauvegarde de la cartouche et ne conservent pas les données après extinction. Pour préserver la progression, le jeu doit sérialiser les valeurs d’indicateurs et de quêtes via son système de sauvegarde, puis les restaurer au chargement.

Incluez rpg.h et compilez lib/flags.c avec le jeu. Les tableaux sont privés à ce fichier source ; accédez-y par les API d’indicateurs et de quêtes. Tous les appelants partagent ce stockage : coordonnez vous-même les écritures de la boucle principale et des gestionnaires d’interruption.

Exemple d’utilisation

c
finished=quest_state(2); // Read back 3 without advancing any quest logic.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple lit la quête 2 après que le jeu a explicitement changé son état de 1 à 3. ACCEPTED affiche 001 et COMPLETED affiche 003. Les noms et le sens des étapes sont choisis par l’exemple, pas imposés par la bibliothèque.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG et bleu sur CGB. FAILED doit valoir 000. Les captures montrent uniquement le comportement des états en RAM ; elles ne démontrent pas la sauvegarde d’une partie.

La vérification sur l’émulateur DMG a couvert tous les ID d’indicateurs de 0 à 2047, les activations et effacements répétés, les entrées voisines et les 256 valeurs d’état de chacune des 64 quêtes. Un motif final de 256 octets d’indicateurs et les 64 octets de quêtes ont été comparés aux données attendues. Les deux écrans pédagogiques ont été vérifiés après 240 images. Le matériel réel et la persistance des sauvegardes n’ont pas été testés.

quest_state: DMG
DMG
quest_state: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\flags_quests.c .\kitaqgb\lib\flags.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\flags_quests.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:374

Notes de déclaration (texte source)
Read a quest-state byte; quest_id must be below 64.

kitaqgb/lib/flags.c:27

c
u8 quest_state(u8 quest_id)
{
    return quest_states[quest_id];
}
rand_range

Choisit une valeur à partir de zéro et inférieure à max avec rng8() % max. Une borne de 10 donne par exemple un indice de 0 à 9. Une borne nulle renvoie immédiatement zéro sans tirage.

Syntaxe

c
u8 rand_range(u8 max);

Paramètres

max

Borne supérieure exclue en u8 (0–255). Pour max > 0, le résultat est inférieur à max. Ce paramètre ne peut pas représenter 256 ; utilisez rng8 pour obtenir toute la plage d’un octet sans réduction modulo.

Valeur renvoyée

Pour max > 0, un u8 de 0 à max−1 après un tirage. Pour max == 0, zéro sans tirage. Même max == 1 consomme un tirage, bien que le résultat soit toujours nul.

Conditions et limites

La réduction modulo peut favoriser certains résultats lorsque la plage d’entrée n’est pas divisible par la borne. Le générateur sous-jacent n’est pas nécessairement uniforme non plus. Traitez les sélections bornées et les seuils de chance comme des approximations de jeu, pas des probabilités exactes.

Ces appels partagent un état persistant. La reproduction exige la même cible, la même graine et le même ordre d’appels, y compris ceux des autres fonctions auxiliaires. Gardez réglage de graine et tirages dans un même contexte d’exécution ; ces vérifications ne prouvent pas la sûreté d’un accès concurrent depuis une interruption.

GB et FC utilisent des algorithmes différents et ne garantissent pas la même suite avec la même graine. Ce sont des générateurs déterministes pour le jeu, pas des sources d’aléa cryptographique. Les tests vérifient le comportement de l’implémentation, pas sa qualité statistique ni sa période.

Incluez rpg.h et compilez lib/rng.c avec le jeu pour utiliser les fonctions de bibliothèque. Les intrinsèques __rng_seed et __rng8 sont émises par le compilateur ; un programme limité à ces deux fonctions n’a pas besoin d’objet rng.c.

Exemple d’utilisation

c
rng_seed(0x1234);
bounded=rand_range(10); // An index from 0 through 9; this seed yields 2.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple choisit un indice inférieur à 10. RANGE 10 affiche 00002, car le premier octet de la graine 0x1234 vaut 2. ZERO BOUND vaut 00000 et NEXT BYTE reste ensuite à 00002, confirmant que la borne nulle n’a consommé aucun tirage.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG, bleu sur CGB. FAILED doit indiquer 00000. Les images montrent la sortie réelle de cet exemple dans l’émulateur.

La validation a comparé, pour chaque cas, 32 sorties et huit tirages d’octet suivants à un modèle hôte indépendant : 93 cas GB et 18 cas FC, avec graines constantes ou calculées à l’exécution et limites GB de plage, chance et poids. Les écrans pédagogiques ont été contrôlés après 240 images émulées. Le matériel réel et la qualité statistique n’ont pas été testés.

rand_range: DMG
DMG
rand_range: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\rng_choices.c .\kitaqgb\lib\rng.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\rng_choices.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:199

Notes de déclaration (texte source)
Reduce a random byte modulo max; zero returns zero without consuming randomness.
Modulo reduction is biased unless max divides the generator range.

kitaqgb/lib/rng.c:37

c
u8 rand_range(u8 max)
{
    if (max == 0) return 0;
    return (u8)(rng8() % max);
}
range_fill_move

Parcourt les voisins cardinaux à coût unitaire par recherche en largeur pour calculer les coûts de déplacement.

Syntaxe

c
void range_fill_move(u8 sx, u8 sy, u8 move, u8* out_costmap);

Paramètres

sx

X de la case de départ, dans les limites.

sy

Y de la case de départ.

move

Limite de déplacement de 0 à 254 ; zéro atteint seulement l’origine.

out_costmap

Tableau de coûts de width*height octets accessible en écriture : 255 pour non atteint, zéro à l’origine.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Les coordonnées désignent les cases de la carte active : 8×8 pixels pour les tuiles ordinaires, 16×16 pour les métatuiles.

La recherche utilise environ 4 Kio d’espace de travail partagé non réentrant. Limitez les cartes à 1024 cases et les distances explorées à 254. La distance 0xFF signifie « non atteint » : un trajet de 255 pas n’est donc pas représentable. Les sorties de coût et de masque nécessitent width*height octets accessibles en écriture.

Une carte absente ou une origine invalide laisse la sortie inchangée. Les cases de destination bloquées ne sont pas traversées.

Exemple d’utilisation

c
range_fill_move(0,2,3,costs);for(i=0;i<30;i++)result[13+i]=costs[i];

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La grille de gauche montre les coûts de déplacement en trois pas au plus ; celle de droite, un plus court chemin de S à G. Des astérisques verts tracent neuf pas autour d’un mur rouge de trois cases ; les chiffres bleus donnent les coûts. Le DMG utilise la même disposition en noir. Les contrôles RAM montrent aussi que le masque d’attaque ignore les murs.

range_fill_move: DMG
DMG
range_fill_move: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_map_path.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_map_path.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:365

Notes de déclaration (texte source)
Flood cardinal neighbors at unit cost, stopping expansion at the movement
limit and rejecting blocked destinations. Initialize output to 0xFF only
after validating the map and origin; invalid input leaves output unchanged.

kitaqgb/lib/slg_path.c:14

c
void range_fill_move(u8 sx, u8 sy, u8 move, u8* out_costmap)
{
    u8 w = map_current_width();
    u8 h = map_current_height();
    u16 total;
    u16 head = 0;
    u16 tail = 0;
    u16 start;

    if (w == 0 || h == 0) return;
    if (sx >= w || sy >= h) return;

    total = (u16)((u16)w * (u16)h);
    __memset(out_costmap, 0xFF, total);

    start = __map_index(sx, sy, w);
    out_costmap[start] = 0;
    path_queue[tail++] = start;

    while (head < tail) {
        u16 cur = path_queue[head++];
        u8 cost = out_costmap[cur];
        u8 y = (u8)(cur / w);
        u8 x = (u8)(cur - ((u16)y * (u16)w));

        if (cost >= move) continue;

        if (y > 0) {
            u16 next = (u16)(cur - w);
            if (out_costmap[next] == 0xFF && map_is_blocked(x, (u8)(y - 1)) == 0) {
                out_costmap[next] = (u8)(cost + 1);
                path_queue[tail++] = next;
            }
        }
        if ((u8)(x + 1) < w) {
            u16 next = (u16)(cur + 1);
            if (out_costmap[next] == 0xFF && map_is_blocked((u8)(x + 1), y) == 0) {
                out_costmap[next] = (u8)(cost + 1);
                path_queue[tail++] = next;
            }
        }
        if ((u8)(y + 1) < h) {
            u16 next = (u16)(cur + w);
            if (out_costmap[next] == 0xFF && map_is_blocked(x, (u8)(y + 1)) == 0) {
                out_costmap[next] = (u8)(cost + 1);
                path_queue[tail++] = next;
            }
        }
        if (x > 0) {
            u16 next = (u16)(cur - 1);
            if (out_costmap[next] == 0xFF && map_is_blocked((u8)(x - 1), y) == 0) {
                out_costmap[next] = (u8)(cost + 1);
                path_queue[tail++] = next;
            }
        }
    }
}
rle_decode

Décompresse un flux d’octets RLE dans la RAM ordinaire inscriptible. Chaque paire count/value répète un octet count fois ; un compte nul termine le flux. Utilisez cette variante lorsque les données encodées sont accessibles par un pointeur ordinaire et que vous souhaitez examiner ou modifier les octets décompressés avant leur transfert.

Syntaxe

c
u16 rle_decode(void* dst, const void* src);

Paramètres

dst

Pointeur vers une RAM inscriptible assez grande pour tout le flux décompressé. Aucune capacité n’est passée à la fonction. Séparez la sortie de la source encodée pour éviter d’écraser des paires pas encore lues.

src

Pointeur lisible vers des paires d’octets count/value terminées par un compte nul. Une répétition normale utilise un compte de 1 à 255 ; la valeur peut être n’importe quel octet, zéro compris. Le zéro terminal n’est suivi d’aucun octet de valeur. Le pointeur doit rester lisible dans le mappage courant pendant tout l’appel.

Valeur renvoyée

Nombre d’octets écrits en u16. Un compte nul immédiat ne produit aucun octet et renvoie 0. Le terminateur n’est pas copié. La longueur décompressée doit tenir dans u16 ; le retour n’a pas de code d’erreur distinct et ne représente pas un nombre de tuiles.

Conditions et limites

Le codage porte sur des octets, pas sur du texte. Par exemple, {3, 0x12, 2, 0xA5, 0} donne cinq octets : 12 12 12 A5 A5. Cette liste de sortie est en hexadécimal. Une valeur nulle dans une paire à compte non nul est une donnée ordinaire, pas un marqueur de fin.

Aucun argument ne décrit la taille encodée, la capacité de sortie ou les données mal formées. Validez les ressources à leur création ou chargement, fournissez le zéro terminal et calculez la taille décompressée avant le décodage. Un flux invalide ou non terminé peut lire au-delà de la source et écrire au-delà de la destination.

Les décodeurs RAM utilisent des écritures ordinaires sans synchronisation avec les périodes d’accès du LCD. Gardez leurs destinations en RAM. Pour afficher le résultat, transférez-le séparément avec une API de copie VRAM adaptée, comme le fait l’exemple lorsque le LCD est arrêté.

Pendant une lecture avec banque, ne laissez pas une interruption changer le mappage ROM ni réutiliser la routine de copie distante : ces fonctions partagent leur suivi de banque. Placez le décodeur à pointeur ordinaire et sa source dans des mappages compatibles ; le passage à la banque de la fonction ne doit pas masquer le pointeur source ordinaire.

rle_decode et rle_decode_far sont déclarées dans rpg.h et implémentées dans lib/rle.c. Compilez cette implémentation une seule fois avec le jeu. L’exemple complet inclut rle.c après #pragma bank 0 pour garder appelant et décodeurs dans la banque commune ; ne passez pas aussi rle.c comme entrée séparée pour cet exemple. L’intrinsèque __rle_decode_vram ne nécessite aucun fichier d’implémentation de bibliothèque.

Exemple d’utilisation

c
near_count=rle_decode(near_buffer+1,local_rle); // 48 bytes in writable RAM.
__vram_copy(0x8800,near_buffer+1,near_count); // Upload those bytes while the LCD is off.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple décompresse neuf octets encodés dans un tampon RAM entouré de zones de garde, puis copie les 48 octets obtenus à l’adresse de tuiles 0x8800. RLE TO RAM affiche 048. La rangée supérieure, rouge sur CGB, présente les trois tuiles décodées par cette voie à pointeur ordinaire.

Chaque rangée contient de gauche à droite un carré plein de 8×8, un contour de 8×8 épais d’un pixel et un rectangle plein de 4×8 occupant la moitié gauche d’une tuile de 8×8. Ils sont aux colonnes de tuiles 2, 5 et 8 (x = 16, 40 et 64 pixels). Les rangées commencent à y = 32, 72 et 112 pixels. Les formes sont noires sur DMG ; les rangées CGB sont rouges, vertes et bleues. FAILED doit afficher 000. Les nombres comptent des octets : trois tuiles GB de 16 octets nécessitent 48 octets décompressés.

La matrice de validation couvre 42 cas : flux vide, répétition d’un octet, données nulles, répétition de 255 octets, sortie de 510 octets franchissant une page et données encodées franchissant une page source. Elle compare les 528 octets observés de destination et de garde, la longueur produite et le mappage ROM restauré. Les cas VRAM directe incluent LCD allumé/éteint sur DMG et CGB, ainsi que VBK 1 sur CGB. Les deux écrans pédagogiques sont contrôlés après 240 images émulées. Les ressources invalides, l’utilisation concurrente par interruption et le matériel réel ne sont pas couverts.

rle_decode: DMG
DMG
rle_decode: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\rle_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\rle_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:382

Notes de déclaration (texte source)
Expand count/value byte pairs until a zero count terminates the stream.
The caller must provide a valid terminator and sufficient destination storage;
there are no source or destination bounds parameters. Return the 16-bit byte count.

kitaqgb/lib/rle.c:8

c
u16 rle_decode(void* dst, const void* src)
{
    const u8* in = (const u8*)src;
    u8* out = (u8*)dst;
    u16 total = 0;

    while (1) {
        u8 count = *in++;
        u8 value;
        if (count == 0) break;
        value = *in++;
        while (count != 0) {
            *out++ = value;
            total++;
            count--;
        }
    }

    return total;
}
rle_decode_far

Décompresse le même format count/value en RAM en lisant chaque octet encodé avec __farpeek8 dans la banque ROM fournie. Utilisez cette variante pour les ressources compressées d’une banque ROM commutable. La destination reste un pointeur RAM ordinaire ; l’argument de banque décrit la source.

Syntaxe

c
u16 rle_decode_far(void* dst, u8 bank, const void* src);

Paramètres

dst

Pointeur vers une RAM inscriptible assez grande pour tout le flux décompressé. Aucune capacité n’est passée à la fonction. Séparez la sortie de la source encodée pour éviter d’écraser des paires pas encore lues.

bank

Numéro de banque ROM source en u8. Banque et adresse CPU doivent correspondre au mapper de la cartouche et à l’emplacement de la ressource. La sélection de banque est restaurée après chaque lecture d’octet encodé. Ce n’est pas un sélecteur de banque VRAM de destination, et il ne peut pas représenter un numéro MBC5 sur neuf bits.

src

Pointeur CPU vers le flux encodé dans la banque fournie. L’adresse avance, mais le numéro de banque reste fixe. Gardez tout le flux, zéro terminal compris, dans un mappage lisible ; franchir 0x7FFF ne poursuit pas automatiquement dans la banque ROM suivante.

Valeur renvoyée

Nombre d’octets écrits en u16. Un compte nul immédiat ne produit aucun octet et renvoie 0. Le terminateur n’est pas copié. La longueur décompressée doit tenir dans u16 ; le retour n’a pas de code d’erreur distinct et ne représente pas un nombre de tuiles.

Conditions et limites

Le codage porte sur des octets, pas sur du texte. Par exemple, {3, 0x12, 2, 0xA5, 0} donne cinq octets : 12 12 12 A5 A5. Cette liste de sortie est en hexadécimal. Une valeur nulle dans une paire à compte non nul est une donnée ordinaire, pas un marqueur de fin.

Aucun argument ne décrit la taille encodée, la capacité de sortie ou les données mal formées. Validez les ressources à leur création ou chargement, fournissez le zéro terminal et calculez la taille décompressée avant le décodage. Un flux invalide ou non terminé peut lire au-delà de la source et écrire au-delà de la destination.

Les décodeurs RAM utilisent des écritures ordinaires sans synchronisation avec les périodes d’accès du LCD. Gardez leurs destinations en RAM. Pour afficher le résultat, transférez-le séparément avec une API de copie VRAM adaptée, comme le fait l’exemple lorsque le LCD est arrêté.

Pendant une lecture avec banque, ne laissez pas une interruption changer le mappage ROM ni réutiliser la routine de copie distante : ces fonctions partagent leur suivi de banque. Placez le décodeur à pointeur ordinaire et sa source dans des mappages compatibles ; le passage à la banque de la fonction ne doit pas masquer le pointeur source ordinaire.

rle_decode et rle_decode_far sont déclarées dans rpg.h et implémentées dans lib/rle.c. Compilez cette implémentation une seule fois avec le jeu. L’exemple complet inclut rle.c après #pragma bank 0 pour garder appelant et décodeurs dans la banque commune ; ne passez pas aussi rle.c comme entrée séparée pour cet exemple. L’intrinsèque __rle_decode_vram ne nécessite aucun fichier d’implémentation de bibliothèque.

Exemple d’utilisation

c
far_count=rle_decode_far(far_buffer+1,2,banked_rle); // Read encoded pairs from ROM bank 2.
if(*rle_bank_marker!=0xA1)failures++; // ROM bank 1 must be visible again.
__vram_copy(0x8830,far_buffer+1,far_count);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple lit le flux encodé dans la banque ROM 2, décompresse 48 octets en RAM et les transfère à 0x8830. BANKED RAM affiche 048. La rangée centrale est verte sur CGB. Un marqueur de la banque ROM 1 est aussi vérifié pour confirmer la restauration du mappage de l’appelant.

Chaque rangée contient de gauche à droite un carré plein de 8×8, un contour de 8×8 épais d’un pixel et un rectangle plein de 4×8 occupant la moitié gauche d’une tuile de 8×8. Ils sont aux colonnes de tuiles 2, 5 et 8 (x = 16, 40 et 64 pixels). Les rangées commencent à y = 32, 72 et 112 pixels. Les formes sont noires sur DMG ; les rangées CGB sont rouges, vertes et bleues. FAILED doit afficher 000. Les nombres comptent des octets : trois tuiles GB de 16 octets nécessitent 48 octets décompressés.

La matrice de validation couvre 42 cas : flux vide, répétition d’un octet, données nulles, répétition de 255 octets, sortie de 510 octets franchissant une page et données encodées franchissant une page source. Elle compare les 528 octets observés de destination et de garde, la longueur produite et le mappage ROM restauré. Les cas VRAM directe incluent LCD allumé/éteint sur DMG et CGB, ainsi que VBK 1 sur CGB. Les deux écrans pédagogiques sont contrôlés après 240 images émulées. Les ressources invalides, l’utilisation concurrente par interruption et le matériel réel ne sont pas couverts.

rle_decode_far: DMG
DMG
rle_decode_far: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\rle_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\rle_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:386

Notes de déclaration (texte source)
Decode the same count/value format using bank-qualified reads for every source
byte. Keep the encoded stream within the supplied bank/address mapping and
provide enough destination space; a zero count ends the stream.

kitaqgb/lib/rle.c:34

c
u16 rle_decode_far(void* dst, u8 bank, const void* src)
{
    const u8* p = (const u8*)src;
    u8* out = (u8*)dst;
    u16 total = 0;

    while (1) {
        u8 count = __farpeek8(bank, p);
        u8 value;
        p++;
        if (count == 0) break;
        value = __farpeek8(bank, p);
        p++;
        while (count != 0) {
            *out++ = value;
            total++;
            count--;
        }
    }

    return total;
}
rng16

Construit une valeur non signée de 16 bits avec deux tirages rng8 successifs. Le premier octet occupe les bits 15–8, le second les bits 7–0. À utiliser lorsque la plage souhaitée dépasse un octet.

Syntaxe

c
u16 rng16();

Valeur renvoyée

Un résultat u16 (0–65535), formé par (first_byte << 8) | second_byte. Exactement deux tirages d’octet sont consommés ; cela n’établit pas une distribution uniforme des 65536 valeurs.

Conditions et limites

Ces appels partagent un état persistant. La reproduction exige la même cible, la même graine et le même ordre d’appels, y compris ceux des autres fonctions auxiliaires. Gardez réglage de graine et tirages dans un même contexte d’exécution ; ces vérifications ne prouvent pas la sûreté d’un accès concurrent depuis une interruption.

GB et FC utilisent des algorithmes différents et ne garantissent pas la même suite avec la même graine. Ce sont des générateurs déterministes pour le jeu, pas des sources d’aléa cryptographique. Les tests vérifient le comportement de l’implémentation, pas sa qualité statistique ni sa période.

Incluez rpg.h et compilez lib/rng.c avec le jeu pour utiliser les fonctions de bibliothèque. Les intrinsèques __rng_seed et __rng8 sont émises par le compilateur ; un programme limité à ces deux fonctions n’a pas besoin d’objet rng.c.

Exemple d’utilisation

c
rng_seed(0x1234);
word=rng16(); // First draw 2 is high, second draw 34 is low: 0x0222 = 546.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple montre l’assemblage d’un mot. Après réinitialisation à 0x1234, les octets 2 et 34 forment 0x0222 ; RNG16 affiche donc 00546. FIRST et SECOND montrent séparément les octets correspondants.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG, bleu sur CGB. FAILED doit indiquer 00000. Les images montrent la sortie réelle de cet exemple dans l’émulateur.

La validation a comparé, pour chaque cas, 32 sorties et huit tirages d’octet suivants à un modèle hôte indépendant : 93 cas GB et 18 cas FC, avec graines constantes ou calculées à l’exécution et limites GB de plage, chance et poids. Les écrans pédagogiques ont été contrôlés après 240 images émulées. Le matériel réel et la qualité statistique n’ont pas été testés.

rng16: DMG
DMG
rng16: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\rng_values.c .\kitaqgb\lib\rng.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\rng_values.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:196

Notes de déclaration (texte source)
Consume two generator bytes in high-byte/low-byte order to form a 16-bit value.

kitaqgb/lib/rng.c:22

c
u16 rng16()
{
    u16 hi = (u16)rng8();
    u16 lo = (u16)rng8();
    return (u16)((hi << 8) | lo);
}
rng8

Obtient un octet pseudo-aléatoire via la bibliothèque GB. rng8 appelle __rng8 exactement une fois ; c’est le tirage de base utilisé par les autres fonctions de rng.c.

Syntaxe

c
u8 rng8();

Valeur renvoyée

Un résultat u8 (0–255), après un avancement du générateur partagé. Cela décrit le type et les bornes, pas une équiprobabilité de chaque octet.

Conditions et limites

Ces appels partagent un état persistant. La reproduction exige la même cible, la même graine et le même ordre d’appels, y compris ceux des autres fonctions auxiliaires. Gardez réglage de graine et tirages dans un même contexte d’exécution ; ces vérifications ne prouvent pas la sûreté d’un accès concurrent depuis une interruption.

GB et FC utilisent des algorithmes différents et ne garantissent pas la même suite avec la même graine. Ce sont des générateurs déterministes pour le jeu, pas des sources d’aléa cryptographique. Les tests vérifient le comportement de l’implémentation, pas sa qualité statistique ni sa période.

Incluez rpg.h et compilez lib/rng.c avec le jeu pour utiliser les fonctions de bibliothèque. Les intrinsèques __rng_seed et __rng8 sont émises par le compilateur ; un programme limité à ces deux fonctions n’a pas besoin d’objet rng.c.

Exemple d’utilisation

c
rng_seed(0x1234); // Reset the same generator used by the intrinsics.
wrapped=rng8(); // One byte draw: 2 after the preceding seed.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple compare le tirage d’octet de bibliothèque à l’intrinsèque. Après rng_seed(0x1234), RNG8 affiche 00002 comme FIRST. Fixer la graine ne consomme pas le premier tirage.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG, bleu sur CGB. FAILED doit indiquer 00000. Les images montrent la sortie réelle de cet exemple dans l’émulateur.

La validation a comparé, pour chaque cas, 32 sorties et huit tirages d’octet suivants à un modèle hôte indépendant : 93 cas GB et 18 cas FC, avec graines constantes ou calculées à l’exécution et limites GB de plage, chance et poids. Les écrans pédagogiques ont été contrôlés après 240 images émulées. Le matériel réel et la qualité statistique n’ont pas été testés.

rng8: DMG
DMG
rng8: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\rng_values.c .\kitaqgb\lib\rng.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\rng_values.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:194

Notes de déclaration (texte source)
Advance the compiler-provided pseudorandom generator and return one byte.

kitaqgb/lib/rng.c:4

c
u8 rng8()
{
    return __rng8();
}
rng_chance

Fait un choix oui/non avec rng_range(100) < percent. Utile pour des chances de jeu approximatives, par exemple décider si un ennemi laisse tomber un objet. Zéro renvoie toujours faux ; 100 ou plus renvoie toujours vrai. Aucun de ces cas limites ne consomme de tirage.

Syntaxe

c
u8 rng_chance(u8 percent);

Paramètres

percent

Chance demandée en u8. Les valeurs 1–99 utilisent un octet réduit modulo ; 0 renvoie faux et 100–255 renvoient vrai. Les valeurs intermédiaires sont des seuils approximatifs, pas une garantie de pourcentages exacts.

Valeur renvoyée

Booléen normalisé : 0 pour faux, 1 pour vrai. Un seuil de 1 à 99 consomme un tirage d’octet.

Conditions et limites

La réduction modulo peut favoriser certains résultats lorsque la plage d’entrée n’est pas divisible par la borne. Le générateur sous-jacent n’est pas nécessairement uniforme non plus. Traitez les sélections bornées et les seuils de chance comme des approximations de jeu, pas des probabilités exactes.

Ces appels partagent un état persistant. La reproduction exige la même cible, la même graine et le même ordre d’appels, y compris ceux des autres fonctions auxiliaires. Gardez réglage de graine et tirages dans un même contexte d’exécution ; ces vérifications ne prouvent pas la sûreté d’un accès concurrent depuis une interruption.

GB et FC utilisent des algorithmes différents et ne garantissent pas la même suite avec la même graine. Ce sont des générateurs déterministes pour le jeu, pas des sources d’aléa cryptographique. Les tests vérifient le comportement de l’implémentation, pas sa qualité statistique ni sa période.

Incluez rpg.h et compilez lib/rng.c avec le jeu pour utiliser les fonctions de bibliothèque. Les intrinsèques __rng_seed et __rng8 sont émises par le compilateur ; un programme limité à ces deux fonctions n’a pas besoin d’objet rng.c.

Exemple d’utilisation

c
rng_seed(0x1234);
chance=rng_chance(50); // Here 2 % 100 < 50, so the result is 1 (true).

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple effectue une décision approximative à 50 %. L’octet issu de la graine vaut 2, et 2 % 100 < 50 est vrai ; CHANCE 50 affiche donc 00001. Un seul succès ne démontre pas un taux de réussite de 50 % à long terme.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG, bleu sur CGB. FAILED doit indiquer 00000. Les images montrent la sortie réelle de cet exemple dans l’émulateur.

La validation a comparé, pour chaque cas, 32 sorties et huit tirages d’octet suivants à un modèle hôte indépendant : 93 cas GB et 18 cas FC, avec graines constantes ou calculées à l’exécution et limites GB de plage, chance et poids. Les écrans pédagogiques ont été contrôlés après 240 images émulées. Le matériel réel et la qualité statistique n’ont pas été testés.

rng_chance: DMG
DMG
rng_chance: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\rng_choices.c .\kitaqgb\lib\rng.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\rng_choices.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:214

Notes de déclaration (texte source)
Return false for zero and true for values at least 100. Intermediate values
use the modulo-based range generator, so percentages are approximate.

kitaqgb/lib/rng.c:51

c
u8 rng_chance(u8 percent)
{
    if (percent == 0) return 0;
    if (percent >= 100) return 1;
    return (u8)(rng_range(100) < percent);
}
rng_next16

Renvoie le même mot obtenu par deux tirages que rng16. Cet alias de bibliothèque place le premier tirage dans l’octet haut et le second dans l’octet bas ; il ne saute aucune valeur supplémentaire avant de tirer.

Syntaxe

c
u16 rng_next16();

Valeur renvoyée

Un résultat u16 (0–65535), formé par (first_byte << 8) | second_byte. Exactement deux tirages d’octet sont consommés ; cela n’établit pas une distribution uniforme des 65536 valeurs.

Conditions et limites

Ces appels partagent un état persistant. La reproduction exige la même cible, la même graine et le même ordre d’appels, y compris ceux des autres fonctions auxiliaires. Gardez réglage de graine et tirages dans un même contexte d’exécution ; ces vérifications ne prouvent pas la sûreté d’un accès concurrent depuis une interruption.

GB et FC utilisent des algorithmes différents et ne garantissent pas la même suite avec la même graine. Ce sont des générateurs déterministes pour le jeu, pas des sources d’aléa cryptographique. Les tests vérifient le comportement de l’implémentation, pas sa qualité statistique ni sa période.

Incluez rpg.h et compilez lib/rng.c avec le jeu pour utiliser les fonctions de bibliothèque. Les intrinsèques __rng_seed et __rng8 sont émises par le compilateur ; un programme limité à ces deux fonctions n’a pas besoin d’objet rng.c.

Exemple d’utilisation

c
rng_seed(0x1234);
nextword=rng_next16(); // The same two-draw word: 546.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple compare l’alias de mot à rng16 après des graines identiques. NEXT16 et RNG16 affichent 00546, soit deux tirages d’octet dans l’ordre haut/bas.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG, bleu sur CGB. FAILED doit indiquer 00000. Les images montrent la sortie réelle de cet exemple dans l’émulateur.

La validation a comparé, pour chaque cas, 32 sorties et huit tirages d’octet suivants à un modèle hôte indépendant : 93 cas GB et 18 cas FC, avec graines constantes ou calculées à l’exécution et limites GB de plage, chance et poids. Les écrans pédagogiques ont été contrôlés après 240 images émulées. Le matériel réel et la qualité statistique n’ont pas été testés.

rng_next16: DMG
DMG
rng_next16: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\rng_values.c .\kitaqgb\lib\rng.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\rng_values.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:209

Notes de déclaration (texte source)
Alias the two-step 16-bit generator.

kitaqgb/lib/rng.c:30

c
u16 rng_next16()
{
    return rng16();
}
rng_next8

Tire l’octet suivant avec la même opération que rng8. Le nom souligne l’avancement de la suite ; appeler successivement les deux noms consomme deux tirages consécutifs du même générateur partagé.

Syntaxe

c
u8 rng_next8();

Valeur renvoyée

Un résultat u8 (0–255), après un avancement du générateur partagé. Cela décrit le type et les bornes, pas une équiprobabilité de chaque octet.

Conditions et limites

Ces appels partagent un état persistant. La reproduction exige la même cible, la même graine et le même ordre d’appels, y compris ceux des autres fonctions auxiliaires. Gardez réglage de graine et tirages dans un même contexte d’exécution ; ces vérifications ne prouvent pas la sûreté d’un accès concurrent depuis une interruption.

GB et FC utilisent des algorithmes différents et ne garantissent pas la même suite avec la même graine. Ce sont des générateurs déterministes pour le jeu, pas des sources d’aléa cryptographique. Les tests vérifient le comportement de l’implémentation, pas sa qualité statistique ni sa période.

Incluez rpg.h et compilez lib/rng.c avec le jeu pour utiliser les fonctions de bibliothèque. Les intrinsèques __rng_seed et __rng8 sont émises par le compilateur ; un programme limité à ces deux fonctions n’a pas besoin d’objet rng.c.

Exemple d’utilisation

c
rng_seed(0x1234);
nextbyte=rng_next8(); // One draw, just like rng8(): 2.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple vérifie l’alias d’octet après la même graine. NEXT8 et RNG8 affichent tous deux 00002, car le programme réinitialise la graine avant chaque comparaison ; sans ces remises à zéro, ils consommeraient des valeurs successives.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG, bleu sur CGB. FAILED doit indiquer 00000. Les images montrent la sortie réelle de cet exemple dans l’émulateur.

La validation a comparé, pour chaque cas, 32 sorties et huit tirages d’octet suivants à un modèle hôte indépendant : 93 cas GB et 18 cas FC, avec graines constantes ou calculées à l’exécution et limites GB de plage, chance et poids. Les écrans pédagogiques ont été contrôlés après 240 images émulées. Le matériel réel et la qualité statistique n’ont pas été testés.

rng_next8: DMG
DMG
rng_next8: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\rng_values.c .\kitaqgb\lib\rng.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\rng_values.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:207

Notes de déclaration (texte source)
Alias the byte generator; this consumes one generator step.

kitaqgb/lib/rng.c:16

c
u8 rng_next8()
{
    return rng8();
}
rng_range

Appelle rand_range avec la même borne supérieure exclue. Ce nom regroupe la sélection bornée avec les autres fonctions rng_. Il utilise le même tirage d’octet et le même modulo, y compris le résultat sans tirage pour une borne nulle.

Syntaxe

c
u8 rng_range(u8 max);

Paramètres

max

Borne supérieure exclue en u8 (0–255). Pour max > 0, le résultat est inférieur à max. Ce paramètre ne peut pas représenter 256 ; utilisez rng8 pour obtenir toute la plage d’un octet sans réduction modulo.

Valeur renvoyée

Pour max > 0, un u8 de 0 à max−1 après un tirage. Pour max == 0, zéro sans tirage. Même max == 1 consomme un tirage, bien que le résultat soit toujours nul.

Conditions et limites

La réduction modulo peut favoriser certains résultats lorsque la plage d’entrée n’est pas divisible par la borne. Le générateur sous-jacent n’est pas nécessairement uniforme non plus. Traitez les sélections bornées et les seuils de chance comme des approximations de jeu, pas des probabilités exactes.

Ces appels partagent un état persistant. La reproduction exige la même cible, la même graine et le même ordre d’appels, y compris ceux des autres fonctions auxiliaires. Gardez réglage de graine et tirages dans un même contexte d’exécution ; ces vérifications ne prouvent pas la sûreté d’un accès concurrent depuis une interruption.

GB et FC utilisent des algorithmes différents et ne garantissent pas la même suite avec la même graine. Ce sont des générateurs déterministes pour le jeu, pas des sources d’aléa cryptographique. Les tests vérifient le comportement de l’implémentation, pas sa qualité statistique ni sa période.

Incluez rpg.h et compilez lib/rng.c avec le jeu pour utiliser les fonctions de bibliothèque. Les intrinsèques __rng_seed et __rng8 sont émises par le compilateur ; un programme limité à ces deux fonctions n’a pas besoin d’objet rng.c.

Exemple d’utilisation

c
rng_seed(0x1234);
alias=rng_range(10); // The same exclusive upper bound and result, 2.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple compare les deux noms de sélection bornée. Réinitialiser la graine avant chaque appel donne ALIAS 10 et RANGE 10 à 00002. La borne 10 elle-même est exclue.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG, bleu sur CGB. FAILED doit indiquer 00000. Les images montrent la sortie réelle de cet exemple dans l’émulateur.

La validation a comparé, pour chaque cas, 32 sorties et huit tirages d’octet suivants à un modèle hôte indépendant : 93 cas GB et 18 cas FC, avec graines constantes ou calculées à l’exécution et limites GB de plage, chance et poids. Les écrans pédagogiques ont été contrôlés après 240 images émulées. Le matériel réel et la qualité statistique n’ont pas été testés.

rng_range: DMG
DMG
rng_range: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\rng_choices.c .\kitaqgb\lib\rng.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\rng_choices.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:211

Notes de déclaration (texte source)
Alias rand_range and return a value in [0,max), or zero when max is zero.

kitaqgb/lib/rng.c:44

c
u8 rng_range(u8 max)
{
    return rand_range(max);
}
rng_seed

Fixe la graine via l’interface de bibliothèque GB. C’est un enrobage de __rng_seed : il réinitialise le même état partagé que rng8, rng16 et les fonctions de sélection, sans créer de générateur distinct.

Syntaxe

c
void rng_seed(u16 seed);

Paramètres

seed

Graine non signée de 16 bits, de 0 à 65535. Les deux octets sont stockés tels quels. Choisissez et notez la graine avant la suite de tirages de jeu à reproduire.

Valeur renvoyée

Aucune (void).

Conditions et limites

L’état zéro est accepté. Au prochain tirage d’octet, le générateur GB le remplace par 0x5AA5 avant d’avancer ; __rng_seed(0) suivi de __rng8() renvoie donc 122. Réinitialiser sans cesse la graine redémarre la suite au lieu d’ajouter du hasard.

Ces appels partagent un état persistant. La reproduction exige la même cible, la même graine et le même ordre d’appels, y compris ceux des autres fonctions auxiliaires. Gardez réglage de graine et tirages dans un même contexte d’exécution ; ces vérifications ne prouvent pas la sûreté d’un accès concurrent depuis une interruption.

GB et FC utilisent des algorithmes différents et ne garantissent pas la même suite avec la même graine. Ce sont des générateurs déterministes pour le jeu, pas des sources d’aléa cryptographique. Les tests vérifient le comportement de l’implémentation, pas sa qualité statistique ni sa période.

Incluez rpg.h et compilez lib/rng.c avec le jeu pour utiliser les fonctions de bibliothèque. Les intrinsèques __rng_seed et __rng8 sont émises par le compilateur ; un programme limité à ces deux fonctions n’a pas besoin d’objet rng.c.

Exemple d’utilisation

c
rng_seed(0x1234); // Reset the same generator used by the intrinsics.
wrapped=rng8(); // One byte draw: 2 after the preceding seed.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple compare le tirage d’octet de bibliothèque à l’intrinsèque. Après rng_seed(0x1234), RNG8 affiche 00002 comme FIRST. Fixer la graine ne consomme pas le premier tirage.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG, bleu sur CGB. FAILED doit indiquer 00000. Les images montrent la sortie réelle de cet exemple dans l’émulateur.

La validation a comparé, pour chaque cas, 32 sorties et huit tirages d’octet suivants à un modèle hôte indépendant : 93 cas GB et 18 cas FC, avec graines constantes ou calculées à l’exécution et limites GB de plage, chance et poids. Les écrans pédagogiques ont été contrôlés après 240 images émulées. Le matériel réel et la qualité statistique n’ont pas été testés.

rng_seed: DMG
DMG
rng_seed: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\rng_values.c .\kitaqgb\lib\rng.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\rng_values.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:205

Notes de déclaration (texte source)
Replace the generator seed so subsequent calls can reproduce a sequence.

kitaqgb/lib/rng.c:10

c
void rng_seed(u16 seed)
{
    __rng_seed(seed);
}
save_check

Effectue le même contrôle d’intégrité que save_exists sans extraire les données.

Syntaxe

c
u8 save_check(u8 slot);

Paramètres

slot

Numéro d’emplacement de 0 à 3.

Valeur renvoyée

Renvoie 1 si valide, sinon 0. Une sauvegarde de longueur nulle peut être valide.

Conditions et limites

Par défaut, quatre emplacements de 512 octets contiennent chacun un en-tête de six octets et jusqu’à 506 octets de données. L’exemple utilise MBC5 avec 8 Kio de SRAM. Les appels se terminent avec la RAM désactivée, sans restaurer sa banque ni son état d’activation précédent.

Exemple d’utilisation

c
result[4]=save_check(0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Sauvegardez trois octets, 7/42/255, puis testez une longueur différente, un emplacement invalide et une somme de contrôle endommagée. Un chargement réussi donne 42 au milieu ; une lecture échouée préserve la destination à 77 ; la validation après effacement renvoie 0.

save_check: DMG
DMG
save_check: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_save.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_save.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=8k
Implémentation et source

kitaqgb/lib/rpg.h:341

Notes de déclaration (texte source)
Alias save_exists, including its header and checksum validation.

kitaqgb/lib/save.c:175

c
u8 save_check(u8 slot)
{
    return save_exists(slot);
}
save_clear

Met à zéro les 512 octets d’un emplacement pour invalider sa sauvegarde.

Syntaxe

c
void save_clear(u8 slot);

Paramètres

slot

Numéro d’emplacement de 0 à 3.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Par défaut, quatre emplacements de 512 octets contiennent chacun un en-tête de six octets et jusqu’à 506 octets de données. L’exemple utilise MBC5 avec 8 Kio de SRAM. Les appels se terminent avec la RAM désactivée, sans restaurer sa banque ni son état d’activation précédent.

Ignore les emplacements hors de 0..3 et laisse les autres inchangés.

Exemple d’utilisation

c
save_clear(0);result[16]=save_check(0);result[17]=save_write(3,payload,0);result[18]=save_exists(3);save_clear(3);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Sauvegardez trois octets, 7/42/255, puis testez une longueur différente, un emplacement invalide et une somme de contrôle endommagée. Un chargement réussi donne 42 au milieu ; une lecture échouée préserve la destination à 77 ; la validation après effacement renvoie 0.

save_clear: DMG
DMG
save_clear: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_save.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_save.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=8k
Implémentation et source

kitaqgb/lib/rpg.h:344

Notes de déclaration (texte source)
Zero the complete selected slot, including header and payload; invalid slot
IDs are ignored. Cartridge RAM is disabled when clearing finishes.

kitaqgb/lib/save.c:225

c
void save_clear(u8 slot)
{
    u16 base;
    u16 i;

    if (slot >= SAVE_SLOT_COUNT) return;

    base = save_slot_base(slot);
    save_enable();

    i = 0;
    while (i < SAVE_SLOT_SIZE) {
        save_write_abs((u16)(base + i), 0);
        i++;
    }

    save_disable();
}
save_exists

Valide l’en-tête, la longueur et la somme de contrôle d’un emplacement pour vérifier la présence d’une sauvegarde utilisable.

Syntaxe

c
u8 save_exists(u8 slot);

Paramètres

slot

Numéro d’emplacement de 0 à 3.

Valeur renvoyée

Renvoie 1 si valide, sinon 0. Une sauvegarde de longueur nulle peut être valide.

Conditions et limites

Par défaut, quatre emplacements de 512 octets contiennent chacun un en-tête de six octets et jusqu’à 506 octets de données. L’exemple utilise MBC5 avec 8 Kio de SRAM. Les appels se terminent avec la RAM désactivée, sans restaurer sa banque ni son état d’activation précédent.

Exemple d’utilisation

c
result[0]=save_exists(0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Sauvegardez trois octets, 7/42/255, puis testez une longueur différente, un emplacement invalide et une somme de contrôle endommagée. Un chargement réussi donne 42 au milieu ; une lecture échouée préserve la destination à 77 ; la validation après effacement renvoie 0.

save_exists: DMG
DMG
save_exists: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_save.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_save.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=8k
Implémentation et source

kitaqgb/lib/rpg.h:334

Notes de déclaration (texte source)
Validate a slot's header, payload bounds and checksum without copying the
payload out. A nonzero result means the stored record passes these checks.

kitaqgb/lib/save.c:182

c
u8 save_exists(u8 slot)
{
    u16 base;
    u16 stored_len;
    u8 stored_sum;

    if (slot >= SAVE_SLOT_COUNT) return 0;

    base = save_slot_base(slot);
    save_enable();

    if (save_read_abs(base + 0) != SAVE_MAGIC0) {
        save_disable();
        return 0;
    }
    if (save_read_abs(base + 1) != SAVE_MAGIC1) {
        save_disable();
        return 0;
    }
    if (save_read_abs(base + 2) != SAVE_VERSION) {
        save_disable();
        return 0;
    }

    stored_len = (u16)save_read_abs(base + 3);
    stored_len |= (u16)((u16)save_read_abs(base + 4) << 8);
    stored_sum = save_read_abs(base + 5);

    if (stored_len > (u16)(SAVE_SLOT_SIZE - SAVE_HEADER_SIZE)) {
        save_disable();
        return 0;
    }
    if (save_checksum_ram((u16)(base + SAVE_HEADER_SIZE), stored_len) != stored_sum) {
        save_disable();
        return 0;
    }

    save_disable();
    return 1;
}
save_init

Sélectionne la banque RAM zéro, l’active brièvement puis la désactive.

Syntaxe

c
void save_init();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Par défaut, quatre emplacements de 512 octets contiennent chacun un en-tête de six octets et jusqu’à 506 octets de données. L’exemple utilise MBC5 avec 8 Kio de SRAM. Les appels se terminent avec la RAM désactivée, sans restaurer sa banque ni son état d’activation précédent.

N’efface pas les sauvegardes, ne détecte pas le matériel de la cartouche et ne formate pas les emplacements.

Exemple d’utilisation

c
save_init();save_clear(0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Sauvegardez trois octets, 7/42/255, puis testez une longueur différente, un emplacement invalide et une somme de contrôle endommagée. Un chargement réussi donne 42 au milieu ; une lecture échouée préserve la destination à 77 ; la validation après effacement renvoie 0.

save_init: DMG
DMG
save_init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_save.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_save.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=8k
Implémentation et source

kitaqgb/lib/rpg.h:337

Notes de déclaration (texte source)
Initialize the expected RAM access state and leave cartridge RAM disabled.
Existing slot contents are preserved.

kitaqgb/lib/save.c:70

c
void save_init()
{
    save_enable();
    save_disable();
}
save_load

Charge les données sauvegardées avec la même validation que save_read.

Syntaxe

c
u8 save_load(u8 slot, void* data, u16 len);

Paramètres

slot

Numéro d’emplacement de 0 à 3.

data

Destination accessible en écriture de len octets.

len

Longueur des données de 0 à 506 octets. La lecture exige une correspondance exacte avec la longueur enregistrée.

Valeur renvoyée

Renvoie 1 si le chargement réussit, sinon 0 ; la longueur demandée doit correspondre à la longueur enregistrée.

Conditions et limites

Par défaut, quatre emplacements de 512 octets contiennent chacun un en-tête de six octets et jusqu’à 506 octets de données. L’exemple utilise MBC5 avec 8 Kio de SRAM. Les appels se terminent avec la RAM désactivée, sans restaurer sa banque ni son état d’activation précédent.

La somme de contrôle additive sur huit bits ne détecte pas toutes les corruptions. Les écritures ne sont pas atomiques face à une coupure de courant ; un résultat de succès ne garantit donc pas à lui seul la persistance physique.

Exemple d’utilisation

c
readback[1]=0;result[10]=save_load(0,readback,3);result[11]=readback[1];

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Sauvegardez trois octets, 7/42/255, puis testez une longueur différente, un emplacement invalide et une somme de contrôle endommagée. Un chargement réussi donne 42 au milieu ; une lecture échouée préserve la destination à 77 ; la validation après effacement renvoie 0.

save_load: DMG
DMG
save_load: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_save.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_save.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=8k
Implémentation et source

kitaqgb/lib/rpg.h:339

Notes de déclaration (texte source)
Alias the checked save_read operation.

kitaqgb/lib/save.c:114

c
u8 save_load(u8 slot, void* data, u16 len)
{
    return save_read(slot, data, len);
}
save_read

Valide l’en-tête, la longueur exacte et la somme de contrôle, puis copie les données uniquement si tout est valide.

Syntaxe

c
u8 save_read(u8 slot, void* data, u16 len);

Paramètres

slot

Numéro d’emplacement de 0 à 3.

data

Destination accessible en écriture de len octets.

len

Longueur des données de 0 à 506 octets. La lecture exige une correspondance exacte avec la longueur enregistrée.

Valeur renvoyée

Renvoie 1 en cas de succès, 0 si la validation échoue ; l’échec laisse la destination inchangée.

Conditions et limites

Par défaut, quatre emplacements de 512 octets contiennent chacun un en-tête de six octets et jusqu’à 506 octets de données. L’exemple utilise MBC5 avec 8 Kio de SRAM. Les appels se terminent avec la RAM désactivée, sans restaurer sa banque ni son état d’activation précédent.

La somme de contrôle additive sur huit bits ne détecte pas toutes les corruptions. Les écritures ne sont pas atomiques face à une coupure de courant ; un résultat de succès ne garantit donc pas à lui seul la persistance physique.

Exemple d’utilisation

c
readback[0]=99;result[5]=save_read(0,readback,2);result[6]=readback[0];result[7]=save_read(0,readback,3);result[8]=readback[0];result[9]=readback[2];

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Sauvegardez trois octets, 7/42/255, puis testez une longueur différente, un emplacement invalide et une somme de contrôle endommagée. Un chargement réussi donne 42 au milieu ; une lecture échouée préserve la destination à 77 ; la validation après effacement renvoie 0.

save_read: DMG
DMG
save_read: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_save.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_save.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=8k
Implémentation et source

kitaqgb/lib/rpg.h:331

Notes de déclaration (texte source)
Require matching magic/version, exact requested length and a valid checksum
before copying data into the destination. Validation failure leaves the
destination unchanged. An invalid slot returns before touching RAM control;
validation failures after enabling RAM disable it before returning zero.

kitaqgb/lib/save.c:125

c
u8 save_read(u8 slot, void* data, u16 len)
{
    u8* dst = (u8*)data;
    u16 base;
    u16 stored_len;
    u8 stored_sum;
    u16 i;

    if (slot >= SAVE_SLOT_COUNT) return 0;

    base = save_slot_base(slot);
    save_enable();

    if (save_read_abs(base + 0) != SAVE_MAGIC0) {
        save_disable();
        return 0;
    }
    if (save_read_abs(base + 1) != SAVE_MAGIC1) {
        save_disable();
        return 0;
    }
    if (save_read_abs(base + 2) != SAVE_VERSION) {
        save_disable();
        return 0;
    }

    stored_len = (u16)save_read_abs(base + 3);
    stored_len |= (u16)((u16)save_read_abs(base + 4) << 8);
    stored_sum = save_read_abs(base + 5);

    if (stored_len != len || stored_len > (u16)(SAVE_SLOT_SIZE - SAVE_HEADER_SIZE)) {
        save_disable();
        return 0;
    }
    if (save_checksum_ram((u16)(base + SAVE_HEADER_SIZE), stored_len) != stored_sum) {
        save_disable();
        return 0;
    }

    i = 0;
    while (i < stored_len) {
        dst[i] = save_read_abs((u16)(base + SAVE_HEADER_SIZE + i));
        i++;
    }

    save_disable();
    return 1;
}
save_write

Écrit les données, leur longueur et la somme de contrôle dans un emplacement.

Syntaxe

c
u8 save_write(u8 slot, const void* data, u16 len);

Paramètres

slot

Numéro d’emplacement de 0 à 3.

data

Source lisible de len octets.

len

Longueur des données de 0 à 506 octets. La lecture exige une correspondance exacte avec la longueur enregistrée.

Valeur renvoyée

Renvoie 1 pour des arguments valides, 0 pour un emplacement ou une longueur invalide ; n’effectue pas de vérification par relecture.

Conditions et limites

Par défaut, quatre emplacements de 512 octets contiennent chacun un en-tête de six octets et jusqu’à 506 octets de données. L’exemple utilise MBC5 avec 8 Kio de SRAM. Les appels se terminent avec la RAM désactivée, sans restaurer sa banque ni son état d’activation précédent.

La somme de contrôle additive sur huit bits ne détecte pas toutes les corruptions. Les écritures ne sont pas atomiques face à une coupure de courant ; un résultat de succès ne garantit donc pas à lui seul la persistance physique.

Exemple d’utilisation

c
payload[0]=7;payload[1]=42;payload[2]=255;result[1]=save_write(0,payload,3);result[2]=save_write(4,payload,3);result[3]=save_write(0,payload,507);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Sauvegardez trois octets, 7/42/255, puis testez une longueur différente, un emplacement invalide et une somme de contrôle endommagée. Un chargement réussi donne 42 au milieu ; une lecture échouée préserve la destination à 77 ; la validation après effacement renvoie 0.

save_write: DMG
DMG
save_write: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_save.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_save.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=8k
Implémentation et source

kitaqgb/lib/rpg.h:326

Notes de déclaration (texte source)
Validate slot and payload length, write payload bytes, then write the header
and checksum. Return one after completing the writes; interruption can leave
a partially replaced slot, so this is not transactional save storage.

kitaqgb/lib/save.c:81

c
u8 save_write(u8 slot, const void* data, u16 len)
{
    const u8* src = (const u8*)data;
    u16 base;
    u16 i;
    u8 sum = 0;

    if (slot >= SAVE_SLOT_COUNT) return 0;
    if (len > (u16)(SAVE_SLOT_SIZE - SAVE_HEADER_SIZE)) return 0;

    base = save_slot_base(slot);
    save_enable();

    i = 0;
    while (i < len) {
        u8 v = src[i];
        save_write_abs((u16)(base + SAVE_HEADER_SIZE + i), v);
        sum = (u8)(sum + v);
        i++;
    }

    save_write_abs(base + 0, SAVE_MAGIC0);
    save_write_abs(base + 1, SAVE_MAGIC1);
    save_write_abs(base + 2, SAVE_VERSION);
    save_write_abs(base + 3, (u8)(len & 0xFF));
    save_write_abs(base + 4, (u8)(len >> 8));
    save_write_abs(base + 5, sum);

    save_disable();
    return 1;
}
script_run

Sélectionne un script et réinitialise son compteur d’attente, le résultat du choix et l’emplacement de retour sauvegardé.

Syntaxe

c
void script_run(u8 bank, const u8* script);

Paramètres

bank

Banque ROM du flux d’instructions.

script

Début d’un flux valide terminé ; cet appel le prépare sans exécuter de commandes.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Codes d’opération : 00 END ; 01 TEXT(bank,ptr16) ; 02 SET_FLAG(id16) ; 03 CLEAR_FLAG(id16) ; 04 JUMP(bank,ptr16) ; 05 IF_FLAG(id16,bank,ptr16) ; 06 CHOICE(count,table16) ; 07 WAIT(n) ; 08 CALL_EVENT(bank,ptr16). Les mots sont en petit-boutiste. Gardez les chaînes, tables de pointeurs et instructions lisibles et dans leurs banques mappées.

Exemple d’utilisation

c
flag_clear(19);script_run(1,(const u8*)&entry);result[0]=flag_get(19);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Sautez de la banque 1 à la banque 2, activez le drapeau 19 et attendez. Les deux premiers appels d’attente renvoient 1 ; le drapeau de destination passe à 1 ; la fin après WAIT renvoie 2. Le drapeau prouve que le contrôle a atteint l’autre banque.

script_run: DMG
DMG
script_run: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_script.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_script.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:250

Notes de déclaration (texte source)
Replace the active script and clear wait, choice and saved-return state.

kitaqgb/lib/script.c:105

c
void script_run(u8 bank, const u8* script)
{
    script_active = 1;
    script_bank = bank;
    script_pc = script;
    script_wait = 0;
    script_last_choice = 0xFF;
    script_return_active = 0;
}
script_step

Avance dans les commandes jusqu’à ce qu’une sortie, un choix, une attente ou la fin rende le contrôle.

Syntaxe

c
u8 script_step();

Valeur renvoyée

0=retour de contrôle TEXT/CHOICE ; 1=attente ; 2=terminé ou inactif. Les codes d’opération inconnus terminent aussi avec 2.

Conditions et limites

Codes d’opération : 00 END ; 01 TEXT(bank,ptr16) ; 02 SET_FLAG(id16) ; 03 CLEAR_FLAG(id16) ; 04 JUMP(bank,ptr16) ; 05 IF_FLAG(id16,bank,ptr16) ; 06 CHOICE(count,table16) ; 07 WAIT(n) ; 08 CALL_EVENT(bank,ptr16). Les mots sont en petit-boutiste. Gardez les chaînes, tables de pointeurs et instructions lisibles et dans leurs banques mappées.

WAIT n renvoie 1 au décodage, puis attend encore n appels. CALL_EVENT ne possède qu’un emplacement de retour sauvegardé. CHOICE exige un nombre non nul et bloque en interne jusqu’au choix. Une boucle de sauts sans restitution de contrôle bloque la boucle de jeu ; assurez-vous d’atteindre une commande de fin ou de restitution de contrôle.

Exemple d’utilisation

c
result[3]=script_step();result[4]=flag_get(19);result[5]=script_step();result[6]=script_step();result[7]=script_step();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Sautez de la banque 1 à la banque 2, activez le drapeau 19 et attendez. Les deux premiers appels d’attente renvoient 1 ; le drapeau de destination passe à 1 ; la fin après WAIT renvoie 2. Le drapeau prouve que le contrôle a atteint l’autre banque.

script_step: DMG
DMG
script_step: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_script.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_script.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:254

Notes de déclaration (texte source)
Execute commands until an output/choice yields (0), a wait yields (1), or
execution ends (2). Control/flag commands continue within the same call, so
a script loop without a yielding command can block the game loop indefinitely.

kitaqgb/lib/script.c:125

c
u8 script_step()
{
    if (script_active == 0) return 2;
    if (script_wait != 0) {
        script_wait--;
        return 1;
    }

    while (script_active != 0) {
        u8 op = script_read8();

        // An END returns to the one saved caller when present; otherwise it ends the script.
        if (op == SCRIPT_OP_END) {
            if (script_return_active != 0) {
                script_bank = script_return_bank;
                script_pc = script_return_pc;
                script_return_active = 0;
                continue;
            }
            script_active = 0;
            return 2;
        }

        if (op == SCRIPT_OP_TEXT) {
            u8 bank = script_read8();
            u16 ptr = script_read16();
            text_print_far(bank, (const u8*)ptr);
            return 0;
        }

        if (op == SCRIPT_OP_SET_FLAG) {
            u16 id = script_read16();
            flag_set(id);
            continue;
        }

        if (op == SCRIPT_OP_CLEAR_FLAG) {
            u16 id = script_read16();
            flag_clear(id);
            continue;
        }

        if (op == SCRIPT_OP_JUMP) {
            // Read all operands in the source bank before installing the destination.
            u8 bank = script_read8();
            u16 ptr = script_read16();
            script_bank = bank;
            script_pc = (const u8*)ptr;
            continue;
        }

        // Read all branch operands before switching bank/address so an untaken branch
        // still consumes the full instruction.
        if (op == SCRIPT_OP_IF_FLAG) {
            u16 id = script_read16();
            u8 bank = script_read8();
            u16 ptr = script_read16();
            if (flag_get(id) != 0) {
                script_bank = bank;
                script_pc = (const u8*)ptr;
            }
            continue;
        }

        if (op == SCRIPT_OP_CHOICE) {
            u8 count = script_read8();
            u16 table = script_read16();
            script_last_choice = script_choice(script_bank, (const u8*)table, count);
            return 0;
        }

        if (op == SCRIPT_OP_WAIT) {
            script_wait = script_read8();
            return 1;
        }

        // Save the continuation only when the single return slot is empty. Nested
        // calls replace the current script but do not push another return address.
        if (op == SCRIPT_OP_CALL_EVENT) {
            u8 bank = script_read8();
            u16 ptr = script_read16();
            if (script_return_active == 0) {
                script_return_active = 1;
                script_return_bank = script_bank;
                script_return_pc = script_pc;
            }
            script_bank = bank;
            script_pc = (const u8*)ptr;
            continue;
        }

        // Unknown opcodes terminate with the same return code as END; there is no distinct malformed-stream error.
        script_active = 0;
        return 2;
    }

    return 2;
}
script_wait_frames

Fait attendre le nombre demandé de prochains appels à script_step.

Syntaxe

c
void script_wait_frames(u8 n);

Paramètres

n

Nombre d’appels en attente, de 0 à 255 ; zéro annule l’attente.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Cela ne correspond à un nombre de trames que si script_step est appelé une fois par trame ; la fonction n’attend pas elle-même VBlank.

Exemple d’utilisation

c
script_wait_frames(2);result[1]=script_step();result[2]=script_step();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Sautez de la banque 1 à la banque 2, activez le drapeau 19 et attendez. Les deux premiers appels d’attente renvoient 1 ; le drapeau de destination passe à 1 ; la fin après WAIT renvoie 2. Le drapeau prouve que le contrôle a atteint l’autre banque.

script_wait_frames: DMG
DMG
script_wait_frames: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_script.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_script.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:257

Notes de déclaration (texte source)
Set the number of subsequent script_step calls to spend waiting. Frame-based
timing requires the application to call script_step once per frame.

kitaqgb/lib/script.c:117

c
void script_wait_frames(u8 n)
{
    script_wait = n;
}
text_choice

Dessine une liste verticale dans la zone active et attend un choix. UP/DOWN déplacent le curseur avec rebouclage ; A valide et B annule. La boucle redessine les choix et interroge l’entrée une fois après une attente VBlank. Renvoie un indice à partir de zéro, ou 255 pour une annulation ou une liste vide.

Syntaxe

c
u8 text_choice(const u8* const* choices, u8 count);

Paramètres

choices

Pointeur vers un tableau de count pointeurs de chaînes lisibles. Chaque chaîne se termine par zéro et contient des ID de tuile bruts ; les libellés n’interprètent pas les codes de dialogue. Gardez table et chaînes mappées jusqu’à la fin du choix.

count

Nombre de choix. Zéro renvoie immédiatement 255 sans lire la table de pointeurs. Sinon, prévoyez au moins count lignes intérieures et assez de largeur pour une case de curseur plus le libellé le plus long. Aucun découpage ni défilement n’est effectué.

Valeur renvoyée

Indice de 0 à count−1 lors d’une validation par A. La valeur 255 signifie annulation par B ou count nul ; distinguez ces cas dans l’appelant si nécessaire. La fonction ne ferme pas la zone et n’efface pas la liste.

Conditions et limites

Utilisez un rectangle BG valide et chargez d’abord les tuiles de police et de cadre. La zone logicielle utilise la carte BG choisie par le bit 3 de LCDC, sans activer la couche Window matérielle. Sur CGB, utilisez VBK 0 pour les numéros et réglez les couleurs séparément. Les exemples fournissent la police mappée en ASCII et les tuiles de cadre, curseur et indicateur de page. Dialogues et choix utilisent des ID de tuile d’un octet, sans décodage UTF-8. Pour d’autres caractères, fournissez leurs glyphes et encodez le texte avec ces ID, en réservant les octets de contrôle du dialogue.

Ouvrez et dimensionnez la zone avant l’appel. La sélection utilise sa position mémorisée sans vérifier qu’elle est ouverte. Les libellés commencent deux colonnes après le bord gauche et une ligne sous le haut ; le curseur est juste à leur gauche. Leur affichage n’utilise pas le réglage de vitesse du dialogue.

La boucle réagit aux nouveaux appuis, UP avant DOWN et A avant B. Maintenir une direction ne répète pas le mouvement ; relâchez puis appuyez à nouveau. Le masque précédent commençant à zéro, un bouton tenu peut agir dès l’entrée. Déplacement et A simultanés renvoient l’indice après déplacement, même si le dernier curseur dessiné montre encore l’ancienne position.

Ces fonctions sont bloquantes : pendant l’attente, elles n’appellent ni mise à jour du jeu, ni service musical, ni boucle de rendu. LCD éteint, __wait_vblank revient immédiatement ; vitesse des caractères et WAIT ne créent donc pas de délais en trames. Gardez le LCD actif pour le dialogue temporisé et les entrées cadencées par trame. Utilisez une machine à états côté jeu si d’autres tâches doivent avancer pendant la conversation.

Les écritures de tuiles sûres sous-jacentes attendent un mode LCD accessible et encadrent l’écriture par DI/EI. Elles peuvent activer les interruptions au lieu de préserver un état initialement désactivé. Ne les appelez pas depuis un gestionnaire d’interruption et ne comptez pas sur elles pour préserver cet état.

Chaque exemple complet inclut text.c une fois. Compilez avec les répertoires d’inclusion de la bibliothèque et des exemples du manuel ; n’ajoutez pas aussi lib/text.c comme source séparée. L’exemple de flux distant utilise MBC5 et une ROM de 64 Kio pour contenir les données de banque 2.

Exemple d’utilisation

c
selected=text_choice(dialogue_choices,3);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Appuyez une fois sur DOWN puis sur A. Dans la capture, le curseur pointant à droite est à côté de SHIELD en (2,4) et SELECTED vaut 1. Les libellés commencent en (3,3), (3,4) et (3,5). Cadre, curseur et libellés sont verts sur CGB, noirs sur DMG ; résultat et consignes restent noirs.

Les tests sur émulateur comparent tout le contenu BG et les quatre images d’exemple. D’autres exécutions couvrent ouverture/fermeture, flux ordinaires et bancarisés, temporisations, pages explicites et automatiques, avances A/B/START, boutons tenus, choix circulaires, listes vides et priorités simultanées. Des points de contrôle avant et après l’entrée scriptée vérifient le blocage réel des pages. Matériel physique et concurrence des interruptions ne sont pas testés.

text_choice: DMG
DMG
text_choice: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dialogue_choice.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dialogue_choice.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:231

Notes de déclaration (texte source)
Redraw choices and block for edge-triggered navigation: UP/DOWN wrap, A
accepts, and B returns 0xFF. Zero choices also returns 0xFF. Choice strings
use raw tile bytes, and the caller must fit them inside the available rows.

kitaqgb/lib/text.c:316

c
u8 text_choice(const u8* const* choices, u8 count)
{
    u8 cursor;
    u8 prev;

    if (count == 0) return 0xFF;

    cursor = 0;
    prev = 0;
    while (1) {
        u8 i;
        for (i = 0; i < count; i++) {
            u8 py = (u8)(text_y + 1 + i);
            __settile_xy((u8)(text_x + 1), py, (i == cursor) ? TEXT_TILE_CURSOR : TEXT_TILE_FILL);
            text_draw_string_at((u8)(text_x + 2), py, choices[i]);
        }

        __wait_vblank();
        {
            u16 kt = __readpadex(prev);
            u8 trigger;
            prev = (u8)kt;
            trigger = (u8)(kt >> 8);

            if ((trigger & PAD_KEY_UP) != 0) {
                if (cursor == 0) cursor = (u8)(count - 1);
                else cursor--;
            }
            if ((trigger & PAD_KEY_DOWN) != 0) {
                cursor++;
                if (cursor >= count) cursor = 0;
            }
            if ((trigger & PAD_KEY_A) != 0) return cursor;
            if ((trigger & PAD_KEY_B) != 0) return 0xFF;
        }
    }
}
text_clear_rect

Remplit un rectangle de la carte de tuiles du fond avec TEXT_TILE_FILL. Utilisez-le pour effacer un libellé, un champ numérique ou une partie de panneau. Le curseur actif ne bouge pas ; la zone de texte reste ouverte et garde ses dimensions.

Syntaxe

c
void text_clear_rect(u8 x, u8 y, u8 w, u8 h);

Paramètres

x

Colonne de départ, en cases de 8×8 de la carte du fond. Toute la sortie doit tenir dans les colonnes 0–31. Sans défilement du fond, les colonnes visibles sont 0–19.

y

Ligne de départ, de 0 à 31, en cases de 8×8 de la carte du fond. Sans défilement, les lignes 0–17 sont visibles. Un rectangle doit aussi tenir verticalement dans la carte.

w

Largeur en cases. Pour text_window, elle comprend les deux colonnes du cadre, laissant max(w−2, 0) colonnes intérieures. Pour text_clear_rect, c’est le nombre de cases à remplir sur chaque ligne.

h

Hauteur en cases. Pour text_window, elle comprend les bords supérieur et inférieur, laissant max(h−2, 0) lignes intérieures. Pour text_clear_rect, c’est le nombre de lignes à remplir.

Valeur renvoyée

Aucune valeur de retour. La fonction écrit les cases de la carte avant de rendre la main ; elle ne renvoie ni nombre de caractères ni code d’état.

Conditions et limites

Ces fonctions écrivent dans la carte BG sélectionnée par le bit 3 de LCDC. La fenêtre de texte est une zone logicielle sur cette carte, et non le plan Window matériel. Gardez VBK à 0 sur CGB pour écrire les numéros de tuiles ; ces appels ne règlent ni attributs de couleur, ni palettes, ni défilement.

Chargez la police et les graphismes du cadre avant de dessiner. Les ID de cadre par défaut vont de 1 à 6, la tuile de remplissage vaut 0 et les chiffres commencent à ASCII 0 (tuile 48). Le signe moins utilise ASCII - (tuile 45). L’exemple fournit six tuiles de cadre et la police du manuel, dont les ID de glyphes correspondent à l’ASCII.

Gardez rectangles et texte dans la carte de 32×32. Le remplissage ne réduit pas la largeur ou la hauteur aux limites de la carte. Une largeur ou une hauteur nulle ne remplit rien ; text_window enregistre néanmoins une zone ouverte, sans intérieur utilisable.

Les fonctions numériques publiques utilisent exactement la largeur du nouveau nombre. Elles n’effacent pas les cases restantes à droite. Écrire 7 sur 12345 au même endroit affiche 72345. Pour n’obtenir que 7, effacez d’abord le champ réservé de cinq cases avec text_clear_rect. Réservez six cases pour un entier signé sur 16 bits.

Les intrinsèques d’écriture vérifient l’état du LCD : éteint, elles écrivent immédiatement ; allumé, elles attendent un mode autorisant l’écriture et encadrent celle-ci par DI/EI. Ce chemin peut réactiver les interruptions au retour ; ne supposez donc pas qu’il préserve leur désactivation. Ici, les exemples et tests octet par octet écrivent avec le LCD éteint.

L’exemple complet inclut text.c une seule fois pour compiler l’implémentation avec le programme. Ne passez pas également lib/text.c comme entrée séparée. Pour personnaliser les constantes de tuiles TEXT_*, définissez-les avant d’inclure rpg.h et l’implémentation ; utilisez les mêmes définitions partout où la bibliothèque est compilée.

Exemple d’utilisation

c
text_clear_rect(7,5,5,1);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Au départ, le cadre contient KEEP ERASE KEEP sur la ligne 5. Effacer cinq cases en (7,5) supprime ERASE tout en conservant les deux KEEP et le cadre. La ligne CLEAN efface elle aussi un champ numérique de cinq cases avant d’écrire 7.

La vérification compare chaque pixel visible et les 1024 octets de la carte BG dans les deux écrans d’exemple. Des ROM DMG/CGB distinctes testent les 256 valeurs d’octet non signé, les changements de nombre de chiffres et les extrêmes signés, en conservant des points sentinelles à côté de chaque nombre. Les contrôles de placement couvrent les rectangles vides ou étroits, les bords de carte, les octets de tuiles dont la valeur correspond à un code de contrôle et le curseur de fenêtre après des écritures absolues. Il s’agit de tests sur émulateur, pas sur matériel physique.

text_clear_rect: DMG
DMG
text_clear_rect: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\text_layout.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\text_layout.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:237

Notes de déclaration (texte source)
Fill the supplied tile rectangle without changing the active text window or cursor.

kitaqgb/lib/text.c:220

c
void text_clear_rect(u8 x, u8 y, u8 w, u8 h)
{
    __settile_rect(x, y, w, h, TEXT_TILE_FILL);
}
text_close

Efface la zone de texte active, cadre compris, avec TEXT_TILE_FILL et la marque fermée. Un nouvel appel lorsqu’elle est fermée est sans effet. Les anciennes tuiles de fond présentes avant l’ouverture ne sont pas restaurées.

Syntaxe

c
void text_close();

Valeur renvoyée

Aucune valeur de retour. Le dessin et les attentes bloquantes ont lieu avant le retour.

Conditions et limites

Utilisez un rectangle BG valide et chargez d’abord les tuiles de police et de cadre. La zone logicielle utilise la carte BG choisie par le bit 3 de LCDC, sans activer la couche Window matérielle. Sur CGB, utilisez VBK 0 pour les numéros et réglez les couleurs séparément. Les exemples fournissent la police mappée en ASCII et les tuiles de cadre, curseur et indicateur de page. Dialogues et choix utilisent des ID de tuile d’un octet, sans décodage UTF-8. Pour d’autres caractères, fournissez leurs glyphes et encodez le texte avec ces ID, en réservant les octets de contrôle du dialogue.

Les caractères ordinaires sont ignorés si la zone est fermée ou sans intérieur utilisable. Les contrôles restent interprétés : WAIT peut bloquer et les commandes de page peuvent attendre ou effacer la zone mémorisée. text_print sur une zone fermée n’est donc pas systématiquement sans effet.

Ces fonctions sont bloquantes : pendant l’attente, elles n’appellent ni mise à jour du jeu, ni service musical, ni boucle de rendu. LCD éteint, __wait_vblank revient immédiatement ; vitesse des caractères et WAIT ne créent donc pas de délais en trames. Gardez le LCD actif pour le dialogue temporisé et les entrées cadencées par trame. Utilisez une machine à états côté jeu si d’autres tâches doivent avancer pendant la conversation.

Les écritures de tuiles sûres sous-jacentes attendent un mode LCD accessible et encadrent l’écriture par DI/EI. Elles peuvent activer les interruptions au lieu de préserver un état initialement désactivé. Ne les appelez pas depuis un gestionnaire d’interruption et ne comptez pas sur elles pour préserver cet état.

Chaque exemple complet inclut text.c une fois. Compilez avec les répertoires d’inclusion de la bibliothèque et des exemples du manuel ; n’ajoutez pas aussi lib/text.c comme source séparée. L’exemple de flux distant utilise MBC5 et une ROM de 64 Kio pour contenir les données de banque 2.

Exemple d’utilisation

c
text_close();
text_print("HIDDEN"); // With the area closed, ordinary characters are not drawn.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple ouvre une zone de 18×3 cases en (1,9), écrit ERASE ME, la ferme puis tente d’écrire HIDDEN. Sous CLOSED AREA, les cases x=1–18 et y=9–11 doivent être vides, sans texte ni cadre. Le dialogue bleu au-dessus reste visible.

Les tests sur émulateur comparent tout le contenu BG et les quatre images d’exemple. D’autres exécutions couvrent ouverture/fermeture, flux ordinaires et bancarisés, temporisations, pages explicites et automatiques, avances A/B/START, boutons tenus, choix circulaires, listes vides et priorités simultanées. Des points de contrôle avant et après l’entrée scriptée vérifient le blocage réel des pages. Matériel physique et concurrence des interruptions ne sont pas testés.

text_close: DMG
DMG
text_close: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dialogue_flow.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dialogue_flow.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:220

Notes de déclaration (texte source)
Erase the open window with the fill tile and disable windowed character output.

kitaqgb/lib/text.c:200

c
void text_close()
{
    if (text_opened == 0) return;
    __settile_rect(text_x, text_y, text_w, text_h, TEXT_TILE_FILL);
    text_opened = 0;
}
text_open

Ouvre une zone de texte logicielle sur la carte de fond. Mémorise sa position et sa taille, replace le curseur au premier emplacement intérieur, dessine le cadre et vide l’intérieur. Ouvrir une autre zone change la zone et le curseur actifs, sans effacer une zone déjà dessinée ailleurs.

Syntaxe

c
void text_open(u8 x, u8 y, u8 w, u8 h);

Paramètres

x

Colonne gauche de la zone en cases BG de 8×8 pixels. Gardez toute la largeur dans les colonnes 0–31.

y

Ligne supérieure de la zone en cases BG de 8×8 pixels. Gardez toute la hauteur dans les lignes 0–31.

w

Largeur totale en cases, bordures gauche et droite comprises. Il faut au moins trois cases pour une colonne intérieure de caractères.

h

Hauteur totale en cases, bordures supérieure et inférieure comprises. Il faut au moins trois cases pour une ligne intérieure de caractères.

Valeur renvoyée

Aucune valeur de retour. Le dessin et les attentes bloquantes ont lieu avant le retour.

Conditions et limites

Utilisez un rectangle BG valide et chargez d’abord les tuiles de police et de cadre. La zone logicielle utilise la carte BG choisie par le bit 3 de LCDC, sans activer la couche Window matérielle. Sur CGB, utilisez VBK 0 pour les numéros et réglez les couleurs séparément. Les exemples fournissent la police mappée en ASCII et les tuiles de cadre, curseur et indicateur de page. Dialogues et choix utilisent des ID de tuile d’un octet, sans décodage UTF-8. Pour d’autres caractères, fournissez leurs glyphes et encodez le texte avec ces ID, en réservant les octets de contrôle du dialogue.

Ces fonctions sont bloquantes : pendant l’attente, elles n’appellent ni mise à jour du jeu, ni service musical, ni boucle de rendu. LCD éteint, __wait_vblank revient immédiatement ; vitesse des caractères et WAIT ne créent donc pas de délais en trames. Gardez le LCD actif pour le dialogue temporisé et les entrées cadencées par trame. Utilisez une machine à états côté jeu si d’autres tâches doivent avancer pendant la conversation.

Les écritures de tuiles sûres sous-jacentes attendent un mode LCD accessible et encadrent l’écriture par DI/EI. Elles peuvent activer les interruptions au lieu de préserver un état initialement désactivé. Ne les appelez pas depuis un gestionnaire d’interruption et ne comptez pas sur elles pour préserver cet état.

Chaque exemple complet inclut text.c une fois. Compilez avec les répertoires d’inclusion de la bibliothèque et des exemples du manuel ; n’ajoutez pas aussi lib/text.c comme source séparée. L’exemple de flux distant utilise MBC5 et une ROM de 64 Kio pour contenir les données de banque 2.

Exemple d’utilisation

c
text_open(1,2,18,5);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

DIALOGUE FLOW ouvre un cadre de 18×5 cases en (1,2), avec un intérieur de 16×3. NEAR, READY et BANK 2 occupent les trois lignes. Les traits visibles s’étendent de x=11 à 147 et y=19 à 51 pixels. Cadre et texte sont bleus sur CGB, noirs sur DMG. L’ouverture ultérieure de la zone de test d’effacement laisse ce cadre visible.

Les tests sur émulateur comparent tout le contenu BG et les quatre images d’exemple. D’autres exécutions couvrent ouverture/fermeture, flux ordinaires et bancarisés, temporisations, pages explicites et automatiques, avances A/B/START, boutons tenus, choix circulaires, listes vides et priorités simultanées. Des points de contrôle avant et après l’entrée scriptée vérifient le blocage réel des pages. Matériel physique et concurrence des interruptions ne sont pas testés.

text_open: DMG
DMG
text_open: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dialogue_flow.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dialogue_flow.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:218

Notes de déclaration (texte source)
Set the tile-space window, reset its cursor and redraw it immediately.
Opening does not reset the existing character speed or load font tiles.

kitaqgb/lib/text.c:187

c
void text_open(u8 x, u8 y, u8 w, u8 h)
{
    text_x = x;
    text_y = y;
    text_w = w;
    text_h = h;
    text_opened = 1;
    text_reset_cursor();
    text_draw_frame();
    text_clear_inside();
}
text_print

Lit un flux de contrôle via un pointeur ordinaire et écrit ses tuiles de caractères au curseur de la fenêtre active. Interprète retours à la ligne, attentes temporisées et de page, avec renvoi à la largeur intérieure. Ne revient qu’à END ; une attente de page peut donc bloquer jusqu’à l’appui sur un bouton.

Syntaxe

c
void text_print(const u8* str);

Paramètres

str

Pointeur lisible vers un flux terminé par TEXT_CTRL_END (0). Gardez tout le flux mappé pendant les attentes bloquantes, y compris l’opérande après WAIT. Aucune longueur de tampon ni vérification de validité n’est fournie.

Valeur renvoyée

Aucune valeur de retour. Le dessin et les attentes bloquantes ont lieu avant le retour.

Conditions et limites

Utilisez un rectangle BG valide et chargez d’abord les tuiles de police et de cadre. La zone logicielle utilise la carte BG choisie par le bit 3 de LCDC, sans activer la couche Window matérielle. Sur CGB, utilisez VBK 0 pour les numéros et réglez les couleurs séparément. Les exemples fournissent la police mappée en ASCII et les tuiles de cadre, curseur et indicateur de page. Dialogues et choix utilisent des ID de tuile d’un octet, sans décodage UTF-8. Pour d’autres caractères, fournissez leurs glyphes et encodez le texte avec ces ID, en réservant les octets de contrôle du dialogue.

Octets de contrôle : 0x00 termine le flux ; 0x0A passe à la ligne intérieure suivante ; 0x01 consomme l’octet suivant comme nombre d’attentes VBlank, y compris zéro ; 0x02 attend un changement de page, vide l’intérieur et réinitialise le curseur. Les autres octets sont des ID de tuile. Un opérande WAIT nul n’est pas un marqueur END.

Dépasser la dernière ligne intérieure par saut ou renvoi automatique affiche le repère de page, attend A, B ou START, vide l’intérieur puis reprend à la première case. La page est remplacée, pas défilée. Un 0x02 explicite attend sans ajouter de repère. Le test de page débute sans bouton mémorisé : un bouton déjà tenu au début peut donc faire avancer la page.

Les caractères ordinaires sont ignorés si la zone est fermée ou sans intérieur utilisable. Les contrôles restent interprétés : WAIT peut bloquer et les commandes de page peuvent attendre ou effacer la zone mémorisée. text_print sur une zone fermée n’est donc pas systématiquement sans effet.

Ces fonctions sont bloquantes : pendant l’attente, elles n’appellent ni mise à jour du jeu, ni service musical, ni boucle de rendu. LCD éteint, __wait_vblank revient immédiatement ; vitesse des caractères et WAIT ne créent donc pas de délais en trames. Gardez le LCD actif pour le dialogue temporisé et les entrées cadencées par trame. Utilisez une machine à états côté jeu si d’autres tâches doivent avancer pendant la conversation.

Les écritures de tuiles sûres sous-jacentes attendent un mode LCD accessible et encadrent l’écriture par DI/EI. Elles peuvent activer les interruptions au lieu de préserver un état initialement désactivé. Ne les appelez pas depuis un gestionnaire d’interruption et ne comptez pas sur elles pour préserver cet état.

Chaque exemple complet inclut text.c une fois. Compilez avec les répertoires d’inclusion de la bibliothèque et des exemples du manuel ; n’ajoutez pas aussi lib/text.c comme source séparée. L’exemple de flux distant utilise MBC5 et une ROM de 64 Kio pour contenir les données de banque 2.

Exemple d’utilisation

c
text_print(dialogue_near);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le flux ordinaire écrit NEAR, un saut de ligne, READY et une attente de douze appels avant END. NEAR commence à la tuile (2,3), READY à (2,4). Le flux bancarisé suivant reprend au même curseur ; son premier saut place donc BANK 2 sur la troisième ligne intérieure.

Les tests sur émulateur comparent tout le contenu BG et les quatre images d’exemple. D’autres exécutions couvrent ouverture/fermeture, flux ordinaires et bancarisés, temporisations, pages explicites et automatiques, avances A/B/START, boutons tenus, choix circulaires, listes vides et priorités simultanées. Des points de contrôle avant et après l’entrée scriptée vérifient le blocage réel des pages. Matériel physique et concurrence des interruptions ne sont pas testés.

text_print: DMG
DMG
text_print: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dialogue_flow.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dialogue_flow.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:224

Notes de déclaration (texte source)
Decode an END-terminated stream of tile bytes and newline/wait/page controls.
WAIT consumes a following frame-count byte. The source must remain readable
through blocking waits; the routine does not validate stream length.

kitaqgb/lib/text.c:261

c
void text_print(const u8* str)
{
    while (*str != TEXT_CTRL_END) {
        u8 c = *str++;
        if (c == TEXT_CTRL_NEWLINE) {
            text_newline();
            continue;
        }
        if (c == TEXT_CTRL_WAIT) {
            u8 frames = *str++;
            text_delay_frames(frames);
            continue;
        }
        if (c == TEXT_CTRL_PAGE_WAIT) {
            text_wait_advance();
            text_clear_inside();
            text_reset_cursor();
            continue;
        }
        text_put_tile(c);
    }
}
text_print_far

Interprète le même flux de dialogue en lisant chaque octet dans la banque ROM indiquée avec __farpeek8. Utilisez-le pour un dialogue hors de la banque source actuellement mappée. Placement, vitesse, renvoi à la ligne et contrôle des pages sont identiques à text_print.

Syntaxe

c
void text_print_far(u8 bank, const u8* str);

Paramètres

bank

Numéro de banque ROM source sur huit bits non signés. L’exemple stocke le flux en banque 2 et vérifie que l’appelant peut encore lire un repère en banque 1 après l’affichage.

str

Adresse CPU du flux dans la banque indiquée. L’adresse avance, mais la banque reste fixe ; franchir la fenêtre ROM commutable ne poursuit pas automatiquement dans la banque suivante.

Valeur renvoyée

Aucune valeur de retour. Le dessin et les attentes bloquantes ont lieu avant le retour.

Conditions et limites

Utilisez un rectangle BG valide et chargez d’abord les tuiles de police et de cadre. La zone logicielle utilise la carte BG choisie par le bit 3 de LCDC, sans activer la couche Window matérielle. Sur CGB, utilisez VBK 0 pour les numéros et réglez les couleurs séparément. Les exemples fournissent la police mappée en ASCII et les tuiles de cadre, curseur et indicateur de page. Dialogues et choix utilisent des ID de tuile d’un octet, sans décodage UTF-8. Pour d’autres caractères, fournissez leurs glyphes et encodez le texte avec ces ID, en réservant les octets de contrôle du dialogue.

Octets de contrôle : 0x00 termine le flux ; 0x0A passe à la ligne intérieure suivante ; 0x01 consomme l’octet suivant comme nombre d’attentes VBlank, y compris zéro ; 0x02 attend un changement de page, vide l’intérieur et réinitialise le curseur. Les autres octets sont des ID de tuile. Un opérande WAIT nul n’est pas un marqueur END.

Dépasser la dernière ligne intérieure par saut ou renvoi automatique affiche le repère de page, attend A, B ou START, vide l’intérieur puis reprend à la première case. La page est remplacée, pas défilée. Un 0x02 explicite attend sans ajouter de repère. Le test de page débute sans bouton mémorisé : un bouton déjà tenu au début peut donc faire avancer la page.

Les caractères ordinaires sont ignorés si la zone est fermée ou sans intérieur utilisable. Les contrôles restent interprétés : WAIT peut bloquer et les commandes de page peuvent attendre ou effacer la zone mémorisée. text_print sur une zone fermée n’est donc pas systématiquement sans effet.

Ces fonctions sont bloquantes : pendant l’attente, elles n’appellent ni mise à jour du jeu, ni service musical, ni boucle de rendu. LCD éteint, __wait_vblank revient immédiatement ; vitesse des caractères et WAIT ne créent donc pas de délais en trames. Gardez le LCD actif pour le dialogue temporisé et les entrées cadencées par trame. Utilisez une machine à états côté jeu si d’autres tâches doivent avancer pendant la conversation.

Les écritures de tuiles sûres sous-jacentes attendent un mode LCD accessible et encadrent l’écriture par DI/EI. Elles peuvent activer les interruptions au lieu de préserver un état initialement désactivé. Ne les appelez pas depuis un gestionnaire d’interruption et ne comptez pas sur elles pour préserver cet état.

Chaque exemple complet inclut text.c une fois. Compilez avec les répertoires d’inclusion de la bibliothèque et des exemples du manuel ; n’ajoutez pas aussi lib/text.c comme source séparée. L’exemple de flux distant utilise MBC5 et une ROM de 64 Kio pour contenir les données de banque 2.

Exemple d’utilisation

c
text_print_far(2,dialogue_far);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple lit le saut de ligne et BANK 2 en banque ROM 2. BANK RESTORED affiche 161 après lecture du repère dans la banque 1 de l’appelant. La ligne BANK 2 commence en (2,5) ; le nombre de restauration apparaît en (16,14).

Les tests sur émulateur comparent tout le contenu BG et les quatre images d’exemple. D’autres exécutions couvrent ouverture/fermeture, flux ordinaires et bancarisés, temporisations, pages explicites et automatiques, avances A/B/START, boutons tenus, choix circulaires, listes vides et priorités simultanées. Des points de contrôle avant et après l’entrée scriptée vérifient le blocage réel des pages. Matériel physique et concurrence des interruptions ne sont pas testés.

text_print_far: DMG
DMG
text_print_far: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dialogue_flow.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dialogue_flow.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:227

Notes de déclaration (texte source)
Decode the same text controls while fetching each byte from the specified
ROM bank. The pointer advances within that bank; it does not roll into the next bank.

kitaqgb/lib/text.c:286

c
void text_print_far(u8 bank, const u8* str)
{
    const u8* p = str;
    while (1) {
        u8 c = __farpeek8(bank, p);
        p++;
        if (c == TEXT_CTRL_END) return;
        if (c == TEXT_CTRL_NEWLINE) {
            text_newline();
            continue;
        }
        if (c == TEXT_CTRL_WAIT) {
            u8 frames = __farpeek8(bank, p);
            p++;
            text_delay_frames(frames);
            continue;
        }
        if (c == TEXT_CTRL_PAGE_WAIT) {
            text_wait_advance();
            text_clear_inside();
            text_reset_cursor();
            continue;
        }
        text_put_tile(c);
    }
}
text_print_s16

Affiche une valeur signée sur 16 bits en décimal. Une valeur négative commence par la tuile du signe moins, suivie de sa valeur absolue ; zéro et les valeurs positives n’ont pas de signe. La sortie la plus longue, -32768, occupe six cases.

Syntaxe

c
void text_print_s16(u8 x, u8 y, s16 value);

Paramètres

x

Colonne de départ, en cases de 8×8 de la carte du fond. Toute la sortie doit tenir dans les colonnes 0–31. Sans défilement du fond, les colonnes visibles sont 0–19.

y

Ligne de départ, de 0 à 31, en cases de 8×8 de la carte du fond. Sans défilement, les lignes 0–17 sont visibles. Un rectangle doit aussi tenir verticalement dans la carte.

value

Valeur signée de −32768 à 32767. L’exemple convertit explicitement le motif de 16 bits 32768 (0x8000) en s16 pour afficher −32768.

Valeur renvoyée

Aucune valeur de retour. La fonction écrit les cases de la carte avant de rendre la main ; elle ne renvoie ni nombre de caractères ni code d’état.

Conditions et limites

Ces fonctions écrivent dans la carte BG sélectionnée par le bit 3 de LCDC. La fenêtre de texte est une zone logicielle sur cette carte, et non le plan Window matériel. Gardez VBK à 0 sur CGB pour écrire les numéros de tuiles ; ces appels ne règlent ni attributs de couleur, ni palettes, ni défilement.

Chargez la police et les graphismes du cadre avant de dessiner. Les ID de cadre par défaut vont de 1 à 6, la tuile de remplissage vaut 0 et les chiffres commencent à ASCII 0 (tuile 48). Le signe moins utilise ASCII - (tuile 45). L’exemple fournit six tuiles de cadre et la police du manuel, dont les ID de glyphes correspondent à l’ASCII.

Gardez rectangles et texte dans la carte de 32×32. Le remplissage ne réduit pas la largeur ou la hauteur aux limites de la carte. Une largeur ou une hauteur nulle ne remplit rien ; text_window enregistre néanmoins une zone ouverte, sans intérieur utilisable.

Les fonctions numériques publiques utilisent exactement la largeur du nouveau nombre. Elles n’effacent pas les cases restantes à droite. Écrire 7 sur 12345 au même endroit affiche 72345. Pour n’obtenir que 7, effacez d’abord le champ réservé de cinq cases avec text_clear_rect. Réservez six cases pour un entier signé sur 16 bits.

Les intrinsèques d’écriture vérifient l’état du LCD : éteint, elles écrivent immédiatement ; allumé, elles attendent un mode autorisant l’écriture et encadrent celle-ci par DI/EI. Ce chemin peut réactiver les interruptions au retour ; ne supposez donc pas qu’il préserve leur désactivation. Ici, les exemples et tests octet par octet écrivent avec le LCD éteint.

L’exemple complet inclut text.c une seule fois pour compiler l’implémentation avec le programme. Ne passez pas également lib/text.c comme entrée séparée. Pour personnaliser les constantes de tuiles TEXT_*, définissez-les avant d’inclure rpg.h et l’implémentation ; utilisez les mêmes définitions partout où la bibliothèque est compilée.

Exemple d’utilisation

c
text_print_s16(11,12,(s16)32768);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La ligne S16 affiche -32768 à partir de (11,12), sur six cases signe moins compris, en vert sur CGB. Elle teste la plus petite valeur signée sur 16 bits, dont la valeur absolue positive ne tient pas dans s16.

La vérification compare chaque pixel visible et les 1024 octets de la carte BG dans les deux écrans d’exemple. Des ROM DMG/CGB distinctes testent les 256 valeurs d’octet non signé, les changements de nombre de chiffres et les extrêmes signés, en conservant des points sentinelles à côté de chaque nombre. Les contrôles de placement couvrent les rectangles vides ou étroits, les bords de carte, les octets de tuiles dont la valeur correspond à un code de contrôle et le curseur de fenêtre après des écritures absolues. Il s’agit de tests sur émulateur, pas sur matériel physique.

text_print_s16: DMG
DMG
text_print_s16: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\text_layout.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\text_layout.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:247

Notes de déclaration (texte source)
Print a minus tile for negative values, followed by the unsigned magnitude.
Positive values use the unsigned decimal path; no plus sign is emitted.

kitaqgb/lib/text.c:246

c
void text_print_s16(u8 x, u8 y, s16 value)
{
    u16 magnitude;
    if (value < 0) {
        __settile_xy(x, y, (u8)'-');
        magnitude = (u16)((s16)0 - value);
        text_print_u16_width((u8)(x + 1), y, magnitude, text_dec_digits_u16(magnitude));
        return;
    }
    text_print_u16(x, y, (u16)value);
}
text_print_u16

Affiche une valeur non signée sur 16 bits en décimal à partir de la position de tuile indiquée. La sortie occupe une à cinq cases, sans zéro initial. Utilisez-la pour un score ou un nombre d’objets pouvant dépasser 255.

Syntaxe

c
void text_print_u16(u8 x, u8 y, u16 value);

Paramètres

x

Colonne de départ, en cases de 8×8 de la carte du fond. Toute la sortie doit tenir dans les colonnes 0–31. Sans défilement du fond, les colonnes visibles sont 0–19.

y

Ligne de départ, de 0 à 31, en cases de 8×8 de la carte du fond. Sans défilement, les lignes 0–17 sont visibles. Un rectangle doit aussi tenir verticalement dans la carte.

value

Valeur non signée de 0 à 65535.

Valeur renvoyée

Aucune valeur de retour. La fonction écrit les cases de la carte avant de rendre la main ; elle ne renvoie ni nombre de caractères ni code d’état.

Conditions et limites

Ces fonctions écrivent dans la carte BG sélectionnée par le bit 3 de LCDC. La fenêtre de texte est une zone logicielle sur cette carte, et non le plan Window matériel. Gardez VBK à 0 sur CGB pour écrire les numéros de tuiles ; ces appels ne règlent ni attributs de couleur, ni palettes, ni défilement.

Chargez la police et les graphismes du cadre avant de dessiner. Les ID de cadre par défaut vont de 1 à 6, la tuile de remplissage vaut 0 et les chiffres commencent à ASCII 0 (tuile 48). Le signe moins utilise ASCII - (tuile 45). L’exemple fournit six tuiles de cadre et la police du manuel, dont les ID de glyphes correspondent à l’ASCII.

Gardez rectangles et texte dans la carte de 32×32. Le remplissage ne réduit pas la largeur ou la hauteur aux limites de la carte. Une largeur ou une hauteur nulle ne remplit rien ; text_window enregistre néanmoins une zone ouverte, sans intérieur utilisable.

Les fonctions numériques publiques utilisent exactement la largeur du nouveau nombre. Elles n’effacent pas les cases restantes à droite. Écrire 7 sur 12345 au même endroit affiche 72345. Pour n’obtenir que 7, effacez d’abord le champ réservé de cinq cases avec text_clear_rect. Réservez six cases pour un entier signé sur 16 bits.

Les intrinsèques d’écriture vérifient l’état du LCD : éteint, elles écrivent immédiatement ; allumé, elles attendent un mode autorisant l’écriture et encadrent celle-ci par DI/EI. Ce chemin peut réactiver les interruptions au retour ; ne supposez donc pas qu’il préserve leur désactivation. Ici, les exemples et tests octet par octet écrivent avec le LCD éteint.

L’exemple complet inclut text.c une seule fois pour compiler l’implémentation avec le programme. Ne passez pas également lib/text.c comme entrée séparée. Pour personnaliser les constantes de tuiles TEXT_*, définissez-les avant d’inclure rpg.h et l’implémentation ; utilisez les mêmes définitions partout où la bibliothèque est compilée.

Exemple d’utilisation

c
text_print_u16(11,10,65535);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La ligne U16 affiche 65535 en (11,10), sur cinq cases, en bleu sur CGB. OVERWRITE affiche 72345 après l’écriture de 7 sur 12345 sans effacement préalable du champ de cinq cases.

La vérification compare chaque pixel visible et les 1024 octets de la carte BG dans les deux écrans d’exemple. Des ROM DMG/CGB distinctes testent les 256 valeurs d’octet non signé, les changements de nombre de chiffres et les extrêmes signés, en conservant des points sentinelles à côté de chaque nombre. Les contrôles de placement couvrent les rectangles vides ou étroits, les bords de carte, les octets de tuiles dont la valeur correspond à un code de contrôle et le curseur de fenêtre après des écritures absolues. Il s’agit de tests sur émulateur, pas sur matériel physique.

text_print_u16: DMG
DMG
text_print_u16: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\text_layout.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\text_layout.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:244

Notes de déclaration (texte source)
Print an unsigned word in decimal using only the required number of cells.

kitaqgb/lib/text.c:239

c
void text_print_u16(u8 x, u8 y, u16 value)
{
    text_print_u16_width(x, y, value, text_dec_digits_u16(value));
}
text_print_u8

Affiche une valeur non signée sur 8 bits en décimal à partir de la position de tuile indiquée. Elle occupe une à trois cases, sans zéro initial ; zéro occupe une case. Convient aux petits compteurs, comme les vies ou les munitions.

Syntaxe

c
void text_print_u8(u8 x, u8 y, u8 value);

Paramètres

x

Colonne de départ, en cases de 8×8 de la carte du fond. Toute la sortie doit tenir dans les colonnes 0–31. Sans défilement du fond, les colonnes visibles sont 0–19.

y

Ligne de départ, de 0 à 31, en cases de 8×8 de la carte du fond. Sans défilement, les lignes 0–17 sont visibles. Un rectangle doit aussi tenir verticalement dans la carte.

value

Valeur non signée de 0 à 255. Les expressions de type plus large sont converties en u8 par le paramètre de la fonction.

Valeur renvoyée

Aucune valeur de retour. La fonction écrit les cases de la carte avant de rendre la main ; elle ne renvoie ni nombre de caractères ni code d’état.

Conditions et limites

Ces fonctions écrivent dans la carte BG sélectionnée par le bit 3 de LCDC. La fenêtre de texte est une zone logicielle sur cette carte, et non le plan Window matériel. Gardez VBK à 0 sur CGB pour écrire les numéros de tuiles ; ces appels ne règlent ni attributs de couleur, ni palettes, ni défilement.

Chargez la police et les graphismes du cadre avant de dessiner. Les ID de cadre par défaut vont de 1 à 6, la tuile de remplissage vaut 0 et les chiffres commencent à ASCII 0 (tuile 48). Le signe moins utilise ASCII - (tuile 45). L’exemple fournit six tuiles de cadre et la police du manuel, dont les ID de glyphes correspondent à l’ASCII.

Gardez rectangles et texte dans la carte de 32×32. Le remplissage ne réduit pas la largeur ou la hauteur aux limites de la carte. Une largeur ou une hauteur nulle ne remplit rien ; text_window enregistre néanmoins une zone ouverte, sans intérieur utilisable.

Les fonctions numériques publiques utilisent exactement la largeur du nouveau nombre. Elles n’effacent pas les cases restantes à droite. Écrire 7 sur 12345 au même endroit affiche 72345. Pour n’obtenir que 7, effacez d’abord le champ réservé de cinq cases avec text_clear_rect. Réservez six cases pour un entier signé sur 16 bits.

Les intrinsèques d’écriture vérifient l’état du LCD : éteint, elles écrivent immédiatement ; allumé, elles attendent un mode autorisant l’écriture et encadrent celle-ci par DI/EI. Ce chemin peut réactiver les interruptions au retour ; ne supposez donc pas qu’il préserve leur désactivation. Ici, les exemples et tests octet par octet écrivent avec le LCD éteint.

L’exemple complet inclut text.c une seule fois pour compiler l’implémentation avec le programme. Ne passez pas également lib/text.c comme entrée séparée. Pour personnaliser les constantes de tuiles TEXT_*, définissez-les avant d’inclure rpg.h et l’implémentation ; utilisez les mêmes définitions partout où la bibliothèque est compilée.

Exemple d’utilisation

c
text_print_u8(11,8,255);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La ligne U8 affiche 255 à partir de (11,8), sur exactement trois cases, en bleu sur CGB. Les lignes OVERWRITE et CLEAN montrent pourquoi il faut effacer explicitement le champ lorsqu’on remplace un nombre par un autre plus court.

La vérification compare chaque pixel visible et les 1024 octets de la carte BG dans les deux écrans d’exemple. Des ROM DMG/CGB distinctes testent les 256 valeurs d’octet non signé, les changements de nombre de chiffres et les extrêmes signés, en conservant des points sentinelles à côté de chaque nombre. Les contrôles de placement couvrent les rectangles vides ou étroits, les bords de carte, les octets de tuiles dont la valeur correspond à un code de contrôle et le curseur de fenêtre après des écritures absolues. Il s’agit de tests sur émulateur, pas sur matériel physique.

text_print_u8: DMG
DMG
text_print_u8: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\text_layout.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\text_layout.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:242

Notes de déclaration (texte source)
Print an unsigned byte in decimal using only the required number of cells.

kitaqgb/lib/text.c:233

c
void text_print_u8(u8 x, u8 y, u8 value)
{
    text_print_u16_width(x, y, (u16)value, text_dec_digits_u16((u16)value));
}
text_print_xy

Dessine horizontalement une suite de numéros de tuiles terminée par zéro, à partir d’une position absolue sur la carte du fond. Ce chemin n’applique ni découpage à la fenêtre, ni retour automatique à la ligne, ni interprétation des codes de contrôle, ni délai entre caractères. Le curseur de text_print ne bouge pas.

Syntaxe

c
void text_print_xy(u8 x, u8 y, const u8* str);

Paramètres

x

Colonne de départ, en cases de 8×8 de la carte du fond. Toute la sortie doit tenir dans les colonnes 0–31. Sans défilement du fond, les colonnes visibles sont 0–19.

y

Ligne de départ, de 0 à 31, en cases de 8×8 de la carte du fond. Sans défilement, les lignes 0–17 sont visibles. Un rectangle doit aussi tenir verticalement dans la carte.

str

Pointeur lisible vers des octets de tuiles terminés par 0. Chaque octet sert directement de numéro de tuile. Une chaîne ASCII ne s’affiche comme du texte que si les glyphes correspondants occupent les bons ID de tuiles. La source doit rester mappée et lisible jusqu’au retour. Ces fonctions ne décodent pas l’UTF-8 et ne chargent pas de glyphes. Un texte multioctet nécessite au préalable un encodage défini par le jeu et les tuiles correspondantes.

Valeur renvoyée

Aucune valeur de retour. La fonction écrit les cases de la carte avant de rendre la main ; elle ne renvoie ni nombre de caractères ni code d’état.

Conditions et limites

Ces fonctions écrivent dans la carte BG sélectionnée par le bit 3 de LCDC. La fenêtre de texte est une zone logicielle sur cette carte, et non le plan Window matériel. Gardez VBK à 0 sur CGB pour écrire les numéros de tuiles ; ces appels ne règlent ni attributs de couleur, ni palettes, ni défilement.

Chargez la police et les graphismes du cadre avant de dessiner. Les ID de cadre par défaut vont de 1 à 6, la tuile de remplissage vaut 0 et les chiffres commencent à ASCII 0 (tuile 48). Le signe moins utilise ASCII - (tuile 45). L’exemple fournit six tuiles de cadre et la police du manuel, dont les ID de glyphes correspondent à l’ASCII.

Gardez rectangles et texte dans la carte de 32×32. Le remplissage ne réduit pas la largeur ou la hauteur aux limites de la carte. Une largeur ou une hauteur nulle ne remplit rien ; text_window enregistre néanmoins une zone ouverte, sans intérieur utilisable.

Les intrinsèques d’écriture vérifient l’état du LCD : éteint, elles écrivent immédiatement ; allumé, elles attendent un mode autorisant l’écriture et encadrent celle-ci par DI/EI. Ce chemin peut réactiver les interruptions au retour ; ne supposez donc pas qu’il préserve leur désactivation. Ici, les exemples et tests octet par octet écrivent avec le LCD éteint.

L’exemple complet inclut text.c une seule fois pour compiler l’implémentation avec le programme. Ne passez pas également lib/text.c comme entrée séparée. Pour personnaliser les constantes de tuiles TEXT_*, définissez-les avant d’inclure rpg.h et l’implémentation ; utilisez les mêmes définitions partout où la bibliothèque est compilée.

Exemple d’utilisation

c
text_print_xy(2,3,"HELLO!");

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

HELLO! commence à la tuile (2,3), soit au pixel (16,24), dans le cadre rouge sur CGB. La position est absolue sur la carte BG : ouvrir la zone de texte n’ajoute aucun décalage à x ou y.

La vérification compare chaque pixel visible et les 1024 octets de la carte BG dans les deux écrans d’exemple. Des ROM DMG/CGB distinctes testent les 256 valeurs d’octet non signé, les changements de nombre de chiffres et les extrêmes signés, en conservant des points sentinelles à côté de chaque nombre. Les contrôles de placement couvrent les rectangles vides ou étroits, les bords de carte, les octets de tuiles dont la valeur correspond à un code de contrôle et le curseur de fenêtre après des écritures absolues. Il s’agit de tests sur émulateur, pas sur matériel physique.

text_print_xy: DMG
DMG
text_print_xy: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\text_layout.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\text_layout.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:240

Notes de déclaration (texte source)
Draw a zero-terminated tile string at absolute tile coordinates, without
window clipping, control codes or the windowed printing delay.

kitaqgb/lib/text.c:227

c
void text_print_xy(u8 x, u8 y, const u8* str)
{
    text_draw_string_at(x, y, str);
}
text_set_speed

Définit le nombre d’attentes VBlank après chaque caractère ordinaire écrit par text_print ou text_print_far. Zéro supprime ces attentes par caractère. Ouvrir ou fermer une zone ne réinitialise pas ce réglage. Les commandes WAIT explicites attendent même si la vitesse des caractères vaut zéro.

Syntaxe

c
void text_set_speed(u8 speed);

Paramètres

speed

Nombre d’attentes VBlank après chaque caractère, de 0 à 255. C’est un nombre d’attentes, pas des millisecondes. Ce réglage n’affecte ni text_print_xy, ni les fonctions numériques, ni la liste de choix.

Valeur renvoyée

Aucune valeur de retour. Le dessin et les attentes bloquantes ont lieu avant le retour.

Conditions et limites

Utilisez un rectangle BG valide et chargez d’abord les tuiles de police et de cadre. La zone logicielle utilise la carte BG choisie par le bit 3 de LCDC, sans activer la couche Window matérielle. Sur CGB, utilisez VBK 0 pour les numéros et réglez les couleurs séparément. Les exemples fournissent la police mappée en ASCII et les tuiles de cadre, curseur et indicateur de page. Dialogues et choix utilisent des ID de tuile d’un octet, sans décodage UTF-8. Pour d’autres caractères, fournissez leurs glyphes et encodez le texte avec ces ID, en réservant les octets de contrôle du dialogue.

Ces fonctions sont bloquantes : pendant l’attente, elles n’appellent ni mise à jour du jeu, ni service musical, ni boucle de rendu. LCD éteint, __wait_vblank revient immédiatement ; vitesse des caractères et WAIT ne créent donc pas de délais en trames. Gardez le LCD actif pour le dialogue temporisé et les entrées cadencées par trame. Utilisez une machine à états côté jeu si d’autres tâches doivent avancer pendant la conversation.

Les écritures de tuiles sûres sous-jacentes attendent un mode LCD accessible et encadrent l’écriture par DI/EI. Elles peuvent activer les interruptions au lieu de préserver un état initialement désactivé. Ne les appelez pas depuis un gestionnaire d’interruption et ne comptez pas sur elles pour préserver cet état.

Chaque exemple complet inclut text.c une fois. Compilez avec les répertoires d’inclusion de la bibliothèque et des exemples du manuel ; n’ajoutez pas aussi lib/text.c comme source séparée. L’exemple de flux distant utilise MBC5 et une ROM de 64 Kio pour contenir les données de banque 2.

Exemple d’utilisation

c
text_set_speed(2);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple de flux utilise la vitesse 2 pour les dialogues ordinaires et bancarisés, avec un opérande WAIT de 12. L’image finale montre le texte après ces attentes ; une trace de trames distincte vérifie vitesse 3, cinq attentes explicites et quatre attentes zone fermée. La capture finale seule ne valide pas le timing.

Les tests sur émulateur comparent tout le contenu BG et les quatre images d’exemple. D’autres exécutions couvrent ouverture/fermeture, flux ordinaires et bancarisés, temporisations, pages explicites et automatiques, avances A/B/START, boutons tenus, choix circulaires, listes vides et priorités simultanées. Des points de contrôle avant et après l’entrée scriptée vérifient le blocage réel des pages. Matériel physique et concurrence des interruptions ne sont pas testés.

text_set_speed: DMG
DMG
text_set_speed: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\dialogue_flow.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\dialogue_flow.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:233

Notes de déclaration (texte source)
Set VBlank waits per windowed character; zero prints without character delays.

kitaqgb/lib/text.c:208

c
void text_set_speed(u8 speed)
{
    text_speed = speed;
}
text_window

Dessine une zone de texte encadrée sur la carte de tuiles du fond et en fait la zone active pour l’écriture dans une fenêtre. Cet alias de text_open ramène le curseur à la première case intérieure, redessine le cadre et efface l’intérieur. Le délai actuel entre caractères est conservé.

Syntaxe

c
void text_window(u8 x, u8 y, u8 w, u8 h);

Paramètres

x

Colonne de départ, en cases de 8×8 de la carte du fond. Toute la sortie doit tenir dans les colonnes 0–31. Sans défilement du fond, les colonnes visibles sont 0–19.

y

Ligne de départ, de 0 à 31, en cases de 8×8 de la carte du fond. Sans défilement, les lignes 0–17 sont visibles. Un rectangle doit aussi tenir verticalement dans la carte.

w

Largeur en cases. Pour text_window, elle comprend les deux colonnes du cadre, laissant max(w−2, 0) colonnes intérieures. Pour text_clear_rect, c’est le nombre de cases à remplir sur chaque ligne.

h

Hauteur en cases. Pour text_window, elle comprend les bords supérieur et inférieur, laissant max(h−2, 0) lignes intérieures. Pour text_clear_rect, c’est le nombre de lignes à remplir.

Valeur renvoyée

Aucune valeur de retour. La fonction écrit les cases de la carte avant de rendre la main ; elle ne renvoie ni nombre de caractères ni code d’état.

Conditions et limites

Ces fonctions écrivent dans la carte BG sélectionnée par le bit 3 de LCDC. La fenêtre de texte est une zone logicielle sur cette carte, et non le plan Window matériel. Gardez VBK à 0 sur CGB pour écrire les numéros de tuiles ; ces appels ne règlent ni attributs de couleur, ni palettes, ni défilement.

Chargez la police et les graphismes du cadre avant de dessiner. Les ID de cadre par défaut vont de 1 à 6, la tuile de remplissage vaut 0 et les chiffres commencent à ASCII 0 (tuile 48). Le signe moins utilise ASCII - (tuile 45). L’exemple fournit six tuiles de cadre et la police du manuel, dont les ID de glyphes correspondent à l’ASCII.

Gardez rectangles et texte dans la carte de 32×32. Le remplissage ne réduit pas la largeur ou la hauteur aux limites de la carte. Une largeur ou une hauteur nulle ne remplit rien ; text_window enregistre néanmoins une zone ouverte, sans intérieur utilisable.

Les intrinsèques d’écriture vérifient l’état du LCD : éteint, elles écrivent immédiatement ; allumé, elles attendent un mode autorisant l’écriture et encadrent celle-ci par DI/EI. Ce chemin peut réactiver les interruptions au retour ; ne supposez donc pas qu’il préserve leur désactivation. Ici, les exemples et tests octet par octet écrivent avec le LCD éteint.

L’exemple complet inclut text.c une seule fois pour compiler l’implémentation avec le programme. Ne passez pas également lib/text.c comme entrée séparée. Pour personnaliser les constantes de tuiles TEXT_*, définissez-les avant d’inclure rpg.h et l’implémentation ; utilisez les mêmes définitions partout où la bibliothèque est compilée.

Exemple d’utilisation

c
text_window(1,2,18,5);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple ouvre une zone de 18×5 cases en (1,2), avec un intérieur de 16×3. Le cadre fourni a des traits d’un pixel ; ses lignes extérieures visibles s’étendent de x=11 à 147 et de y=19 à 51 pixels. Il est rouge sur CGB et noir sur DMG.

La vérification compare chaque pixel visible et les 1024 octets de la carte BG dans les deux écrans d’exemple. Des ROM DMG/CGB distinctes testent les 256 valeurs d’octet non signé, les changements de nombre de chiffres et les extrêmes signés, en conservant des points sentinelles à côté de chaque nombre. Les contrôles de placement couvrent les rectangles vides ou étroits, les bords de carte, les octets de tuiles dont la valeur correspond à un code de contrôle et le curseur de fenêtre après des écritures absolues. Il s’agit de tests sur émulateur, pas sur matériel physique.

text_window: DMG
DMG
text_window: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\text_layout.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\text_layout.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:235

Notes de déclaration (texte source)
Open and redraw a window using the same tile-space arguments as text_open.

kitaqgb/lib/text.c:214

c
void text_window(u8 x, u8 y, u8 w, u8 h)
{
    text_open(x, y, w, h);
}
unit_attack_range

Marque les cases dont la distance de Manhattan est comprise entre atk_min et atk_max, bornes incluses.

Syntaxe

c
u8 unit_attack_range(unit_t* u, u8* out_mask);

Paramètres

u

unit_t valide : position en cases, move en pas, intervalle atk_min/atk_max inclusif, ainsi que hp et acted pour déterminer si l’action est possible.

out_mask

width*height octets accessibles en écriture ; reçoit zéro ou un par case.

Valeur renvoyée

Renvoie 1 si la carte est disponible, 0 si ses dimensions sont nulles.

Conditions et limites

Les coordonnées désignent les cases de la carte active : 8×8 pixels pour les tuiles ordinaires, 16×16 pour les métatuiles.

Ignore les obstacles, la ligne de vue et les unités alliées. Limitez les distances évaluées à 255. Si la portée minimale dépasse la maximale, toutes les cases valent zéro.

Exemple d’utilisation

c
result[46]=unit_attack_range(&hero,mask);result[47]=mask[12];result[48]=mask[14];

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La grille de gauche montre les coûts de déplacement en trois pas au plus ; celle de droite, un plus court chemin de S à G. Des astérisques verts tracent neuf pas autour d’un mur rouge de trois cases ; les chiffres bleus donnent les coûts. Le DMG utilise la même disposition en noir. Les contrôles RAM montrent aussi que le masque d’attaque ignore les murs.

unit_attack_range: DMG
DMG
unit_attack_range: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_map_path.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_map_path.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:352

Notes de déclaration (texte source)
Mark cells whose Manhattan distance falls within the inclusive attack range.
This geometric mask does not test obstacles, line of sight or other units.

kitaqgb/lib/slg_unit.c:38

c
u8 unit_attack_range(unit_t* u, u8* out_mask)
{
    u8 w = map_current_width();
    u8 h = map_current_height();
    u8 y;

    if (w == 0 || h == 0) return 0;

    __memset(out_mask, 0, (u16)((u16)w * (u16)h));
    y = 0;
    while (y < h) {
        u8 x = 0;
        while (x < w) {
            u8 dist = __manhattan(u->x, u->y, x, y);
            if (dist >= u->atk_min && dist <= u->atk_max) {
                out_mask[__map_index(x, y, w)] = 1;
            }
            x++;
        }
        y++;
    }
    return 1;
}
unit_can_act

Vérifie qu’une unité a encore des PV et n’a pas agi.

Syntaxe

c
u8 unit_can_act(const unit_t* u);

Paramètres

u

unit_t valide : position en cases, move en pas, intervalle atk_min/atk_max inclusif, ainsi que hp et acted pour déterminer si l’action est possible.

Valeur renvoyée

Renvoie 1 si hp est non nul et acted vaut zéro, sinon 0. Ne modifie pas l’unité.

Exemple d’utilisation

c
result[11]=unit_can_act(&hero);hero.acted=1;result[12]=unit_can_act(&hero);hero.acted=0;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La grille de gauche montre les coûts de déplacement en trois pas au plus ; celle de droite, un plus court chemin de S à G. Des astérisques verts tracent neuf pas autour d’un mur rouge de trois cases ; les chiffres bleus donnent les coûts. Le DMG utilise la même disposition en noir. Les contrôles RAM montrent aussi que le masque d’attaque ignore les murs.

unit_can_act: DMG
DMG
unit_can_act: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_map_path.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_map_path.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:355

Notes de déclaration (texte source)
A unit can act only while HP is nonzero and its acted flag is clear.
The unit pointer must refer to a valid record.

kitaqgb/lib/slg_unit.c:5

c
u8 unit_can_act(const unit_t* u)
{
    if (u->hp == 0) return 0;
    if (u->acted != 0) return 0;
    return 1;
}
unit_move_range

Construit le masque des cases atteignables dans la limite de déplacement de l’unité.

Syntaxe

c
u8 unit_move_range(unit_t* u, u8* out_mask);

Paramètres

u

unit_t valide : position en cases, move en pas, intervalle atk_min/atk_max inclusif, ainsi que hp et acted pour déterminer si l’action est possible.

out_mask

width*height octets accessibles en écriture ; reçoit zéro ou un par case.

Valeur renvoyée

Renvoie 1 si la carte est disponible, 0 si ses dimensions sont nulles. L’origine de l’unité doit être dans les limites.

Conditions et limites

Les coordonnées désignent les cases de la carte active : 8×8 pixels pour les tuiles ordinaires, 16×16 pour les métatuiles.

La recherche utilise environ 4 Kio d’espace de travail partagé non réentrant. Limitez les cartes à 1024 cases et les distances explorées à 254. La distance 0xFF signifie « non atteint » : un trajet de 255 pas n’est donc pas représentable. Les sorties de coût et de masque nécessitent width*height octets accessibles en écriture.

L’origine est marquée comme atteignable même si elle est bloquée. Les PV, acted et les autres unités n’influencent pas le masque de déplacement.

Exemple d’utilisation

c
result[43]=unit_move_range(&hero,mask);result[44]=mask[12];result[45]=mask[14];

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La grille de gauche montre les coûts de déplacement en trois pas au plus ; celle de droite, un plus court chemin de S à G. Des astérisques verts tracent neuf pas autour d’un mur rouge de trois cases ; les chiffres bleus donnent les coûts. Le DMG utilise la même disposition en noir. Les contrôles RAM montrent aussi que le masque d’attaque ignore les murs.

unit_move_range: DMG
DMG
unit_move_range: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch3_map_path.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch3_map_path.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k --ramsize=none
Implémentation et source

kitaqgb/lib/rpg.h:349

Notes de déclaration (texte source)
Build movement costs, then convert reachable cells to one and unreachable
0xFF cells to zero. The caller provides one output byte per current-map cell
and a valid unit origin; path-search workspace limits also apply.

kitaqgb/lib/slg_unit.c:15

c
u8 unit_move_range(unit_t* u, u8* out_mask)
{
    u8 w = map_current_width();
    u8 h = map_current_height();
    u16 total;
    u16 i;

    if (w == 0 || h == 0) return 0;

    // A valid origin is required: the fill leaves storage unchanged on invalid origins, but this loop still converts it.
    range_fill_move(u->x, u->y, u->move, out_mask);
    total = (u16)((u16)w * (u16)h);
    i = 0;
    while (i < total) {
        out_mask[i] = (u8)((out_mask[i] == 0xFF) ? 0 : 1);
        i++;
    }
    return 1;
}
weighted_choice

Choisit un indice dans une liste de poids relatifs sur un octet. La fonction additionne les poids, réduit un tirage rng16 modulo ce total, puis trouve le premier intervalle cumulé contenant le résultat. Avec [1, 3, 6], les indices 0, 1 et 2 possèdent les intervalles 0, 1–3 et 4–9.

Syntaxe

c
u8 weighted_choice(const u8* weights, u8 count);

Paramètres

weights

Pointeur vers count poids u8 lisibles. Le tableau n’est pas modifié. Les poids nuls sont ignorés si le total est positif. Avec count == 0, le pointeur n’est pas lu et peut être nul ; sinon, fournissez un tableau valide.

count

Nombre de poids, de 0 à 255. Au maximum, 255 poids de 255 totalisent 65025, ce qui tient dans l’accumulateur u16. La fonction parcourt d’abord la liste pour sommer les poids, puis la reparcourt jusqu’à l’intervalle choisi.

Valeur renvoyée

Si le total est positif, un indice de 0 à count−1 après deux tirages d’octet. Si count ou tous les poids sont nuls, renvoie zéro sans tirage. Ce repli est indiscernable d’une sélection valide de l’indice 0 ; vérifiez donc vous-même les listes vides ou entièrement nulles si cette distinction importe.

Conditions et limites

Les poids définissent des tailles d’intervalles relatives, pas des pourcentages observés garantis. La distribution de rng16 et la réduction modulo le total influencent toutes deux les fréquences réelles. Un total positif consomme toujours deux tirages d’octet, même si un seul élément a un poids non nul.

Ces appels partagent un état persistant. La reproduction exige la même cible, la même graine et le même ordre d’appels, y compris ceux des autres fonctions auxiliaires. Gardez réglage de graine et tirages dans un même contexte d’exécution ; ces vérifications ne prouvent pas la sûreté d’un accès concurrent depuis une interruption.

GB et FC utilisent des algorithmes différents et ne garantissent pas la même suite avec la même graine. Ce sont des générateurs déterministes pour le jeu, pas des sources d’aléa cryptographique. Les tests vérifient le comportement de l’implémentation, pas sa qualité statistique ni sa période.

Incluez rpg.h et compilez lib/rng.c avec le jeu pour utiliser les fonctions de bibliothèque. Les intrinsèques __rng_seed et __rng8 sont émises par le compilateur ; un programme limité à ces deux fonctions n’a pas besoin d’objet rng.c.

Exemple d’utilisation

c
weights[0]=1;weights[1]=3;weights[2]=6;
rng_seed(0x1234);
chosen=weighted_choice(weights,3); // 546 % 10 = 6 selects index 2.
empty=weighted_choice((const u8*)0,0); // No items: 0 is a fallback, not a chosen item.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple donne les poids 1, 3 et 6 à trois éléments. Le mot 546 issu de la graine donne un reste de 6, dans l’intervalle 4–9 de l’indice 2 ; WEIGHT INDEX affiche 00002. EMPTY LIST affiche 00000 comme valeur de repli d’une liste vide, pas comme sélection réussie de l’élément 0.

Le programme complet affiche les résultats décimaux sur fond blanc : texte noir sur DMG, bleu sur CGB. FAILED doit indiquer 00000. Les images montrent la sortie réelle de cet exemple dans l’émulateur.

La validation a comparé, pour chaque cas, 32 sorties et huit tirages d’octet suivants à un modèle hôte indépendant : 93 cas GB et 18 cas FC, avec graines constantes ou calculées à l’exécution et limites GB de plage, chance et poids. Les écrans pédagogiques ont été contrôlés après 240 images émulées. Le matériel réel et la qualité statistique n’ont pas été testés.

weighted_choice: DMG
DMG
weighted_choice: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\rng_choices.c .\kitaqgb\lib\rng.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\rng_choices.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/rpg.h:203

Notes de déclaration (texte source)
Select an index from cumulative byte weights using a 16-bit random draw.
A zero total, including an empty list, returns zero; callers must distinguish
that case from a valid index. Modulo reduction can introduce a small bias.

kitaqgb/lib/rng.c:61

c
u8 weighted_choice(const u8* weights, u8 count)
{
    u8 i;
    u16 total;
    u16 pick;
    u16 acc;

    // At most 255 byte weights sum to 65025, so this accumulator fits u16.
    // A nonempty list requires count readable weight bytes.
    total = 0;
    i = 0;
    while (i < count) {
        total = (u16)(total + (u16)weights[i]);
        i++;
    }

    if (total == 0) return 0;

    pick = (u16)(rng16() % total);
    acc = 0;
    i = 0;
    while (i < count) {
        acc = (u16)(acc + (u16)weights[i]);
        if (pick < acc) return i;
        i++;
    }

    return (u8)(count - 1);
}

scene.h — Enregistrement, changement et mise à jour des scènes

Appelle les gestionnaires enter, update, draw et exit d’une table de scènes pour passer entre des écrans tels que le titre et la partie.

scene_change

Quitte la scène active, s’il y en a une, puis entre dans la scène demandée.

Syntaxe

c
void scene_change(u8 scene_id);

Paramètres

scene_id

Indice de la scène à activer, de 0 à count−1.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Les identifiants hors limites sont ignorés. Une transition valide exécute exit, enregistre le nouvel identifiant et le drapeau de transition, puis exécute enter. Choisir le même identifiant exécute tout de même exit et enter. La table de scènes appartient à l’appelant. Gardez cette table et les cibles de ses pointeurs de fonction ordinaires valides pendant toute son utilisation. Les fonctions de rappel nulles sont ignorées. Ne déclenchez pas de transition récursive et ne remplacez pas la table depuis les fonctions de rappel enter ou exit.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
scene_change(0);scene_change(9);result[11]=events;result[12]=scene_was_changed();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme active la scène 0, ignore l’identifiant invalide 9, effectue la transition 0→1 puis une nouvelle entrée 1→1, et vérifie l’ordre des fonctions de rappel.

scene_change: DMG
DMG
scene_change: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scene.h:20

Notes de déclaration (texte source)
Ignore invalid IDs; otherwise exit the current scene and enter the requested one.
Selecting the current ID still performs exit/enter. Callbacks run synchronously.

kitaqgb/lib/scene.c:27

c
void scene_change(u8 scene_id)
{
    SceneFunc fn;

    if (scene_id >= scene_count) return;

    // Exit/enter handlers must not recursively change scenes or replace this shared table.
    if (scene_has_current != 0) {
        fn = scene_table[(__safe_index u8)scene_current].exit;
        if (fn != 0) fn();
    }

    scene_current = scene_id;
    scene_has_current = 1;
    scene_changed = 1;

    fn = scene_table[(__safe_index u8)scene_current].enter;
    if (fn != 0) fn();
}
scene_draw

Appelle une fois la fonction de rappel draw de la scène active.

Syntaxe

c
void scene_draw();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Sans scène active ou avec une fonction de rappel draw nulle, cet appel est sans effet. Il n’efface pas le drapeau de transition. Organisez les transferts d’affichage et la synchronisation des trames dans la fonction de rappel ou dans la boucle de jeu qui l’entoure. La table de scènes appartient à l’appelant. Gardez cette table et les cibles de ses pointeurs de fonction ordinaires valides pendant toute son utilisation. Les fonctions de rappel nulles sont ignorées. Ne déclenchez pas de transition récursive et ne remplacez pas la table depuis les fonctions de rappel enter ou exit.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
scene_draw();result[15]=events;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La séquence contient l’événement 12 produit par draw dans la scène 0 et l’événement 22 produit par draw dans la scène 1.

scene_draw: DMG
DMG
scene_draw: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scene.h:25

Notes de déclaration (texte source)
Call the active scene's draw handler if one exists; no current scene is a no-op.

kitaqgb/lib/scene.c:60

c
void scene_draw()
{
    SceneFunc fn;

    if (scene_has_current == 0) return;
    fn = scene_table[(__safe_index u8)scene_current].draw;
    if (fn != 0) fn();
}
scene_get_current

Lit l’identifiant de scène courant enregistré.

Syntaxe

c
u8 scene_get_current();

Valeur renvoyée

Renvoie l’identifiant enregistré sur huit bits ; l’initialisation le met également à zéro.

Conditions et limites

Une valeur de retour de zéro ne suffit pas à prouver que la scène 0 est active. Suivez séparément si le premier appel à scene_change() a eu lieu après l’initialisation.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
result[16]=scene_get_current();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple lit zéro après l’activation de la scène 0, puis un après le passage à la scène 1.

scene_get_current: DMG
DMG
scene_get_current: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scene.h:27

Notes de déclaration (texte source)
Return the stored scene ID; zero is also returned before the first transition.

kitaqgb/lib/scene.c:70

c
u8 scene_get_current()
{
    return scene_current;
}
scene_init

Enregistre une table de scènes sans en activer aucune.

Syntaxe

c
void scene_init(const SceneDef* scenes, u8 count);

Paramètres

scenes

Tableau d’entrées SceneDef contenant les fonctions de rappel enter, update, draw et exit.

count

Nombre d’entrées ; zéro signifie qu’aucun identifiant de scène n’est valide.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Remet l’identifiant enregistré et le drapeau de transition à zéro. N’appelle pas enter ; utilisez scene_change() pour activer une scène. La table de scènes appartient à l’appelant. Gardez cette table et les cibles de ses pointeurs de fonction ordinaires valides pendant toute son utilisation. Les fonctions de rappel nulles sont ignorées. Ne déclenchez pas de transition récursive et ne remplacez pas la table depuis les fonctions de rappel enter ou exit.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
scene_init(scenes,2);scene_update();scene_draw();result[9]=events;result[10]=scene_was_changed();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple enregistre deux scènes et vérifie que les appels à update et draw avant activation ne produisent aucun événement.

scene_init: DMG
DMG
scene_init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scene.h:15

Notes de déclaration (texte source)
Attach the caller-owned scene table and clear current-scene state without invoking callbacks.

kitaqgb/lib/scene.c:10

c
void scene_init(const SceneDef* scenes, u8 count)
{
    scene_table = scenes;
    scene_count = count;
    scene_current = 0;
    scene_changed = 0;
    scene_has_current = 0;
}
scene_set_table

Remplace la table de scènes et désactive toute scène active.

Syntaxe

c
void scene_set_table(const SceneDef* scenes, u8 count);

Paramètres

scenes

Tableau d’entrées SceneDef contenant les fonctions de rappel enter, update, draw et exit.

count

Nombre d’entrées ; zéro signifie qu’aucun identifiant de scène n’est valide.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Réinitialise l’état comme scene_init(), sans appeler ni l’ancienne fonction de rappel exit ni une nouvelle fonction de rappel enter. La table de scènes appartient à l’appelant. Gardez cette table et les cibles de ses pointeurs de fonction ordinaires valides pendant toute son utilisation. Les fonctions de rappel nulles sont ignorées. Ne déclenchez pas de transition récursive et ne remplacez pas la table depuis les fonctions de rappel enter ou exit.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
scene_set_table(scenes,2);result[23]=events;result[24]=scene_was_changed();scene_draw();result[25]=events;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le remplacement de la table après neuf événements laisse le compteur à neuf, remet le drapeau de transition à zéro et rend l’appel suivant à draw sans effet.

scene_set_table: DMG
DMG
scene_set_table: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scene.h:17

Notes de déclaration (texte source)
Replace the table by resetting scene state; this does not call the old scene's exit handler.

kitaqgb/lib/scene.c:20

c
void scene_set_table(const SceneDef* scenes, u8 count)
{
    scene_init(scenes, count);
}
scene_update

Appelle une fois la fonction de rappel update de la scène active.

Syntaxe

c
void scene_update();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Sans scène active, cet appel est sans effet. Sinon, il efface le drapeau de transition avant l’appel de la fonction de rappel : une transition effectuée dans update reste ainsi détectable après son retour. La table de scènes appartient à l’appelant. Gardez cette table et les cibles de ses pointeurs de fonction ordinaires valides pendant toute son utilisation. Les fonctions de rappel nulles sont ignorées. Ne déclenchez pas de transition récursive et ne remplacez pas la table depuis les fonctions de rappel enter ou exit.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
scene_update();result[13]=events;result[14]=scene_was_changed();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La fonction update de la scène 0 enregistre l’événement 11. Le drapeau de transition, auparavant à un, passe à zéro après cette mise à jour ordinaire.

scene_update: DMG
DMG
scene_update: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scene.h:23

Notes de déclaration (texte source)
Clear the change flag before calling the active scene's update handler, so a
transition made during that handler is visible afterward.

kitaqgb/lib/scene.c:49

c
void scene_update()
{
    SceneFunc fn;

    if (scene_has_current == 0) return;
    scene_changed = 0;
    fn = scene_table[(__safe_index u8)scene_current].update;
    if (fn != 0) fn();
}
scene_was_changed

Indique si une transition de scène est actuellement enregistrée.

Syntaxe

c
u8 scene_was_changed();

Valeur renvoyée

Renvoie 1 si le drapeau de transition est activé, sinon 0.

Conditions et limites

La lecture n’efface pas le drapeau. L’initialisation, le remplacement de la table et le début d’une mise à jour de scène active l’effacent. Un identifiant de scène invalide ne le modifie pas.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
result[17]=scene_was_changed();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Les vérifications attendent un juste après une transition, zéro après une mise à jour ordinaire et zéro après le remplacement de la table.

scene_was_changed: DMG
DMG
scene_was_changed: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scene.h:29

Notes de déclaration (texte source)
Read the transition flag, which is cleared at the start of an active scene update.

kitaqgb/lib/scene.c:76

c
u8 scene_was_changed()
{
    return scene_changed;
}

scroll.h — Arrière-plan, fenêtre et défilement fractionné

Contrôle le défilement immédiat ou en tampon du fond et de la fenêtre, ainsi que jusqu’à huit coupures raster. Distinguez les valeurs courantes suivies par les accesseurs, les registres matériels réels et les valeurs en attente.

Scroll_BgAdd

Ajoute des déplacements signés aux coordonnées suivies du fond et les applique immédiatement.

Syntaxe

c
void Scroll_BgAdd(s8 dx, s8 dy);

Paramètres

dx

Déplacement horizontal signé en pixels, de −128 à 127.

dy

Déplacement vertical signé en pixels, de −128 à 127.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Aucune attente n’est effectuée. Les réglages et additions immédiats synchronisent la paire de coordonnées en attente concernée avec les valeurs courantes et effacent son drapeau de modification. Même le réglage immédiat d’un seul axe annule la valeur en attente de l’autre axe de la même paire. Les résultats rebouclent modulo 256. Les additions partent des valeurs courantes suivies, pas des valeurs en attente ni des valeurs temporaires des registres raster. Cette fonction enveloppe __scroll_bg_add.

Exemple d’utilisation

c
Scroll_BgAdd(-20,3);result[22]=M_SCX;result[23]=M_SCY;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_BgAdd: DMG
DMG
Scroll_BgAdd: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_BgAdd: DMG
DMG
Scroll_BgAdd: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:73

Notes de déclaration (texte source)
Apply signed deltas to the byte-sized background-scroll coordinates.

kitaqgb/lib/scroll.c:41

c
void Scroll_BgAdd(s8 dx, s8 dy) { __scroll_bg_add(dx, dy); }
Scroll_Flush

Applique les coordonnées modifiées du fond et de la fenêtre à l’état suivi et au matériel, puis efface leurs drapeaux d’attente.

Syntaxe

c
void Scroll_Flush();

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Une paire de coordonnées inchangée est laissée intacte. Aucune interruption n’est masquée et aucune attente VBlank n’est effectuée ; l’appelant doit prévoir le moment approprié. Cette fonction enveloppe __scroll_flush.

Exemple d’utilisation

c
Scroll_Flush();result[18]=M_SCX;result[19]=M_SCY;result[20]=M_WX;result[21]=M_WY;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_Flush: DMG
DMG
Scroll_Flush: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_Flush: DMG
DMG
Scroll_Flush: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:70

Notes de déclaration (texte source)
Apply the buffered scroll/window state through the compiler runtime.

kitaqgb/lib/scroll.c:38

c
void Scroll_Flush() { __scroll_flush(); }
Scroll_GetBgX

Lit la valeur courante suivie du défilement horizontal du fond.

Syntaxe

c
u8 Scroll_GetBgX();

Valeur renvoyée

Renvoie l’octet courant suivi, de 0 à 255. WX comprend son décalage matériel de sept pixels.

Conditions et limites

Ce n’est pas une lecture de registre matériel. Les valeurs en tampon encore en attente, les écritures directes dans les registres et les valeurs temporaires des coupures raster en sont exclues. Cette fonction enveloppe __scroll_bg_x_get.

Exemple d’utilisation

c
result[6]=Scroll_GetBgX();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_GetBgX: DMG
DMG
Scroll_GetBgX: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_GetBgX: DMG
DMG
Scroll_GetBgX: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:50

Notes de déclaration (texte source)
Read the tracked current background X; this is not a direct SCX register read.

kitaqgb/lib/scroll.c:18

c
u8 Scroll_GetBgX() { return __scroll_bg_x_get(); }
Scroll_GetBgY

Lit la valeur courante suivie du défilement vertical du fond.

Syntaxe

c
u8 Scroll_GetBgY();

Valeur renvoyée

Renvoie l’octet courant suivi, de 0 à 255. WX comprend son décalage matériel de sept pixels.

Conditions et limites

Ce n’est pas une lecture de registre matériel. Les valeurs en tampon encore en attente, les écritures directes dans les registres et les valeurs temporaires des coupures raster en sont exclues. Cette fonction enveloppe __scroll_bg_y_get.

Exemple d’utilisation

c
result[7]=Scroll_GetBgY();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_GetBgY: DMG
DMG
Scroll_GetBgY: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_GetBgY: DMG
DMG
Scroll_GetBgY: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:52

Notes de déclaration (texte source)
Read the tracked current background Y; pending and raster-only values are excluded.

kitaqgb/lib/scroll.c:20

c
u8 Scroll_GetBgY() { return __scroll_bg_y_get(); }
Scroll_GetWindowX

Lit la valeur WX courante suivie de la fenêtre.

Syntaxe

c
u8 Scroll_GetWindowX();

Valeur renvoyée

Renvoie l’octet courant suivi, de 0 à 255. WX comprend son décalage matériel de sept pixels.

Conditions et limites

Ce n’est pas une lecture de registre matériel. Les valeurs en tampon encore en attente, les écritures directes dans les registres et les valeurs temporaires des coupures raster en sont exclues. Cette fonction enveloppe __scroll_win_x_get.

Exemple d’utilisation

c
result[12]=Scroll_GetWindowX();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_GetWindowX: DMG
DMG
Scroll_GetWindowX: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_GetWindowX: DMG
DMG
Scroll_GetWindowX: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:61

Notes de déclaration (texte source)
Read tracked current WX, including its seven-pixel offset; not a live hardware read.

kitaqgb/lib/scroll.c:29

c
u8 Scroll_GetWindowX() { return __scroll_win_x_get(); }
Scroll_GetWindowY

Lit la valeur WY courante suivie de la fenêtre.

Syntaxe

c
u8 Scroll_GetWindowY();

Valeur renvoyée

Renvoie l’octet courant suivi, de 0 à 255. WX comprend son décalage matériel de sept pixels.

Conditions et limites

Ce n’est pas une lecture de registre matériel. Les valeurs en tampon encore en attente, les écritures directes dans les registres et les valeurs temporaires des coupures raster en sont exclues. Cette fonction enveloppe __scroll_win_y_get.

Exemple d’utilisation

c
result[13]=Scroll_GetWindowY();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_GetWindowY: DMG
DMG
Scroll_GetWindowY: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_GetWindowY: DMG
DMG
Scroll_GetWindowY: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:63

Notes de déclaration (texte source)
Read tracked current WY; pending and raster-only values are excluded.

kitaqgb/lib/scroll.c:31

c
u8 Scroll_GetWindowY() { return __scroll_win_y_get(); }
Scroll_Init

Initialise le défilement du fond à (0,0) et la position de la fenêtre à WX=7, WY=0.

Syntaxe

c
void Scroll_Init();

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Synchronise les coordonnées courantes et en attente ; ne réinitialise ni la visibilité de la fenêtre ni la table de coupures.

Exemple d’utilisation

c
Scroll_Init();result[0]=M_SCX;result[1]=M_SCY;result[2]=M_WX;result[3]=M_WY;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_Init: DMG
DMG
Scroll_Init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_Init: DMG
DMG
Scroll_Init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:42

Notes de déclaration (texte source)
Reset background scroll to zero and place the window at screen origin
using hardware WX=7 and WY=0.

kitaqgb/lib/scroll.c:5

c
void Scroll_Init()
{
    __scroll_bg_set(0, 0);
    __scroll_win_set(7, 0);
}
Scroll_SetBg

Règle immédiatement les deux coordonnées de défilement du fond.

Syntaxe

c
void Scroll_SetBg(u8 scx, u8 scy);

Paramètres

scx

Défilement horizontal du fond, de 0 à 255 pixels ; l’augmenter déplace le fond vers la gauche.

scy

Défilement vertical du fond, de 0 à 255 pixels ; l’augmenter déplace le fond vers le haut.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Enveloppe __scroll_bg_set : synchronise les valeurs courantes, en attente et matérielles, puis efface le drapeau de modification BG, sans attendre VBlank.

Exemple d’utilisation

c
Scroll_SetBg(8,16);result[28]=M_SCX;result[29]=M_SCY;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_SetBg: DMG
DMG
Scroll_SetBg: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_SetBg: DMG
DMG
Scroll_SetBg: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:44

Notes de déclaration (texte source)
Write both hardware background-scroll bytes immediately.

kitaqgb/lib/scroll.c:12

c
void Scroll_SetBg(u8 scx, u8 scy) { __scroll_bg_set(scx, scy); }
Scroll_SetBgBuffered

Prépare les deux coordonnées de défilement du fond pour une application ultérieure.

Syntaxe

c
void Scroll_SetBgBuffered(u8 scx, u8 scy);

Paramètres

scx

Défilement horizontal du fond, de 0 à 255 pixels ; l’augmenter déplace le fond vers la gauche.

scy

Défilement vertical du fond, de 0 à 255 pixels ; l’augmenter déplace le fond vers le haut.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Ne modifie ni les valeurs courantes suivies ni les registres. Appliquez-les avec __scroll_flush ou Scroll_Flush ; la mise en attente n’attend pas VBlank. Cette fonction enveloppe __scroll_bg_set_buffered.

Exemple d’utilisation

c
Scroll_SetBgBuffered(16,24);result[14]=M_SCX;result[15]=Scroll_GetBgX();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_SetBgBuffered: DMG
DMG
Scroll_SetBgBuffered: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_SetBgBuffered: DMG
DMG
Scroll_SetBgBuffered: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:66

Notes de déclaration (texte source)
Stage background-scroll values in the intrinsic buffer for a later flush.

kitaqgb/lib/scroll.c:34

c
void Scroll_SetBgBuffered(u8 scx, u8 scy) { __scroll_bg_set_buffered(scx, scy); }
Scroll_SetBgX

Règle immédiatement le défilement horizontal du fond.

Syntaxe

c
void Scroll_SetBgX(u8 scx);

Paramètres

scx

Défilement horizontal du fond, de 0 à 255 pixels ; l’augmenter déplace le fond vers la gauche.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Aucune attente n’est effectuée. Les réglages et additions immédiats synchronisent la paire de coordonnées en attente concernée avec les valeurs courantes et effacent son drapeau de modification. Même le réglage immédiat d’un seul axe annule la valeur en attente de l’autre axe de la même paire. Cette fonction enveloppe __scroll_bg_x_set.

Exemple d’utilisation

c
Scroll_SetBgX(250);result[4]=M_SCX;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_SetBgX: DMG
DMG
Scroll_SetBgX: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_SetBgX: DMG
DMG
Scroll_SetBgX: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:46

Notes de déclaration (texte source)
Write horizontal background scroll while leaving vertical scroll unchanged.

kitaqgb/lib/scroll.c:14

c
void Scroll_SetBgX(u8 scx) { __scroll_bg_x_set(scx); }
Scroll_SetBgY

Règle immédiatement le défilement vertical du fond.

Syntaxe

c
void Scroll_SetBgY(u8 scy);

Paramètres

scy

Défilement vertical du fond, de 0 à 255 pixels ; l’augmenter déplace le fond vers le haut.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Aucune attente n’est effectuée. Les réglages et additions immédiats synchronisent la paire de coordonnées en attente concernée avec les valeurs courantes et effacent son drapeau de modification. Même le réglage immédiat d’un seul axe annule la valeur en attente de l’autre axe de la même paire. Cette fonction enveloppe __scroll_bg_y_set.

Exemple d’utilisation

c
Scroll_SetBgY(2);result[5]=M_SCY;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_SetBgY: DMG
DMG
Scroll_SetBgY: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_SetBgY: DMG
DMG
Scroll_SetBgY: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:48

Notes de déclaration (texte source)
Write vertical background scroll while leaving horizontal scroll unchanged.

kitaqgb/lib/scroll.c:16

c
void Scroll_SetBgY(u8 scy) { __scroll_bg_y_set(scy); }
Scroll_SetWindow

Règle immédiatement WX et WY de la fenêtre.

Syntaxe

c
void Scroll_SetWindow(u8 wx, u8 wy);

Paramètres

wx

Octet WX brut, de 0 à 255 : ajoutez 7 au X voulu à l’écran ; le bord gauche utilise 7.

wy

Haut de la fenêtre en pixels Y de l’écran, de 0 à 255 ; les lignes visibles vont de 0 à 143.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Aucune attente n’est effectuée. Les réglages et additions immédiats synchronisent la paire de coordonnées en attente concernée avec les valeurs courantes et effacent son drapeau de modification. Même le réglage immédiat d’un seul axe annule la valeur en attente de l’autre axe de la même paire. Cette fonction enveloppe __scroll_win_set.

Exemple d’utilisation

c
Scroll_SetWindow(15,8);result[8]=M_WX;result[9]=M_WY;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_SetWindow: DMG
DMG
Scroll_SetWindow: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_SetWindow: DMG
DMG
Scroll_SetWindow: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:55

Notes de déclaration (texte source)
Write raw hardware WX/WY values; callers add seven to a screen-space window X.

kitaqgb/lib/scroll.c:23

c
void Scroll_SetWindow(u8 wx, u8 wy) { __scroll_win_set(wx, wy); }
Scroll_SetWindowBuffered

Prépare les deux coordonnées de la fenêtre pour une application ultérieure.

Syntaxe

c
void Scroll_SetWindowBuffered(u8 wx, u8 wy);

Paramètres

wx

Octet WX brut, de 0 à 255 : ajoutez 7 au X voulu à l’écran ; le bord gauche utilise 7.

wy

Haut de la fenêtre en pixels Y de l’écran, de 0 à 255 ; les lignes visibles vont de 0 à 143.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Ne modifie ni les valeurs courantes suivies ni les registres. Appliquez-les avec __scroll_flush ou Scroll_Flush ; la mise en attente n’attend pas VBlank. Cette fonction enveloppe __scroll_win_set_buffered.

Exemple d’utilisation

c
Scroll_SetWindowBuffered(39,32);result[16]=M_WX;result[17]=Scroll_GetWindowX();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_SetWindowBuffered: DMG
DMG
Scroll_SetWindowBuffered: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_SetWindowBuffered: DMG
DMG
Scroll_SetWindowBuffered: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:68

Notes de déclaration (texte source)
Stage raw window-coordinate values for a later flush.

kitaqgb/lib/scroll.c:36

c
void Scroll_SetWindowBuffered(u8 wx, u8 wy) { __scroll_win_set_buffered(wx, wy); }
Scroll_SetWindowX

Règle immédiatement la seule coordonnée WX brute de la fenêtre.

Syntaxe

c
void Scroll_SetWindowX(u8 wx);

Paramètres

wx

Octet WX brut, de 0 à 255 : ajoutez 7 au X voulu à l’écran ; le bord gauche utilise 7.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Aucune attente n’est effectuée. Les réglages et additions immédiats synchronisent la paire de coordonnées en attente concernée avec les valeurs courantes et effacent son drapeau de modification. Même le réglage immédiat d’un seul axe annule la valeur en attente de l’autre axe de la même paire. Cette fonction enveloppe __scroll_win_x_set.

Exemple d’utilisation

c
Scroll_SetWindowX(23);result[10]=M_WX;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_SetWindowX: DMG
DMG
Scroll_SetWindowX: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_SetWindowX: DMG
DMG
Scroll_SetWindowX: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:57

Notes de déclaration (texte source)
Write raw hardware WX without converting a screen-space X coordinate.

kitaqgb/lib/scroll.c:25

c
void Scroll_SetWindowX(u8 wx) { __scroll_win_x_set(wx); }
Scroll_SetWindowY

Règle immédiatement la seule coordonnée WY de la fenêtre.

Syntaxe

c
void Scroll_SetWindowY(u8 wy);

Paramètres

wy

Haut de la fenêtre en pixels Y de l’écran, de 0 à 255 ; les lignes visibles vont de 0 à 143.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Aucune attente n’est effectuée. Les réglages et additions immédiats synchronisent la paire de coordonnées en attente concernée avec les valeurs courantes et effacent son drapeau de modification. Même le réglage immédiat d’un seul axe annule la valeur en attente de l’autre axe de la même paire. Cette fonction enveloppe __scroll_win_y_set.

Exemple d’utilisation

c
Scroll_SetWindowY(16);result[11]=M_WY;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_SetWindowY: DMG
DMG
Scroll_SetWindowY: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_SetWindowY: DMG
DMG
Scroll_SetWindowY: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:59

Notes de déclaration (texte source)
Write the window Y coordinate through the intrinsic.

kitaqgb/lib/scroll.c:27

c
void Scroll_SetWindowY(u8 wy) { __scroll_win_y_set(wy); }
Scroll_SplitCommit

Mémorise la visibilité de base de la fenêtre et arme le premier événement de ligne de la table de coupures.

Syntaxe

c
void Scroll_SplitCommit();

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

La table partagée contient huit entrées. L’ajout ne les applique pas et ne les trie pas ; les entrées en excès sont ignorées. Reconstruisez-la avec reset→push→commit à une frontière de trame sûre et espacez assez les événements pour laisser le gestionnaire se terminer. La latence d’interruption peut décaler le premier pixel affecté par rapport à la ligne programmée. Une table non vide active VBlank/STAT dans IE et exécute EI. Une table vide désactive la source LYC, sans restaurer IE ni l’état des interruptions CPU. Cette fonction enveloppe __scroll_split_commit.

Exemple d’utilisation

c
Scroll_SplitCommit();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions enveloppantes Scroll pour créer trois bandes de défilement du fond. Les événements à LY=64 et 104 changent X en 8 puis 16, plaçant les rectangles de 24×16 en (32,16), (24,80) et (16,112). L’image montre le décalage de chaque bande.

Scroll_SplitCommit: DMG
DMG
Scroll_SplitCommit: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_split_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_split_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:92

Notes de déclaration (texte source)
Publish the pending split configuration through the compiler runtime.

kitaqgb/lib/scroll.c:66

c
void Scroll_SplitCommit() { __scroll_split_commit(); }
Scroll_SplitPush

Ajoute une coupure qui modifie le défilement du fond lors de l’événement de ligne demandé.

Syntaxe

c
void Scroll_SplitPush(u8 ly, u8 scx, u8 scy);

Paramètres

ly

Numéro de ligne de l’événement ; utilisez 0–143 pour les événements visibles et ajoutez-les par ordre croissant. Une première entrée à zéro est appliquée pendant VBlank.

scx

Défilement horizontal du fond, de 0 à 255 pixels ; l’augmenter déplace le fond vers la gauche.

scy

Défilement vertical du fond, de 0 à 255 pixels ; l’augmenter déplace le fond vers le haut.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

La table partagée contient huit entrées. L’ajout ne les applique pas et ne les trie pas ; les entrées en excès sont ignorées. Reconstruisez-la avec reset→push→commit à une frontière de trame sûre et espacez assez les événements pour laisser le gestionnaire se terminer. La latence d’interruption peut décaler le premier pixel affecté par rapport à la ligne programmée. Cette fonction enveloppe __scroll_split_push.

Exemple d’utilisation

c
Scroll_SplitPush(64,8,0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions enveloppantes Scroll pour créer trois bandes de défilement du fond. Les événements à LY=64 et 104 changent X en 8 puis 16, plaçant les rectangles de 24×16 en (32,16), (24,80) et (16,112). L’image montre le décalage de chaque bande.

Scroll_SplitPush: DMG
DMG
Scroll_SplitPush: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_split_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_split_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:85

Notes de déclaration (texte source)
Append a background-scroll split directly. Use Raster_Push when caller-side
scanline ordering and capacity validation are desired.

kitaqgb/lib/scroll.c:53

c
void Scroll_SplitPush(u8 ly, u8 scx, u8 scy) { __scroll_split_push(ly, scx, scy); }
Scroll_SplitPushBgColor0

Ajoute un événement qui change la couleur zéro de la palette zéro du fond CGB.

Syntaxe

c
void Scroll_SplitPushBgColor0(u8 ly, u16 rgb15);

Paramètres

ly

Numéro de ligne de l’événement ; utilisez 0–143 pour les événements visibles et ajoutez-les par ordre croissant. Une première entrée à zéro est appliquée pendant VBlank.

rgb15

Couleur RGB555 sur 15 bits : rouge aux bits 0–4, vert aux bits 5–9 et bleu aux bits 10–14.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

CGB uniquement. Utilise une entrée de la table à huit coupures via l’opération étendue. Les écritures de palette attendent un créneau accessible du PPU. Dans cet exemple CGB à vitesse normale, les événements LY=64/112 deviennent visibles aux lignes 66/114. Ne confondez pas la ligne de l’événement avec la première ligne affectée à l’écran.

Exemple d’utilisation

c
Scroll_SplitPushBgColor0(0,0x7C00);Scroll_SplitPushBgColor0(64,0x001F);Scroll_SplitPushBgColor0(112,0x03E0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Changez la couleur zéro du fond CGB pendant la trame. À vitesse normale, cet exemple dessine les lignes 0–65 en bleu, 66–113 en rouge et 114–143 en vert. Les événements sont programmés à 0, 64 et 112 ; le traitement des interruptions et l’accès aux palettes ajoutent de la latence. Le DMG ne propose pas ces palettes de couleurs.

Scroll_SplitPushBgColor0: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_split_color.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_split_color.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:90

Notes de déclaration (texte source)
Reuse the two background-scroll fields to carry the low/high RGB15 bytes
for a split whose operation flag selects background color zero.

kitaqgb/lib/scroll.c:61

c
void Scroll_SplitPushBgColor0(u8 ly, u16 rgb15)
{
    __scroll_split_push_ex(ly, (u8)rgb15, (u8)(rgb15 >> 8), 0, 0, KQ_SCROLL_SPLIT_BG_COLOR0);
}
Scroll_SplitPushEx

Ajoute une coupure dont les drapeaux choisissent les opérations sur le fond, la fenêtre, sa visibilité ou la couleur zéro du fond.

Syntaxe

c
void Scroll_SplitPushEx(u8 ly, u8 scx, u8 scy, u8 wx, u8 wy, u8 flags);

Paramètres

ly

Numéro de ligne de l’événement ; utilisez 0–143 pour les événements visibles et ajoutez-les par ordre croissant. Une première entrée à zéro est appliquée pendant VBlank.

scx

Défilement horizontal du fond, de 0 à 255 pixels ; l’augmenter déplace le fond vers la gauche.

scy

Défilement vertical du fond, de 0 à 255 pixels ; l’augmenter déplace le fond vers le haut.

wx

Octet WX brut, de 0 à 255 : ajoutez 7 au X voulu à l’écran ; le bord gauche utilise 7.

wy

Haut de la fenêtre en pixels Y de l’écran, de 0 à 255 ; les lignes visibles vont de 0 à 143.

flags

Bits d’opération : BG=1, position de fenêtre=2, afficher=4, masquer=8, palette de fond CGB 0/couleur 0=16. Les bits inconnus sont ignorés. Le mode couleur zéro réutilise scx/scy comme octets faible/fort de RGB15.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

La table partagée contient huit entrées. L’ajout ne les applique pas et ne les trie pas ; les entrées en excès sont ignorées. Reconstruisez-la avec reset→push→commit à une frontière de trame sûre et espacez assez les événements pour laisser le gestionnaire se terminer. La latence d’interruption peut décaler le premier pixel affecté par rapport à la ligne programmée. Afficher est prioritaire si les deux bits de visibilité sont actifs. La couleur zéro est réservée au CGB ; la combiner au déplacement BG utilise les mêmes octets scx/scy pour les deux opérations. Cette fonction enveloppe __scroll_split_push_ex.

Exemple d’utilisation

c
Scroll_SplitPushEx(104,16,0,7,0,KQ_SCROLL_SPLIT_USE_BG|KQ_SCROLL_SPLIT_WIN_HIDE);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions enveloppantes Scroll pour créer trois bandes de défilement du fond. Les événements à LY=64 et 104 changent X en 8 puis 16, plaçant les rectangles de 24×16 en (32,16), (24,80) et (16,112). L’image montre le décalage de chaque bande.

Scroll_SplitPushEx: DMG
DMG
Scroll_SplitPushEx: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_split_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_split_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:87

Notes de déclaration (texte source)
Append an extended split with raw background/window fields and operation flags.

kitaqgb/lib/scroll.c:55

c
void Scroll_SplitPushEx(u8 ly, u8 scx, u8 scy, u8 wx, u8 wy, u8 flags)
{
    __scroll_split_push_ex(ly, scx, scy, wx, wy, flags);
}
Scroll_SplitReset

Remet à zéro le nombre et l’indice des coupures, désactive leur traitement et efface le bit d’activation de l’interruption LYC dans STAT.

Syntaxe

c
void Scroll_SplitReset();

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

La table partagée contient huit entrées. L’ajout ne les applique pas et ne les trie pas ; les entrées en excès sont ignorées. Reconstruisez-la avec reset→push→commit à une frontière de trame sûre et espacez assez les événements pour laisser le gestionnaire se terminer. La latence d’interruption peut décaler le premier pixel affecté par rapport à la ligne programmée. N’efface pas les octets de la table ni IE et ne désactive pas les interruptions du CPU. Cette fonction enveloppe __scroll_split_reset.

Exemple d’utilisation

c
Scroll_SplitReset();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions enveloppantes Scroll pour créer trois bandes de défilement du fond. Les événements à LY=64 et 104 changent X en 8 puis 16, plaçant les rectangles de 24×16 en (32,16), (24,80) et (16,112). L’image montre le décalage de chaque bande.

Scroll_SplitReset: DMG
DMG
Scroll_SplitReset: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_split_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_split_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:82

Notes de déclaration (texte source)
Clear the pending split table before building a new raster configuration.

kitaqgb/lib/scroll.c:50

c
void Scroll_SplitReset() { __scroll_split_reset(); }
Scroll_WindowAdd

Ajoute des déplacements signés aux coordonnées suivies de la fenêtre et les applique immédiatement.

Syntaxe

c
void Scroll_WindowAdd(s8 dx, s8 dy);

Paramètres

dx

Déplacement horizontal signé en pixels, de −128 à 127.

dy

Déplacement vertical signé en pixels, de −128 à 127.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Aucune attente n’est effectuée. Les réglages et additions immédiats synchronisent la paire de coordonnées en attente concernée avec les valeurs courantes et effacent son drapeau de modification. Même le réglage immédiat d’un seul axe annule la valeur en attente de l’autre axe de la même paire. Les résultats rebouclent modulo 256. Les additions partent des valeurs courantes suivies, pas des valeurs en attente ni des valeurs temporaires des registres raster. Cette fonction enveloppe __scroll_win_add.

Exemple d’utilisation

c
Scroll_WindowAdd(4,-40);result[24]=M_WX;result[25]=M_WY;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_WindowAdd: DMG
DMG
Scroll_WindowAdd: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_WindowAdd: DMG
DMG
Scroll_WindowAdd: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:75

Notes de déclaration (texte source)
Apply signed deltas to the byte-sized hardware window coordinates.

kitaqgb/lib/scroll.c:43

c
void Scroll_WindowAdd(s8 dx, s8 dy) { __scroll_win_add(dx, dy); }
Scroll_WindowHide

Efface le bit de fenêtre LCDC et l’état suivi de visibilité de la fenêtre.

Syntaxe

c
void Scroll_WindowHide();

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Ne modifie ni les coordonnées ni le choix de la carte. Pour être visible, la fenêtre exige aussi que le LCD et les fonctions fond/fenêtre soient activés et qu’elle se trouve dans la zone visible. Cette fonction enveloppe __scroll_win_hide.

Exemple d’utilisation

c
Scroll_WindowHide();result[27]=M_LCDC&32;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_WindowHide: DMG
DMG
Scroll_WindowHide: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_WindowHide: DMG
DMG
Scroll_WindowHide: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:79

Notes de déclaration (texte source)
Request that the window be hidden through the compiler intrinsic.

kitaqgb/lib/scroll.c:47

c
void Scroll_WindowHide() { __scroll_win_hide(); }
Scroll_WindowShow

Active le bit de fenêtre LCDC et l’état suivi de visibilité de la fenêtre.

Syntaxe

c
void Scroll_WindowShow();

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Ne modifie ni les coordonnées ni le choix de la carte. Pour être visible, la fenêtre exige aussi que le LCD et les fonctions fond/fenêtre soient activés et qu’elle se trouve dans la zone visible. Cette fonction enveloppe __scroll_win_show.

Exemple d’utilisation

c
Scroll_WindowShow();result[26]=M_LCDC&32;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Utilisez les fonctions Scroll pour découvrir les mises à jour immédiates, la préparation, l’application, l’addition et la visibilité. L’application fait passer BG X de 250 à 16 et WX de 23 à 39. Le bit de fenêtre vaut 32 après affichage et 0 après masquage.

Scroll_WindowShow: DMG
DMG
Scroll_WindowShow: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_scroll_wrappers.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_scroll_wrappers.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k

Exemple d’utilisation

c
Camera_Init(&view);
Camera_Set(&view,2048,4096);
Camera_ApplyBg(&view);
Scroll_SetWindow(103,80);
Scroll_WindowShow();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec la caméra en (8,16), le rectangle rouge de 32×24 apparaît à l’écran en (24,16). La fenêtre montre un cadre bleu de 64×64 en (96,80) et un carré vert de 16×16 en (112,96). Toutes les formes sont noires sur DMG.

Scroll_WindowShow: DMG
DMG
Scroll_WindowShow: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_camera_view.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_camera_view.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/scroll.h:77

Notes de déclaration (texte source)
Request window visibility through the compiler intrinsic.

kitaqgb/lib/scroll.c:45

c
void Scroll_WindowShow() { __scroll_win_show(); }

slg.h — Plateaux, listes de coups et annulation

Fournit un plateau à valeurs d’un octet, une liste de coups de capacité limitée et une pile d’annulations. Le jeu combine ces opérations pour appliquer les coups ou les annulations au plateau.

slg_board_clear

Remplit toutes les cases du plateau avec la valeur demandée.

Syntaxe

c
void slg_board_clear(SLGBoard* board, u8 value);

Paramètres

board

SLGBoard à utiliser ; l’initialisation exige un stockage non NULL.

value

Valeur d’octet à stocker ; le jeu en définit le sens, par exemple un type de pièce ou de terrain.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Le stockage est fourni par l’appelant. L’initialisation ne l’alloue pas et ne l’efface pas. Les coordonnées du plateau sont exprimées en cases.

Exemple d’utilisation

c
slg_board_clear(&board,0);result[1]=cells[0];result[2]=cells[11];

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple distingue plateau, liste de coups et enregistrements d’annulation. L’initialisation du plateau conserve 9 ; un troisième ajout à une liste de capacité deux renvoie 0. Dépiler seul laisse le plateau à 8 ; appliquer explicitement l’enregistrement récupéré rétablit 7.

slg_board_clear: DMG
DMG
slg_board_clear: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_board.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_board.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/slg.h:33

Notes de déclaration (texte source)
Fill every cell with value; a null board is ignored. A valid board must own
enough accessible cell storage for its declared dimensions.

kitaqgb/lib/slg_board.c:36

c
void slg_board_clear(SLGBoard* board, u8 value)
{
    u16 total;
    u16 i;
    u8* p;
    if (board == 0) return;
    total = (u16)((u16)board->width * (u16)board->height);
    i = 0;
    p = board->cells;
    while (i < total) {
        *p = value;
        p++;
        i++;
    }
}
slg_board_get

Lit une case ; renvoie zéro pour un plateau NULL ou des coordonnées hors limites.

Syntaxe

c
u8 slg_board_get(const SLGBoard* board, u8 x, u8 y);

Paramètres

board

SLGBoard à utiliser ; l’initialisation exige un stockage non NULL.

x

Colonne de la case depuis la gauche, à partir de zéro ; enregistrer un coup ne vérifie pas les limites du plateau.

y

Ligne de la case depuis le haut, à partir de zéro ; enregistrer un coup ne vérifie pas les limites du plateau.

Valeur renvoyée

Octet de la case, ou zéro si la lecture est invalide. Zéro seul ne distingue pas une case vide de coordonnées invalides.

Conditions et limites

Le stockage est fourni par l’appelant. L’initialisation ne l’alloue pas et ne l’efface pas. Les coordonnées du plateau sont exprimées en cases.

Exemple d’utilisation

c
result[3]=slg_board_get(&board,1,1);result[4]=slg_board_get(&board,4,1);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple distingue plateau, liste de coups et enregistrements d’annulation. L’initialisation du plateau conserve 9 ; un troisième ajout à une liste de capacité deux renvoie 0. Dépiler seul laisse le plateau à 8 ; appliquer explicitement l’enregistrement récupéré rétablit 7.

slg_board_get: DMG
DMG
slg_board_get: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_board.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_board.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/slg.h:36

Notes de déclaration (texte source)
Return zero for a null board or out-of-range coordinate; otherwise read the
cell. Zero therefore cannot distinguish an invalid lookup from an empty cell.

kitaqgb/lib/slg_board.c:54

c
u8 slg_board_get(const SLGBoard* board, u8 x, u8 y)
{
    u8* p;
    if (board == 0) return 0;
    if (x >= board->width || y >= board->height) return 0;
    p = slg_cell_ptr((SLGBoard*)board, x, y);
    return *p;
}
slg_board_init

Associe les dimensions d’un plateau à un tableau de cases en conservant son contenu existant.

Syntaxe

c
void slg_board_init(SLGBoard* board, u8 width, u8 height, u8* cells);

Paramètres

board

SLGBoard à utiliser ; l’initialisation exige un stockage non NULL.

width

Largeur du plateau en cases, également utilisée comme pas entre les lignes.

height

Nombre de lignes du plateau.

cells

Tableau accessible en écriture, rangé ligne par ligne, d’au moins width*height octets de cases.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Le stockage est fourni par l’appelant. L’initialisation ne l’alloue pas et ne l’efface pas. Les coordonnées du plateau sont exprimées en cases.

Exemple d’utilisation

c
cells[0]=9;slg_board_init(&board,4,3,cells);result[0]=slg_board_get(&board,0,0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple distingue plateau, liste de coups et enregistrements d’annulation. L’initialisation du plateau conserve 9 ; un troisième ajout à une liste de capacité deux renvoie 0. Dépiler seul laisse le plateau à 8 ; appliquer explicitement l’enregistrement récupéré rétablit 7.

slg_board_init: DMG
DMG
slg_board_init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_board.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_board.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/slg.h:30

Notes de déclaration (texte source)
Attach width * height bytes of caller-owned cell storage without clearing it.

kitaqgb/lib/slg_board.c:27

c
void slg_board_init(SLGBoard* board, u8 width, u8 height, u8* cells)
{
    board->width = width;
    board->height = height;
    board->cells = cells;
}
slg_board_set

Écrit dans une case valide du plateau ; ignore un plateau NULL ou des coordonnées hors limites.

Syntaxe

c
void slg_board_set(SLGBoard* board, u8 x, u8 y, u8 value);

Paramètres

board

SLGBoard à utiliser ; l’initialisation exige un stockage non NULL.

x

Colonne de la case depuis la gauche, à partir de zéro ; enregistrer un coup ne vérifie pas les limites du plateau.

y

Ligne de la case depuis le haut, à partir de zéro ; enregistrer un coup ne vérifie pas les limites du plateau.

value

Valeur d’octet à stocker ; le jeu en définit le sens, par exemple un type de pièce ou de terrain.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Le stockage est fourni par l’appelant. L’initialisation ne l’alloue pas et ne l’efface pas. Les coordonnées du plateau sont exprimées en cases.

Exemple d’utilisation

c
slg_board_set(&board,1,1,7);slg_board_set(&board,4,1,9);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple distingue plateau, liste de coups et enregistrements d’annulation. L’initialisation du plateau conserve 9 ; un troisième ajout à une liste de capacité deux renvoie 0. Dépiler seul laisse le plateau à 8 ; appliquer explicitement l’enregistrement récupéré rétablit 7.

slg_board_set: DMG
DMG
slg_board_set: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_board.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_board.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/slg.h:38

Notes de déclaration (texte source)
Write a cell only when the board and coordinate are valid.

kitaqgb/lib/slg_board.c:64

c
void slg_board_set(SLGBoard* board, u8 x, u8 y, u8 value)
{
    u8* p;
    if (board == 0) return;
    if (x >= board->width || y >= board->height) return;
    p = slg_cell_ptr(board, x, y);
    *p = value;
}
slg_move_list_clear

Réinitialise le nombre de coups sans effacer les enregistrements stockés.

Syntaxe

c
void slg_move_list_clear(SLGMoveList* list);

Paramètres

list

Liste de coups à utiliser ; l’initialisation exige un pointeur non NULL.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Le stockage est fourni par l’appelant. L’initialisation ne l’alloue pas et ne l’efface pas. Les coordonnées du plateau sont exprimées en cases.

Exemple d’utilisation

c
slg_move_list_clear(&moves);result[10]=moves.count;result[11]=move_data[0].value;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple distingue plateau, liste de coups et enregistrements d’annulation. L’initialisation du plateau conserve 9 ; un troisième ajout à une liste de capacité deux renvoie 0. Dépiler seul laisse le plateau à 8 ; appliquer explicitement l’enregistrement récupéré rétablit 7.

slg_move_list_clear: DMG
DMG
slg_move_list_clear: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_board.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_board.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/slg.h:42

Notes de déclaration (texte source)
Forget the moves without erasing their storage; a null list is ignored.

kitaqgb/lib/slg_board.c:83

c
void slg_move_list_clear(SLGMoveList* list)
{
    if (list == 0) return;
    list->count = 0;
}
slg_move_list_init

Associe un espace de stockage de coups et sa capacité, puis met le compteur à zéro.

Syntaxe

c
void slg_move_list_init(SLGMoveList* list, SLGMove* items, u8 capacity);

Paramètres

list

Liste de coups à utiliser ; l’initialisation exige un pointeur non NULL.

items

Tableau détenu par l’appelant, capable de contenir au moins capacity enregistrements SLGMove.

capacity

Nombre maximal d’enregistrements ; zéro interdit tout ajout. Chaque enregistrement contient trois octets : x, y et valeur.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Le stockage est fourni par l’appelant. L’initialisation ne l’alloue pas et ne l’efface pas. Les coordonnées du plateau sont exprimées en cases.

Exemple d’utilisation

c
slg_move_list_init(&moves,move_data,2);result[5]=moves.count;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple distingue plateau, liste de coups et enregistrements d’annulation. L’initialisation du plateau conserve 9 ; un troisième ajout à une liste de capacité deux renvoie 0. Dépiler seul laisse le plateau à 8 ; appliquer explicitement l’enregistrement récupéré rétablit 7.

slg_move_list_init: DMG
DMG
slg_move_list_init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_board.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_board.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/slg.h:40

Notes de déclaration (texte source)
Attach caller-owned move storage and reset the list length.

kitaqgb/lib/slg_board.c:75

c
void slg_move_list_init(SLGMoveList* list, SLGMove* items, u8 capacity)
{
    list->items = items;
    list->capacity = capacity;
    list->count = 0;
}
slg_move_list_push

Ajoute des coordonnées et une valeur à la liste de coups sans modifier le plateau.

Syntaxe

c
u8 slg_move_list_push(SLGMoveList* list, u8 x, u8 y, u8 value);

Paramètres

list

Liste de coups à utiliser ; l’initialisation exige un pointeur non NULL.

x

Colonne de la case depuis la gauche, à partir de zéro ; enregistrer un coup ne vérifie pas les limites du plateau.

y

Ligne de la case depuis le haut, à partir de zéro ; enregistrer un coup ne vérifie pas les limites du plateau.

value

Valeur d’octet à stocker ; le jeu en définit le sens, par exemple un type de pièce ou de terrain.

Valeur renvoyée

1 si l’ajout réussit, 0 pour NULL ou un stockage plein ; en cas d’échec, le compteur et les enregistrements existants sont conservés.

Conditions et limites

Le stockage est fourni par l’appelant. L’initialisation ne l’alloue pas et ne l’efface pas. Les coordonnées du plateau sont exprimées en cases.

Exemple d’utilisation

c
result[6]=slg_move_list_push(&moves,1,1,7);result[7]=slg_move_list_push(&moves,2,1,8);result[8]=slg_move_list_push(&moves,3,1,9);result[9]=moves.count;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple distingue plateau, liste de coups et enregistrements d’annulation. L’initialisation du plateau conserve 9 ; un troisième ajout à une liste de capacité deux renvoie 0. Dépiler seul laisse le plateau à 8 ; appliquer explicitement l’enregistrement récupéré rétablit 7.

slg_move_list_push: DMG
DMG
slg_move_list_push: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_board.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_board.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/slg.h:45

Notes de déclaration (texte source)
Append coordinates and a value to the bounded move list. Return zero on a
null/full list without replacing any existing move.

kitaqgb/lib/slg_board.c:91

c
u8 slg_move_list_push(SLGMoveList* list, u8 x, u8 y, u8 value)
{
    SLGMove* move;
    if (list == 0) return 0;
    if (list->count >= list->capacity) return 0;
    move = &list->items[(__safe_index u8)list->count];
    move->x = x;
    move->y = y;
    move->value = value;
    list->count++;
    return 1;
}
slg_undo_init

Associe un espace de stockage d’annulations et sa capacité, avec une pile initialement vide.

Syntaxe

c
void slg_undo_init(SLGUndoStack* stack, SLGMove* items, u8 capacity);

Paramètres

stack

Pile d’annulation à utiliser ; l’initialisation exige un pointeur non NULL.

items

Tableau détenu par l’appelant, capable de contenir au moins capacity enregistrements SLGMove.

capacity

Nombre maximal d’enregistrements ; zéro interdit tout ajout. Chaque enregistrement contient trois octets : x, y et valeur.

Valeur renvoyée

Aucune valeur de retour. L’état modifié et le moment de sa prise d’effet sont décrits dans cette entrée.

Conditions et limites

Le stockage est fourni par l’appelant. L’initialisation ne l’alloue pas et ne l’efface pas. Les coordonnées du plateau sont exprimées en cases.

Exemple d’utilisation

c
slg_undo_init(&undo,undo_data,2);result[12]=undo.count;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple distingue plateau, liste de coups et enregistrements d’annulation. L’initialisation du plateau conserve 9 ; un troisième ajout à une liste de capacité deux renvoie 0. Dépiler seul laisse le plateau à 8 ; appliquer explicitement l’enregistrement récupéré rétablit 7.

slg_undo_init: DMG
DMG
slg_undo_init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_board.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_board.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/slg.h:47

Notes de déclaration (texte source)
Attach caller-owned undo records and initialize an empty stack.

kitaqgb/lib/slg_board.c:106

c
void slg_undo_init(SLGUndoStack* stack, SLGMove* items, u8 capacity)
{
    stack->items = items;
    stack->capacity = capacity;
    stack->count = 0;
}
slg_undo_pop

Retire et récupère le dernier enregistrement d’annulation ; l’appelant l’applique au plateau.

Syntaxe

c
u8 slg_undo_pop(SLGUndoStack* stack, SLGMove* out_move);

Paramètres

stack

Pile d’annulation à utiliser ; l’initialisation exige un pointeur non NULL.

out_move

Destination de l’enregistrement retiré ; NULL le supprime sans le copier.

Valeur renvoyée

1 si un enregistrement a été retiré, 0 pour une pile NULL ou vide ; une pile vide laisse la sortie inchangée.

Conditions et limites

Le stockage est fourni par l’appelant. L’initialisation ne l’alloue pas et ne l’efface pas. Les coordonnées du plateau sont exprimées en cases.

Exemple d’utilisation

c
result[15]=slg_undo_pop(&undo,&old);result[16]=old.value;result[17]=slg_board_get(&board,1,1);slg_undo_pop(&undo,&old);slg_board_set(&board,old.x,old.y,old.value);result[18]=slg_board_get(&board,1,1);result[19]=slg_undo_pop(&undo,&old);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple distingue plateau, liste de coups et enregistrements d’annulation. L’initialisation du plateau conserve 9 ; un troisième ajout à une liste de capacité deux renvoie 0. Dépiler seul laisse le plateau à 8 ; appliquer explicitement l’enregistrement récupéré rétablit 7.

slg_undo_pop: DMG
DMG
slg_undo_pop: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_board.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_board.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/slg.h:53

Notes de déclaration (texte source)
Remove the newest undo record and optionally copy it out. A null output
still discards the record; a null or empty stack returns zero.

kitaqgb/lib/slg_board.c:128

c
u8 slg_undo_pop(SLGUndoStack* stack, SLGMove* out_move)
{
    if (stack == 0) return 0;
    if (stack->count == 0) return 0;
    stack->count--;
    if (out_move != 0) {
        out_move->x = stack->items[stack->count].x;
        out_move->y = stack->items[stack->count].y;
        out_move->value = stack->items[stack->count].value;
    }
    return 1;
}
slg_undo_push

Empile l’ancienne valeur d’une case dans la pile d’annulation sans modifier le plateau.

Syntaxe

c
u8 slg_undo_push(SLGUndoStack* stack, u8 x, u8 y, u8 old_value);

Paramètres

stack

Pile d’annulation à utiliser ; l’initialisation exige un pointeur non NULL.

x

Colonne de la case depuis la gauche, à partir de zéro ; enregistrer un coup ne vérifie pas les limites du plateau.

y

Ligne de la case depuis le haut, à partir de zéro ; enregistrer un coup ne vérifie pas les limites du plateau.

old_value

Ancien octet de la case ; la fonction ne le lit pas automatiquement dans le plateau.

Valeur renvoyée

1 si l’ajout réussit, 0 pour NULL ou un stockage plein ; en cas d’échec, le compteur et les enregistrements existants sont conservés.

Conditions et limites

Le stockage est fourni par l’appelant. L’initialisation ne l’alloue pas et ne l’efface pas. Les coordonnées du plateau sont exprimées en cases.

Exemple d’utilisation

c
result[13]=slg_undo_push(&undo,1,1,slg_board_get(&board,1,1));slg_board_set(&board,1,1,8);slg_undo_push(&undo,1,1,8);result[14]=slg_undo_push(&undo,0,0,9);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cet exemple distingue plateau, liste de coups et enregistrements d’annulation. L’initialisation du plateau conserve 9 ; un troisième ajout à une liste de capacité deux renvoie 0. Dépiler seul laisse le plateau à 8 ; appliquer explicitement l’enregistrement récupéré rétablit 7.

slg_undo_push: DMG
DMG
slg_undo_push: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch2_board.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch2_board.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/slg.h:50

Notes de déclaration (texte source)
Record a cell's previous value for later undo. Return zero if the stack is
null or full; this function does not change the board itself.

kitaqgb/lib/slg_board.c:115

c
u8 slg_undo_push(SLGUndoStack* stack, u8 x, u8 y, u8 old_value)
{
    if (stack == 0) return 0;
    if (stack->count >= stack->capacity) return 0;
    stack->items[stack->count].x = x;
    stack->items[stack->count].y = y;
    stack->items[stack->count].value = old_value;
    stack->count++;
    return 1;
}

sprite.h — Allocation d'OBJ, placement, métasprites et animation

Les sprites sont des objets matériels mobiles, généralement de 8×8 ou 8×16 pixels, décrits dans l’OAM, la mémoire des attributs d’objets. Réservez des entrées, préparez position, tuile et attributs dans la copie de l’OAM, puis transférez-la. Un métasprite réunit plusieurs entrées en un objet. Le GB offre 40 entrées avec une limite de 10 par ligne ; le FC, 64 avec une limite de 8 par ligne.

Attributs GB : le bit 4 sélectionne OBP1 sur DMG ; 5/6 retournent X/Y ; 7 place le sprite derrière les pixels de fond d’indice non nul. Sur CGB, 0..2 choisissent la palette d’objets et 3 la banque VRAM des tuiles ; le bit de palette DMG ne choisit pas les couleurs natives CGB.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

anim_update

Avance le compteur SpriteAnim et renvoie la tuile sélectionnée. Toutes les ticks_per_frame invocations, il passe à la tuile consécutive suivante et revient à la première après frame_count images. Appliquez le résultat avec sprite_set_tile.

Syntaxe

c
u8 anim_update(SpriteAnim* anim);

Paramètres

anim

État SpriteAnim modifiable contenant first_tile, frame_count, frame, ticks et ticks_per_frame. Pour des limites non nulles, gardez frame inférieur à frame_count et ticks inférieur à ticks_per_frame.

Valeur renvoyée

Numéro de tuile sur 8 bits ; 0 si le pointeur d’état est nul. La fonction n’écrit pas dans l’OAM.

Conditions et limites

frame_count=0 renvoie first_tile sans avancer ; ticks_per_frame=0 fige l’image courante. Le compteur avance par appel, pas par image vidéo. Les numéros rebouclent après 255 et avancent de un même en mode 8×16.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
sprite_example_animation.first_tile=128;sprite_example_animation.frame_count=2;
sprite_example_animation.frame=0;sprite_example_animation.ticks=0;
sprite_example_animation.ticks_per_frame=2;
sprite_example_expect(anim_update(&sprite_example_animation)==128);
tile=anim_update(&sprite_example_animation);
sprite_example_expect(tile==129);sprite_set_tile(5,tile);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec first_tile=128, deux images et deux appels par image, la première mise à jour renvoie la flèche 128 et la seconde le carré 129. Le carré près d’ANIMATION confirme l’application du résultat à l’OAM.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

anim_update: DMG
DMG
anim_update: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:86

Notes de déclaration (texte source)
Advance animation ticks/frame with wrapping frame selection and return the
resulting tile. Zero ticks-per-frame freezes animation; null state returns zero.

kitaqgb/lib/sprite.c:211

c
u8 anim_update(SpriteAnim* anim)
{
    if (anim == 0) return 0;
    if (anim->frame_count == 0) return anim->first_tile;
    if (anim->ticks_per_frame == 0) return (u8)(anim->first_tile + anim->frame);

    anim->ticks++;
    if (anim->ticks >= anim->ticks_per_frame) {
        anim->ticks = 0;
        anim->frame++;
        if (anim->frame >= anim->frame_count) anim->frame = 0;
    }
    return (u8)(anim->first_tile + anim->frame);
}
metasprite_draw

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Place un tableau de parties de sprite dans des entrées consécutives. Chaque partie fournit un décalage signé, une tuile et des attributs. La routine active les entrées libres, remplace les actives et s’arrête à la limite des entrées.

Syntaxe

c
u8 metasprite_draw(u8 first_id, u8 x, u8 y, const MetaSpritePart* parts, u8 count);

Paramètres

first_id

Identifiant entre 0 et SPRITE_MAX-1 : par défaut 0..39 sur GB, 0..63 sur FC. Les identifiants hors limites sont ignorés.

x

Position horizontale en pixels, sous forme d’octet non signé ; ce n’est pas une coordonnée de tuile.

y

Coordonnée Y écran en pixels. La fonction GB ajoute 16 avant de la stocker dans l’OAM.

parts

Tableau lisible d’au moins count enregistrements MetaSpritePart. Chaque enregistrement de quatre octets contient dx/dy signés, tuile et attributs, sans marqueur de fin.

count

Nombre de parties sous forme d’octet non signé. Zéro n’écrit rien. Si les entrées consécutives atteignent SPRITE_MAX, seules les parties qui tiennent sont écrites.

Valeur renvoyée

Nombre de parties écrites, entre 0 et count. Vérifiez ce résultat pour détecter une troncature à la limite des entrées.

Conditions et limites

Position, tuile, attributs et masquage modifient la copie de travail. Ils ne réservent aucune entrée et ne mettent pas immédiatement l’OAM à jour ; transférez l’image préparée avec sprite_flush_oam.

Les décalages sont des octets signés ajoutés à l’origine, avec rebouclage sur huit bits. Le tableau doit rester lisible pendant l’appel. Les entrées actives sont remplacées ; celles d’autres objets ne sont pas protégées.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
sprite_example_expect(metasprite_draw(10,88,SPRITE_EXAMPLE_Y(64),sprite_example_pair,2)==2);
sprite_example_expect(sprite_count_used()==9); // Sparse IDs count actual active slots.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’initialisation donne zéro réservation. Huit allocations renvoient 0..7. Masquer l’entrée 6 conserve 8 ; libérer deux fois la 7 laisse 7. Placer la paire en 10 et 11 porte le total à 9.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

metasprite_draw: DMG
DMG
metasprite_draw: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:83

Notes de déclaration (texte source)
Place consecutive parts, counting each newly activated slot once. Existing
active slots are overwritten without increasing the allocation count. Return
the number written; an invalid first slot or zero count writes nothing.

kitaqgb/lib/sprite.c:191

c
u8 metasprite_draw(u8 first_id, u8 x, u8 y, const MetaSpritePart* parts, u8 count)
{
    u8 i = 0;
    while (i < count) {
        u8 id = (u8)(first_id + i);
        if (id >= SPRITE_MAX) return i;
        if (kq_sprite_active[id] == 0) {
            kq_sprite_active[id] = 1;
            kq_sprite_used = (u8)(kq_sprite_used + 1);
        }
        sprite_set_pos(id, (u8)(x + parts[i].dx), (u8)(y + parts[i].dy));
        sprite_set_tile(id, parts[i].tile);
        sprite_set_flags(id, parts[i].flags);
        i++;
    }
    return count;
}
sprite_alloc

Réserve la première entrée libre et la masque jusqu’à ce que vous la positionniez. Une entrée masquée reste réservée ; définissez sa tuile et ses attributs avant de l’afficher.

Syntaxe

c
u8 sprite_alloc();

Valeur renvoyée

Identifiant réservé, ou 0xFF si toutes les entrées sont actives.

Conditions et limites

Position, tuile, attributs et masquage modifient la copie de travail. Ils ne réservent aucune entrée et ne mettent pas immédiatement l’OAM à jour ; transférez l’image préparée avec sprite_flush_oam.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
for(i=0;i<8;i++) sprite_example_expect(sprite_alloc()==i);
sprite_example_expect(sprite_count_used()==8);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’initialisation donne zéro réservation. Huit allocations renvoient 0..7. Masquer l’entrée 6 conserve 8 ; libérer deux fois la 7 laisse 7. Placer la paire en 10 et 11 porte le total à 9.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

sprite_alloc: DMG
DMG
sprite_alloc: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:53

Notes de déclaration (texte source)
Claim the first free slot, hide it, and return its ID; return 0xFF when full.
Previously stored tile/flag bytes are retained until the caller replaces them.

kitaqgb/lib/sprite.c:60

c
u8 sprite_alloc()
{
    u8 i = 0;
    while (i < SPRITE_MAX) {
        if (kq_sprite_active[i] == 0) {
            kq_sprite_active[i] = 1;
            kq_sprite_used++;
            sprite_hide(i);
            return i;
        }
        i++;
    }
    return 0xFF;
}
sprite_count_used

Renvoie le nombre d’entrées réservées, y compris les sprites masqués et les entrées activées par metasprite_draw. Il s’agit des réservations, pas des sprites visibles.

Syntaxe

c
u8 sprite_count_used();

Valeur renvoyée

Octet non signé entre 0 et SPRITE_MAX.

Conditions et limites

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
sprite_example_expect(sprite_count_used()==9); // After hiding, freeing and drawing the pair.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’initialisation donne zéro réservation. Huit allocations renvoient 0..7. Masquer l’entrée 6 conserve 8 ; libérer deux fois la 7 laisse 7. Placer la paire en 10 et 11 porte le total à 9.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

sprite_count_used: DMG
DMG
sprite_count_used: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:73

Notes de déclaration (texte source)
Return the number of active slots, including slots activated by metasprite_draw.
Hidden allocated slots remain active until sprite_free releases them.

kitaqgb/lib/sprite.c:148

c
u8 sprite_count_used()
{
    return kq_sprite_used;
}
sprite_flush_oam

Attend le VBlank, puis transfère la copie de l’OAM avec sprite_flush_oam_now.

Syntaxe

c
void sprite_flush_oam();

Valeur renvoyée

Aucune (void).

Conditions et limites

La routine GB exécute le DMA depuis la HRAM et copie les 160 octets de l’OAM alignée. Elle désactive les interruptions pendant le transfert et les réactive toujours ensuite, sans restaurer un éventuel état désactivé à l’entrée.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
while(1) { sprite_flush_oam(); } // Transfer prepared sprites at the next frame boundary.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

sprite_flush_oam: DMG
DMG
sprite_flush_oam: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:70

Notes de déclaration (texte source)
Wait for VBlank, then transfer shadow OAM using the immediate DMA routine.

kitaqgb/lib/sprite.c:139

c
void sprite_flush_oam()
{
    __wait_vblank();
    sprite_flush_oam_now();
}
sprite_flush_oam_now

Transfère immédiatement la copie de l’OAM vers le matériel. La routine n’attend pas une période d’affichage sûre ; le code appelant choisit le moment de l’exécuter.

Syntaxe

c
void sprite_flush_oam_now();

Valeur renvoyée

Aucune (void).

Conditions et limites

La routine GB exécute le DMA depuis la HRAM et copie les 160 octets de l’OAM alignée. Elle désactive les interruptions pendant le transfert et les réactive toujours ensuite, sans restaurer un éventuel état désactivé à l’entrée.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
// Rendering is disabled here; all shadow entries have been prepared.
sprite_flush_oam_now();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

sprite_flush_oam_now: DMG
DMG
sprite_flush_oam_now: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:68

Notes de déclaration (texte source)
Install the HRAM stub lazily and execute OAM DMA with interrupts disabled.
This routine does not wait for VBlank and always enables interrupts afterward;
it does not restore the caller's previous interrupt-enable state.

kitaqgb/lib/sprite.c:122

c
void sprite_flush_oam_now()
{
    SpriteDmaRoutine dma;
    if (kq_sprite_dma_ready == 0) {
        sprite_install_dma_stub();
    }
    dma = (SpriteDmaRoutine)kq_sprite_dma_stub;
    __asm {
        DI
    }
    dma();
    __asm {
        EI
    }
}
sprite_free

Libère une entrée réservée, la masque et diminue le nombre d’entrées actives d’une unité. Un identifiant hors limites ou une entrée déjà libre ne produit aucun changement.

Syntaxe

c
void sprite_free(u8 id);

Paramètres

id

Identifiant entre 0 et SPRITE_MAX-1 : par défaut 0..39 sur GB, 0..63 sur FC. Les identifiants hors limites sont ignorés.

Valeur renvoyée

Aucune (void).

Conditions et limites

Position, tuile, attributs et masquage modifient la copie de travail. Ils ne réservent aucune entrée et ne mettent pas immédiatement l’OAM à jour ; transférez l’image préparée avec sprite_flush_oam.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
sprite_free(7);sprite_free(7);
sprite_example_expect(sprite_count_used()==7); // Repeated release is ignored.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’initialisation donne zéro réservation. Huit allocations renvoient 0..7. Masquer l’entrée 6 conserve 8 ; libérer deux fois la 7 laisse 7. Placer la paire en 10 et 11 porte le total à 9.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

sprite_free: DMG
DMG
sprite_free: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:55

Notes de déclaration (texte source)
Release an allocated valid slot and hide it. Repeated frees do not decrement the count.

kitaqgb/lib/sprite.c:78

c
void sprite_free(u8 id)
{
    if (sprite_valid(id) == 0) return;
    if (kq_sprite_active[id] == 0) return;
    kq_sprite_active[id] = 0;
    if (kq_sprite_used != 0) kq_sprite_used--;
    sprite_hide(id);
}
sprite_hide

Masque un sprite en modifiant sa position dans la copie de l’OAM. La réservation, la tuile et les attributs sont conservés ; une position visible suffit pour le réafficher.

Syntaxe

c
void sprite_hide(u8 id);

Paramètres

id

Identifiant entre 0 et SPRITE_MAX-1 : par défaut 0..39 sur GB, 0..63 sur FC. Les identifiants hors limites sont ignorés.

Valeur renvoyée

Aucune (void).

Conditions et limites

Position, tuile, attributs et masquage modifient la copie de travail. Ils ne réservent aucune entrée et ne mettent pas immédiatement l’OAM à jour ; transférez l’image préparée avec sprite_flush_oam.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
sprite_hide(6);
sprite_example_expect(sprite_count_used()==8); // Hiding retains allocation.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’initialisation donne zéro réservation. Huit allocations renvoient 0..7. Masquer l’entrée 6 conserve 8 ; libérer deux fois la 7 laisse 7. Placer la paire en 10 et 11 porte le total à 9.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

sprite_hide: DMG
DMG
sprite_hide: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:64

Notes de déclaration (texte source)
Move a valid shadow slot off screen without freeing it.

kitaqgb/lib/sprite.c:112

c
void sprite_hide(u8 id)
{
    if (sprite_valid(id) == 0) return;
    kq_sprite_oam[id].y = 0;
    kq_sprite_oam[id].x = 0;
}
sprite_init

Réinitialise l’allocation des sprites et masque toutes les entrées dans la copie de travail de l’OAM. La hauteur logicielle passe à 8 pixels ; la taille matérielle et le transfert vers l’OAM se règlent séparément.

Syntaxe

c
void sprite_init();

Valeur renvoyée

Aucune (void).

Conditions et limites

Sur GB, l’initialisation efface les quatre octets de chaque entrée et réinitialise l’installation de la routine DMA en HRAM. Gardez SPRITE_MAX=40, sauf si votre source DMA personnalisée fournit bien les 160 octets.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
sprite_init();
sprite_example_expect(sprite_count_used()==0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’initialisation donne zéro réservation. Huit allocations renvoient 0..7. Masquer l’entrée 6 conserve 8 ; libérer deux fois la 7 laisse 7. Placer la paire en 10 et 11 porte le total à 9.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

sprite_init: DMG
DMG
sprite_init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:50

Notes de déclaration (texte source)
Clear allocation and shadow OAM state and reset the DMA-stub installation flag.
The default height is eight pixels; the hardware display mode is configured elsewhere.

kitaqgb/lib/sprite.c:22

c
void sprite_init()
{
    u8 i = 0;
    kq_sprite_used = 0;
    kq_sprite_height = 8;
    kq_sprite_dma_ready = 0;
    while (i < SPRITE_MAX) {
        kq_sprite_active[i] = 0;
        kq_sprite_oam[i].y = 0;
        kq_sprite_oam[i].x = 0;
        kq_sprite_oam[i].tile = 0;
        kq_sprite_oam[i].flags = 0;
        i++;
    }
}
sprite_max_scanline_count

Estime le nombre maximal de sprites actifs présents sur une même ligne visible à partir des positions verticales suivies et de kq_sprite_height.

Syntaxe

c
u8 sprite_max_scanline_count();

Valeur renvoyée

Octet non signé entre 0 et SPRITE_MAX.

Conditions et limites

Réglez kq_sprite_height sur la hauteur matérielle, 8 ou 16. L’estimation ignore transparence, visibilité horizontale et priorité. Sur FC, elle lit les coordonnées de la bibliothèque ; les modifications directes par les intrinsèques OAM n’y figurent pas.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
sprite_example_expect(sprite_max_scanline_count()==SPRITE_EXAMPLE_LINE_COUNT);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

sprite_max_scanline_count: DMG
DMG
sprite_max_scanline_count: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:79

Notes de déclaration (texte source)
Estimate the largest overlap of active, non-hidden shadow sprites across
visible scanlines using the configured sprite height. This is a software
overlap count, not a rendered-pixel or hardware-priority simulation.

kitaqgb/lib/sprite.c:158

c
u8 sprite_max_scanline_count()
{
    u8 line = 0;
    u8 best = 0;
    while (line < 144) {
        u8 i = 0;
        u8 count = 0;
        u8 ly_oam = (u8)(line + 16);
        while (i < SPRITE_MAX) {
            u8 sy = kq_sprite_oam[i].y;
            if (kq_sprite_active[i] != 0 && sy != 0) {
                if (ly_oam >= sy && ly_oam < (u8)(sy + kq_sprite_height)) {
                    count++;
                }
            }
            i++;
        }
        if (count > best) best = count;
        line++;
    }
    return best;
}
sprite_set_flags

Remplace tout l’octet d’attributs. Combinez les constantes de la plateforme pour choisir les retournements, la palette et la priorité par rapport au fond ; les bits absents sont remis à zéro.

Syntaxe

c
void sprite_set_flags(u8 id, u8 flags);

Paramètres

id

Identifiant entre 0 et SPRITE_MAX-1 : par défaut 0..39 sur GB, 0..63 sur FC. Les identifiants hors limites sont ignorés.

flags

Octet complet d’attributs, construit avec les constantes SPRITE_FLAG_* de la plateforme. Combinez les indicateurs avec le OU binaire (|).

Valeur renvoyée

Aucune (void).

Conditions et limites

Position, tuile, attributs et masquage modifient la copie de travail. Ils ne réservent aucune entrée et ne mettent pas immédiatement l’OAM à jour ; transférez l’image préparée avec sprite_flush_oam.

Attributs GB : le bit 4 sélectionne OBP1 sur DMG ; 5/6 retournent X/Y ; 7 place le sprite derrière les pixels de fond d’indice non nul. Sur CGB, 0..2 choisissent la palette d’objets et 3 la banque VRAM des tuiles ; le bit de palette DMG ne choisit pas les couleurs natives CGB.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
sprite_set_flags(1,SPRITE_FLAG_XFLIP);
sprite_set_flags(2,SPRITE_FLAG_YFLIP);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

sprite_set_flags: DMG
DMG
sprite_set_flags: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:62

Notes de déclaration (texte source)
Replace a valid shadow slot's complete hardware attribute byte.

kitaqgb/lib/sprite.c:105

c
void sprite_set_flags(u8 id, u8 flags)
{
    if (sprite_valid(id) == 0) return;
    kq_sprite_oam[id].flags = flags;
}
sprite_set_pos

Déplace un sprite GB dans la copie de l’OAM à partir de coordonnées écran en pixels. La fonction ajoute les décalages matériels : 8 à X et 16 à Y.

Syntaxe

c
void sprite_set_pos(u8 id, u8 x, u8 y);

Paramètres

id

Identifiant entre 0 et SPRITE_MAX-1 : par défaut 0..39 sur GB, 0..63 sur FC. Les identifiants hors limites sont ignorés.

x

Position horizontale en pixels, sous forme d’octet non signé ; ce n’est pas une coordonnée de tuile.

y

Coordonnée Y écran en pixels. La fonction GB ajoute 16 avant de la stocker dans l’OAM.

Valeur renvoyée

Aucune (void).

Conditions et limites

Position, tuile, attributs et masquage modifient la copie de travail. Ils ne réservent aucune entrée et ne mettent pas immédiatement l’OAM à jour ; transférez l’image préparée avec sprite_flush_oam.

Les additions de coordonnées se font sur huit bits et rebouclent modulo 256, sans découpage aux limites de l’écran. Une entrée valide peut être modifiée même sans réservation.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
sprite_set_pos(0,88,SPRITE_EXAMPLE_Y(16)); // Visible top-left: (88,16).

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

sprite_set_pos: DMG
DMG
sprite_set_pos: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:58

Notes de déclaration (texte source)
Convert screen coordinates to OAM coordinates by adding X=8 and Y=16.
The byte additions wrap; this updates shadow storage even for an unallocated slot.

kitaqgb/lib/sprite.c:89

c
void sprite_set_pos(u8 id, u8 x, u8 y)
{
    if (sprite_valid(id) == 0) return;
    kq_sprite_oam[id].x = (u8)(x + 8);
    kq_sprite_oam[id].y = (u8)(y + 16);
}
sprite_set_tile

Remplace le numéro de tuile d’une entrée OAM. Cette opération sélectionne un graphisme déjà présent en mémoire ; elle ne transfère aucun graphisme et ne réserve aucun sprite.

Syntaxe

c
void sprite_set_tile(u8 id, u8 tile);

Paramètres

id

Identifiant entre 0 et SPRITE_MAX-1 : par défaut 0..39 sur GB, 0..63 sur FC. Les identifiants hors limites sont ignorés.

tile

Numéro de tuile sur 8 bits. Chargez d’abord les graphismes. Les règles matérielles du mode 8×16 s’appliquent ; aucun ajustement pour les paires de tuiles n’est effectué.

Valeur renvoyée

Aucune (void).

Conditions et limites

Position, tuile, attributs et masquage modifient la copie de travail. Ils ne réservent aucune entrée et ne mettent pas immédiatement l’OAM à jour ; transférez l’image préparée avec sprite_flush_oam.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
sprite_set_tile(5,129); // Select the green square beside ANIMATION.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Avec first_tile=128, deux images et deux appels par image, la première mise à jour renvoie la flèche 128 et la seconde le carré 129. Le carré près d’ANIMATION confirme l’application du résultat à l’OAM.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

sprite_set_tile: DMG
DMG
sprite_set_tile: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:60

Notes de déclaration (texte source)
Set a valid shadow slot's tile byte; allocation and hardware transfer are separate.

kitaqgb/lib/sprite.c:98

c
void sprite_set_tile(u8 id, u8 tile)
{
    if (sprite_valid(id) == 0) return;
    kq_sprite_oam[id].tile = tile;
}
sprite_warn_scanline_overflow

Compare sprite_max_scanline_count à la limite par ligne : 10 sprites sur GB et 8 sur FC. C’est une estimation logicielle, sans lecture de l’indicateur matériel de dépassement.

Syntaxe

c
u8 sprite_warn_scanline_overflow();

Valeur renvoyée

1 si l’estimation dépasse la limite par ligne, sinon 0.

Conditions et limites

Réglez kq_sprite_height sur la hauteur matérielle, 8 ou 16. L’estimation ignore transparence, visibilité horizontale et priorité. Sur FC, elle lit les coordonnées de la bibliothèque ; les modifications directes par les intrinsèques OAM n’y figurent pas.

L’exemple utilise la bibliothèque GB complète. KQ_SPRITE_MINIMAL_RUNTIME retire de sprite.c sprite_free, sprite_set_pos, sprite_count_used, les deux requêtes de lignes, metasprite_draw et anim_update. Ne le définissez pas si vous utilisez ces fonctions.

Exemple d’utilisation

c
sprite_example_expect(sprite_warn_scanline_overflow()==1);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

La rangée sous SCAN LIMIT commence en (8,128). Le programme soumet 11 sprites sur GB ou 9 sur FC, soit un de trop volontairement. Attendez 10 flèches visibles sur GB et 8 sur FC ; la dernière soumise est absente. Les vérifications du maximum logiciel et de l’avertissement doivent donner 11/9 et 1.

Ce programme présente allocation, positionnement, retournements, objets composés, superposition, animation et limite par ligne. Les deux chiffres en haut à droite doivent être 00 : toutes les vérifications internes ont réussi. Chaque flèche et carré occupe une tuile de 8×8.

NORMAL montre une flèche vers la droite en (88,16). FLIP X pointe à gauche en (88,32) ; FLIP Y retourne la flèche verticalement en (88,48). META place deux flèches en (88,64) et (96,64). OVERLAP place la flèche de (88,80) devant le carré de (92,80), visible à travers les pixels transparents. ANIMATION montre le carré en (88,96). Les zones (120,16) et (120,32) restent vides après masquage et libération de leurs entrées.

Sur CGB et FC, la flèche a une tige verte, un contour rouge et des détails bleus à la pointe ; le carré est vert. La transparence révèle le fond blanc du GB ou noir du FC. Le DMG remplace rouge, vert et bleu par gris clair, gris foncé et noir.

sprite_warn_scanline_overflow: DMG
DMG
sprite_warn_scanline_overflow: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite.h:75

Notes de déclaration (texte source)
Report whether the software overlap estimate exceeds ten sprites on a scanline.

kitaqgb/lib/sprite.c:182

c
u8 sprite_warn_scanline_overflow()
{
    return (u8)(sprite_max_scanline_count() > 10);
}

sprite_order.h — Sélection des sprites par priorité et rotation

sprite_order place les objets importants en premier et fait tourner l’ordre OAM à priorité égale. Il produit jusqu’à 40 objets parmi 255 candidats au plus, pour gérer la limite de dix par ligne. La bibliothèque sprite gère allocation et DMA ; sprite_order gère l’ordre de sélection.

Incluez sprite_order.h et compilez sprite_order.c une seule fois. Après initialisation, appelez chaque image begin, puis push pour chaque candidat, puis build. La bibliothèque d’ordre seule ne nécessite ni sprite.c ni définitions de variables globales.

Le matériel sélectionne les dix premiers objets croisant chaque ligne, dans l’ordre OAM. Placer d’abord les petites valeurs de priorité protège les objets importants sur une ligne chargée. La rotation ne garantit pas une fréquence d’affichage égale dans un même niveau. Si les objets prioritaires occupent les dix places, les autres restent invisibles sur cette ligne.

SpriteOrderOamEntry contient quatre octets : Y, X, tile et flags. Pour utiliser l’OAM en RAM de sprite.h, écrivez vers (SpriteOrderOamEntry*)kq_sprite_oam. Gardez SPRITE_MAX à 40 et ne mélangez pas les identités d’emplacement de l’allocateur avec la sortie réordonnée : build ne met pas ses comptes à jour.

sprite_order_begin

Vide le compteur de candidats pour une nouvelle image, en gardant stockage, hauteur et phase. Contrairement à une réinitialisation à chaque image, cela préserve la rotation.

Syntaxe

c
void sprite_order_begin(SpriteOrder* order);

Paramètres

order

Adresse d’un SpriteOrder appartenant à l’appelant. Initialisez-le avant utilisation et mettez-le à jour depuis le code principal.

Valeur renvoyée

Aucune valeur de retour. Un order nul est ignoré. Les anciens octets et l’OAM déjà construit ne sont pas effacés.

Conditions et limites

Incluez sprite_order.h et compilez sprite_order.c une seule fois. Après initialisation, appelez chaque image begin, puis push pour chaque candidat, puis build. La bibliothèque d’ordre seule ne nécessite ni sprite.c ni définitions de variables globales.

Le matériel sélectionne les dix premiers objets croisant chaque ligne, dans l’ordre OAM. Placer d’abord les petites valeurs de priorité protège les objets importants sur une ligne chargée. La rotation ne garantit pas une fréquence d’affichage égale dans un même niveau. Si les objets prioritaires occupent les dix places, les autres restent invisibles sur cette ligne.

Exemple d’utilisation

c
sprite_order_begin(&order_demo);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.

sprite_order_begin: DMG / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
DMG / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
sprite_order_begin: CGB / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
CGB / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
sprite_order_begin: CGB / phase 08 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
CGB / phase 08 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_order_demo.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_order_demo.gb --cgb=cgb --profile=dev --rst-disable --stack-bank=fixed --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite_order.h:42

Notes de déclaration (texte source)
Discard this frame's submissions while preserving storage, height and phase.
A null state is ignored. Call once before submitting the next frame's sprites.

kitaqgb/lib/sprite_order.c:24

c
void sprite_order_begin(SpriteOrder* order)
{
    if (order != 0) order->count = 0;
}
sprite_order_build

Construit 160 octets d’OAM en RAM selon priorité et ordre cyclique. Cache les places inutilisées en les mettant à zéro, puis avance la phase suivante. Le stockage des candidats n’est pas réordonné.

Syntaxe

c
u8 sprite_order_build(SpriteOrder* order, SpriteOrderOamEntry* output, u8 limit);

Paramètres

order

Adresse d’un SpriteOrder appartenant à l’appelant. Initialisez-le avant utilisation et mettez-le à jour depuis le code principal.

output

Tableau inscriptible de 40 SpriteOrderOamEntry. La fonction écrit les 160 octets même si limit vaut zéro ou moins de 40.

limit

Nombre maximal produit, de 0 à 40 ; au-delà, limité à 40. Limite l’OAM entier, pas chaque ligne.

Valeur renvoyée

Renvoie le nombre produit, de 0 à 40. Une file vide valide efface toutes les places et fixe phase=0. Sinon, normalise phase modulo count, utilise ce départ cyclique dans chaque niveau de priorité croissant, puis incrémente et reboucle phase. Une limite nulle avance encore la phase. order/output nul, état désactivé, hauteur invalide ou count>capacity renvoie zéro sans modifier sortie ni phase.

Conditions et limites

Le matériel sélectionne les dix premiers objets croisant chaque ligne, dans l’ordre OAM. Placer d’abord les petites valeurs de priorité protège les objets importants sur une ligne chargée. La rotation ne garantit pas une fréquence d’affichage égale dans un même niveau. Si les objets prioritaires occupent les dix places, les autres restent invisibles sur cette ligne.

L’argument priority règle l’ordre de sélection indépendamment de l’attribut derrière le fond. Sur DMG, les objets sélectionnés qui se chevauchent favorisent le plus petit X, puis l’ordre OAM en cas d’égalité. Le mode couleur CGB normal utilise OAM, mais une configuration de type DMG via OPRI reste applicable. La bibliothèque ne change pas ces règles matérielles.

SpriteOrderOamEntry contient quatre octets : Y, X, tile et flags. Pour utiliser l’OAM en RAM de sprite.h, écrivez vers (SpriteOrderOamEntry*)kq_sprite_oam. Gardez SPRITE_MAX à 40 et ne mélangez pas les identités d’emplacement de l’allocateur avec la sortie réordonnée : build ne met pas ses comptes à jour.

build écrit seulement en RAM. Fournissez un tableau de sortie de 160 octets sans chevauchement avec l’état ou les candidats. Un tampon DMA OAM doit commencer sur une frontière de 256 octets. Terminez la construction avant le transfert VBlank ; une interruption ne doit pas transférer un tampon incomplet. L’exemple utilise sprite_flush_oam.

Chaque ajout a un coût borné. La construction efface 160 octets d’OAM en RAM et parcourt le tableau de candidats au plus quatre fois, sans le trier ni utiliser de tampon de tri. Cela ne garantit pas que 255 candidats tiennent dans le budget d’une image ; ne soumettez que ceux nécessaires à la scène.

Exemple d’utilisation

c
order_demo_state[1]=sprite_order_build(&order_demo,(SpriteOrderOamEntry*)kq_sprite_oam,40);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.

sprite_order_build: DMG / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
DMG / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
sprite_order_build: CGB / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
CGB / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
sprite_order_build: CGB / phase 08 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
CGB / phase 08 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_order_demo.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_order_demo.gb --cgb=cgb --profile=dev --rst-disable --stack-bank=fixed --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite_order.h:62

Notes de déclaration (texte source)
Write a complete 160-byte shadow OAM: ascending priority, then cyclic order
within each priority. Clamp limit to 40, return the number emitted and zero
all unused entries (including Y) so they cannot consume scanline slots.
Advance phase once for a nonempty valid queue, even when limit is zero.
Empty queues reset phase to zero. Null/disabled/corrupt state or null output
returns 0 without modifying output or phase.
Output must provide 40 entries and must not overlap item/state storage.
This only writes RAM. Build in foreground, then transfer during VBlank.
DMG overlap priority also depends on X: this cannot override that hardware
rule. OAM order chooses the first ten sprites per scanline on both DMG/CGB.
It neither updates sprite_alloc's bookkeeping nor performs OAM DMA.

kitaqgb/lib/sprite_order.c:57

c
u8 sprite_order_build(SpriteOrder* order, SpriteOrderOamEntry* output, u8 limit)
{
    u8 i;
    u8 count;
    u8 phase;
    u8 priority;
    u8 visited;
    u8 written;
    SpriteOrderItem* item;
    if (order == 0 || output == 0) return 0;
    if (order->items == 0 || order->capacity == 0) return 0;
    if (order->count > order->capacity) return 0;
    if (order->height != 8 && order->height != 16) return 0;
    // Clear all hardware slots regardless of the requested emission limit.
    for (i = 0; i < SPRITE_ORDER_OAM_COUNT; i++) {
        output[i].y = 0;
        output[i].x = 0;
        output[i].tile = 0;
        output[i].flags = 0;
    }
    count = order->count;
    if (count == 0) {
        order->phase = 0;
        return 0;
    }
    if (limit > SPRITE_ORDER_OAM_COUNT) limit = SPRITE_ORDER_OAM_COUNT;
    phase = order->phase;
    while (phase >= count) phase = (u8)(phase - count);
    written = 0;
    for (priority = 0; priority < SPRITE_ORDER_LEVELS && written < limit; priority++) {
        i = phase;
        visited = 0;
        while (visited < count && written < limit) {
            item = &order->items[i];
            if (item->priority == priority) {
                output[written].y = item->oam.y;
                output[written].x = item->oam.x;
                output[written].tile = item->oam.tile;
                output[written].flags = item->oam.flags;
                written++;
            }
            visited++;
            i++;
            if (i >= count) i = 0;
        }
    }
    phase++;
    if (phase >= count) phase = 0;
    order->phase = phase;
    return written;
}
sprite_order_init

Associe le stockage des candidats à l’état d’ordre et remet à zéro compteur et phase de rotation. À utiliser au début d’une scène ou lors d’un changement de stockage.

Syntaxe

c
u8 sprite_order_init(SpriteOrder* order, SpriteOrderItem* items, u8 capacity, u8 height);

Paramètres

order

Adresse d’un SpriteOrder appartenant à l’appelant. Initialisez-le avant utilisation et mettez-le à jour depuis le code principal.

items

Tableau SpriteOrderItem inscriptible, cinq octets par entrée. Allouez capacity entrées et gardez le stockage valide pendant l’utilisation.

capacity

Capacité du tableau, de 1 à 255 entrées ; ni un nombre d’octets ni le nombre de places matérielles.

height

La hauteur est commune à tous les objets. Passez 8 ou 16 selon le mode LCDC 8×8/8×16 ; la bibliothèque ne règle pas LCDC. En mode 8×16, le matériel ignore le bit bas du numéro de tuile.

Valeur renvoyée

Renvoie 1 en cas de succès, 0 si items est nul, capacité nulle, hauteur autre que 8/16 ou order nul. Si order existe, l’échec le désactive : items=NULL, capacity=count=phase=0, height=8. Le tableau reste intact.

Conditions et limites

Incluez sprite_order.h et compilez sprite_order.c une seule fois. Après initialisation, appelez chaque image begin, puis push pour chaque candidat, puis build. La bibliothèque d’ordre seule ne nécessite ni sprite.c ni définitions de variables globales.

Exemple d’utilisation

c
sprite_init();sprite_order_init(&order_demo,order_demo_items,14,8);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.

sprite_order_init: DMG / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
DMG / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
sprite_order_init: CGB / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
CGB / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
sprite_order_init: CGB / phase 08 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
CGB / phase 08 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_order_demo.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_order_demo.gb --cgb=cgb --profile=dev --rst-disable --stack-bank=fixed --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite_order.h:38

Notes de déclaration (texte source)
Bind writable item storage and select the hardware sprite height (8 or 16).
Return 1 on success. Invalid storage, zero capacity or another height returns
0 and leaves a non-null state disabled. A null state returns 0 without writes.

kitaqgb/lib/sprite_order.c:6

c
u8 sprite_order_init(SpriteOrder* order, SpriteOrderItem* items, u8 capacity, u8 height)
{
    if (order == 0) return 0;
    order->items = 0;
    order->capacity = 0;
    order->count = 0;
    order->height = 8;
    order->phase = 0;
    if (items == 0 || capacity == 0) return 0;
    if (height != 8 && height != 16) return 0;
    order->items = items;
    order->capacity = capacity;
    order->height = height;
    return 1;
}
sprite_order_push

Soumet un sprite croisant l’écran visible d’au moins un pixel. Les candidats entièrement hors écran sont rejetés avant de consommer une place OAM.

Syntaxe

c
u8 sprite_order_push(SpriteOrder* order, s16 x, s16 y, u8 tile, u8 flags, u8 priority);

Paramètres

order

Adresse d’un SpriteOrder appartenant à l’appelant. Initialisez-le avant utilisation et mettez-le à jour depuis le code principal.

x

X écran signé depuis le coin supérieur gauche. Les bords gauches −7..159 sont acceptés ; ≤−8 ou ≥160 est entièrement hors écran. Le stockage ajoute 8 pour les coordonnées OAM.

y

Y écran signé depuis le coin supérieur gauche. Plage acceptée : −7..143 pour hauteur 8, −15..143 pour hauteur 16. Le stockage ajoute 16 pour OAM.

tile

Numéro de tuile de 0 à 255, stocké tel quel. Voir les notes de hauteur pour le mode 8×16.

flags

Octet d’attribut matériel stocké tel quel : retournements, priorité derrière le fond, palette DMG/CGB et banque VRAM CGB gardent leur sens matériel habituel.

priority

Priorité logicielle de sélection de 0 à 3, zéro en premier. À partir de quatre, la valeur est rejetée. Distincte de l’octet matériel flags.

Valeur renvoyée

Renvoie 1 et incrémente count si accepté. État nul/désactivé, hauteur invalide, stockage plein, priorité invalide ou objet entièrement hors écran : renvoie 0 sans changer items ni count.

Conditions et limites

La hauteur est commune à tous les objets. Passez 8 ou 16 selon le mode LCDC 8×8/8×16 ; la bibliothèque ne règle pas LCDC. En mode 8×16, le matériel ignore le bit bas du numéro de tuile.

Le matériel sélectionne les dix premiers objets croisant chaque ligne, dans l’ordre OAM. Placer d’abord les petites valeurs de priorité protège les objets importants sur une ligne chargée. La rotation ne garantit pas une fréquence d’affichage égale dans un même niveau. Si les objets prioritaires occupent les dix places, les autres restent invisibles sur cette ligne.

L’argument priority règle l’ordre de sélection indépendamment de l’attribut derrière le fond. Sur DMG, les objets sélectionnés qui se chevauchent favorisent le plus petit X, puis l’ordre OAM en cas d’égalité. Le mode couleur CGB normal utilise OAM, mais une configuration de type DMG via OPRI reste applicable. La bibliothèque ne change pas ces règles matérielles.

Exemple d’utilisation

c
sprite_order_push(&order_demo,8,64,128,0,0);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.

sprite_order_push: DMG / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
DMG / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
sprite_order_push: CGB / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
CGB / phase 04 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
sprite_order_push: CGB / phase 08 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.
CGB / phase 08 — Cette leçon place quatorze objets sur une ligne. Les deux losanges sous HIGH sont prioritaires ; les douze carrés sous NORMAL sont ordinaires. Sur CGB, les losanges sont rouges et les carrés bleus ; sur DMG, gris et noirs. Les deux losanges restent visibles, mais seulement huit carrés apparaissent. 0..B repère les positions : PHASE 04 montre 4..B ; PHASE 08 montre 8..B et 0..3. La version normale avance PHASE toutes les 60 attentes d’image. Les captures fixent la phase du même programme ; la version animée a aussi été vérifiée.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\sprite_order_demo.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\sprite_order_demo.gb --cgb=cgb --profile=dev --rst-disable --stack-bank=fixed --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/sprite_order.h:49

Notes de déclaration (texte source)
Submit one sprite at signed, top-left SCREEN pixel coordinates. Preserve the
tile and attribute bytes; use priority 0 (first) through 3 (last). Fully
off-screen sprites, invalid priorities, disabled state and full storage return
0 without consuming a slot. Partly visible sprites are accepted. Return 1 on
acceptance. Hardware 8x16 mode still ignores the tile index's low bit.

kitaqgb/lib/sprite_order.c:31

c
u8 sprite_order_push(SpriteOrder* order, s16 x, s16 y, u8 tile, u8 flags, u8 priority)
{
    SpriteOrderItem* item;
    if (order == 0) return 0;
    if (order->items == 0 || order->capacity == 0) return 0;
    if (order->height != 8 && order->height != 16) return 0;
    if (order->count >= order->capacity || priority >= SPRITE_ORDER_LEVELS) return 0;
    if (x <= -8 || x >= 160 || y >= 144) return 0;
    if (order->height == 16) {
        if (y <= -16) return 0;
    } else {
        if (y <= -8) return 0;
    }
    item = &order->items[order->count];
    item->oam.y = (u8)(y + 16);
    item->oam.x = (u8)(x + 8);
    item->oam.tile = tile;
    item->oam.flags = flags;
    item->priority = priority;
    order->count++;
    return 1;
}

system.h — Démarrage, compteurs d'images, attentes et interruptions

Gère le nombre d’attentes de trame, les fonctions de rappel après attente et les interruptions CPU masquables.

gb_disable_interrupts

gb_disable_interrupts est un alias de system_disable_interrupts. Désactive les interruptions CPU sur GB.

Désactive les interruptions masquables du processeur.

Syntaxe

c
void gb_disable_interrupts();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

L’en-tête définit une macro objet qui se développe en nom d’implémentation. Arguments, résultats et accès à l’état sont identiques à ceux de la cible ; l’alias n’ajoute aucun état ni traitement distinct. Utilisez input.h/input.c pour les entrées ou system.h/system.c pour les services d’images, comme dans l’exemple complet et sa commande de compilation.

Gardez les mises à jour protégées aussi courtes que possible et rétablissez ensuite les interruptions de manière appropriée. Le masquage des interruptions est distinct des conditions requises par une routine d’attente de trame.

Sur GB, l’attente se termine immédiatement si le LCD est éteint, mais la fonction enveloppante incrémente tout de même son compteur et appelle sa fonction de rappel. L’initialisation seule ne configure ni le LCD ni les sources d’interruption.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

system_disable_interrupts

Exemple d’utilisation

c
gb_disable_interrupts();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple associe désactivation et réactivation. Des programmes de vérification dédiés examinent aussi l’état des interruptions du processeur.

gb_disable_interrupts: DMG
DMG
gb_disable_interrupts: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\system_aliases.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\system_aliases.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/system.h:32

c
#define gb_disable_interrupts system_disable_interrupts

kitaqgb/lib/system.c:52

c
void system_disable_interrupts()
{
    __asm {
        DI
        RET
    }
}
gb_enable_interrupts

gb_enable_interrupts est un alias de system_enable_interrupts. Active les interruptions CPU sur GB.

Active les interruptions masquables du processeur.

Syntaxe

c
void gb_enable_interrupts();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

L’en-tête définit une macro objet qui se développe en nom d’implémentation. Arguments, résultats et accès à l’état sont identiques à ceux de la cible ; l’alias n’ajoute aucun état ni traitement distinct. Utilisez input.h/input.c pour les entrées ou system.h/system.c pour les services d’images, comme dans l’exemple complet et sa commande de compilation.

Préparez les sources d’interruption et leurs gestionnaires avant de les activer. Sur FC, cette opération est indépendante de l’activation ou de la désactivation de la NMI.

Sur GB, l’attente se termine immédiatement si le LCD est éteint, mais la fonction enveloppante incrémente tout de même son compteur et appelle sa fonction de rappel. L’initialisation seule ne configure ni le LCD ni les sources d’interruption.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

system_enable_interrupts

Exemple d’utilisation

c
gb_enable_interrupts();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple rétablit les interruptions. Le programme FC désactive d’abord les sources IRQ de trame APU et DMC pour éviter de traiter en boucle une IRQ non acquittée.

gb_enable_interrupts: DMG
DMG
gb_enable_interrupts: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\system_aliases.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\system_aliases.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/system.h:31

c
#define gb_enable_interrupts system_enable_interrupts

kitaqgb/lib/system.c:43

c
void system_enable_interrupts()
{
    __asm {
        EI
        RET
    }
}
gb_frame_count

gb_frame_count est un alias de system_get_frame. Lit le compteur logiciel 16 bits des attentes terminées par la fonction d’encapsulation.

Lit le compteur sur 16 bits de la fonction d’attente de trame.

Syntaxe

c
u16 gb_frame_count();

Valeur renvoyée

Renvoie la valeur courante du compteur, de 0 à 65535.

Conditions et limites

L’en-tête définit une macro objet qui se développe en nom d’implémentation. Arguments, résultats et accès à l’état sont identiques à ceux de la cible ; l’alias n’ajoute aucun état ni traitement distinct. Utilisez input.h/input.c pour les entrées ou system.h/system.c pour les services d’images, comme dans l’exemple complet et sa commande de compilation.

Le compteur dénombre les attentes effectuées par cette fonction d’encapsulation ; il ne mesure pas automatiquement les trames réellement écoulées sur le matériel. Il revient à zéro après débordement sur 16 bits.

Sur GB, l’attente se termine immédiatement si le LCD est éteint, mais la fonction enveloppante incrémente tout de même son compteur et appelle sa fonction de rappel. L’initialisation seule ne configure ni le LCD ni les sources d’interruption.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

system_get_frame

Exemple d’utilisation

c
result[3]=gb_frame_count();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple lit trois après trois attentes. Pour tester le rebouclage, il fixe explicitement le compteur à 65535 et vérifie qu’il vaut zéro après l’attente suivante.

gb_frame_count: DMG
DMG
gb_frame_count: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\system_aliases.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\system_aliases.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/system.h:30

c
#define gb_frame_count system_get_frame

kitaqgb/lib/system.c:31

c
u16 system_get_frame()
{
    return kq_system_frame;
}
gb_init

gb_init est un alias de system_init. Réinitialise le compteur logiciel d’images et l’enregistrement du rappel.

Initialise la gestion des trames en remettant le compteur à zéro et en supprimant la fonction de rappel enregistrée.

Syntaxe

c
void gb_init();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

L’en-tête définit une macro objet qui se développe en nom d’implémentation. Arguments, résultats et accès à l’état sont identiques à ceux de la cible ; l’alias n’ajoute aucun état ni traitement distinct. Utilisez input.h/input.c pour les entrées ou system.h/system.c pour les services d’images, comme dans l’exemple complet et sa commande de compilation.

Le compteur dénombre les attentes effectuées par cette fonction d’encapsulation ; il ne mesure pas automatiquement les trames réellement écoulées sur le matériel. Il revient à zéro après débordement sur 16 bits.

Sur GB, l’attente se termine immédiatement si le LCD est éteint, mais la fonction enveloppante incrémente tout de même son compteur et appelle sa fonction de rappel. L’initialisation seule ne configure ni le LCD ni les sources d’interruption.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

system_init

Exemple d’utilisation

c
gb_init();result[0]=gb_frame_count();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple vérifie que le numéro de trame initial est nul avant d’enregistrer sa fonction de rappel.

gb_init: DMG
DMG
gb_init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\system_aliases.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\system_aliases.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/system.h:27

c
#define gb_init system_init

kitaqgb/lib/system.c:7

c
void system_init()
{
    kq_system_frame = 0;
    system_vblank_callback = 0;
}
gb_set_vblank_callback

gb_set_vblank_callback est un alias de system_set_vblank_callback. Enregistre ou supprime le rappel exécuté de manière synchrone après une attente d’image.

Enregistre, remplace ou supprime la fonction appelée après une attente de trame.

Syntaxe

c
void gb_set_vblank_callback(SystemCallback callback);

Paramètres

callback

Fonction à appeler ; 0 supprime le rappel.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

L’en-tête définit une macro objet qui se développe en nom d’implémentation. Arguments, résultats et accès à l’état sont identiques à ceux de la cible ; l’alias n’ajoute aucun état ni traitement distinct. Utilisez input.h/input.c pour les entrées ou system.h/system.c pour les services d’images, comme dans l’exemple complet et sa commande de compilation.

Il s’agit d’un pointeur ordinaire vers une fonction sans argument ni valeur de retour. Il ne contient pas de numéro de banque ; le code cible doit rester mappé tant qu’un appel est possible.

Sur GB, l’attente se termine immédiatement si le LCD est éteint, mais la fonction enveloppante incrémente tout de même son compteur et appelle sa fonction de rappel. L’initialisation seule ne configure ni le LCD ni les sources d’interruption.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

system_set_vblank_callback

Exemple d’utilisation

c
gb_set_vblank_callback(on_frame);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Après trois appels du rappel, enregistrer 0 le désactive. L’attente suivante porte le compteur de trames à quatre, tandis que le nombre d’appels reste trois.

gb_set_vblank_callback: DMG
DMG
gb_set_vblank_callback: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\system_aliases.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\system_aliases.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/system.h:29

c
#define gb_set_vblank_callback system_set_vblank_callback

kitaqgb/lib/system.c:25

c
void system_set_vblank_callback(SystemCallback callback)
{
    system_vblank_callback = callback;
}
gb_wait_vblank

gb_wait_vblank est un alias de system_wait_vblank. Attend la limite d’image, incrémente le compteur logiciel et appelle le rappel enregistré.

Attend la trame suivante, incrémente le compteur, puis appelle la fonction de rappel enregistrée.

Syntaxe

c
void gb_wait_vblank();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

L’en-tête définit une macro objet qui se développe en nom d’implémentation. Arguments, résultats et accès à l’état sont identiques à ceux de la cible ; l’alias n’ajoute aucun état ni traitement distinct. Utilisez input.h/input.c pour les entrées ou system.h/system.c pour les services d’images, comme dans l’exemple complet et sa commande de compilation.

Le rappel s’exécute de manière synchrone à l’intérieur de cette fonction ; son enregistrement n’installe pas de gestionnaire d’interruption. Le compteur dénombre les attentes effectuées par cette fonction d’encapsulation, sans mesurer automatiquement les trames matérielles écoulées. Il revient à zéro après débordement sur 16 bits.

Sur GB, l’attente se termine immédiatement si le LCD est éteint, mais la fonction enveloppante incrémente tout de même son compteur et appelle sa fonction de rappel. L’initialisation seule ne configure ni le LCD ni les sources d’interruption.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

system_wait_vblank

Exemple d’utilisation

c
gb_wait_vblank();gb_wait_vblank();gb_wait_vblank();result[1]=frame_calls;result[2]=frame_seen;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Trois attentes déclenchent trois appels du rappel, et la dernière valeur du compteur observée dans celui-ci est trois.

gb_wait_vblank: DMG
DMG
gb_wait_vblank: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\system_aliases.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\system_aliases.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/system.h:28

c
#define gb_wait_vblank system_wait_vblank

kitaqgb/lib/system.c:15

c
void system_wait_vblank()
{
    __wait_vblank();
    kq_system_frame++;
    if (system_vblank_callback != 0) {
        system_vblank_callback();
    }
}
system_disable_interrupts

Désactive les interruptions masquables du processeur.

Syntaxe

c
void system_disable_interrupts();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Gardez les mises à jour protégées aussi courtes que possible et rétablissez ensuite les interruptions de manière appropriée. Le masquage des interruptions est distinct des conditions requises par une routine d’attente de trame.

Sur GB, l’attente se termine immédiatement si le LCD est éteint, mais la fonction enveloppante incrémente tout de même son compteur et appelle sa fonction de rappel. L’initialisation seule ne configure ni le LCD ni les sources d’interruption.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
system_disable_interrupts();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple associe désactivation et réactivation. Des programmes de vérification dédiés examinent aussi l’état des interruptions du processeur.

system_disable_interrupts: DMG
DMG
system_disable_interrupts: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/system.h:25

Notes de déclaration (texte source)
Disable CPU interrupts and return; callers must explicitly re-enable them later.

kitaqgb/lib/system.c:52

c
void system_disable_interrupts()
{
    __asm {
        DI
        RET
    }
}
system_enable_interrupts

Active les interruptions masquables du processeur.

Syntaxe

c
void system_enable_interrupts();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Préparez les sources d’interruption et leurs gestionnaires avant de les activer. Sur FC, cette opération est indépendante de l’activation ou de la désactivation de la NMI.

Sur GB, l’attente se termine immédiatement si le LCD est éteint, mais la fonction enveloppante incrémente tout de même son compteur et appelle sa fonction de rappel. L’initialisation seule ne configure ni le LCD ni les sources d’interruption.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
system_enable_interrupts();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple rétablit les interruptions. Le programme FC désactive d’abord les sources IRQ de trame APU et DMC pour éviter de traiter en boucle une IRQ non acquittée.

system_enable_interrupts: DMG
DMG
system_enable_interrupts: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/system.h:23

Notes de déclaration (texte source)
Enable CPU interrupts and return using the inline-assembly function body.

kitaqgb/lib/system.c:43

c
void system_enable_interrupts()
{
    __asm {
        EI
        RET
    }
}
system_get_frame

Lit le compteur sur 16 bits de la fonction d’attente de trame.

Syntaxe

c
u16 system_get_frame();

Valeur renvoyée

Renvoie la valeur courante du compteur, de 0 à 65535.

Conditions et limites

Le compteur dénombre les attentes effectuées par cette fonction d’encapsulation ; il ne mesure pas automatiquement les trames réellement écoulées sur le matériel. Il revient à zéro après débordement sur 16 bits.

Sur GB, l’attente se termine immédiatement si le LCD est éteint, mais la fonction enveloppante incrémente tout de même son compteur et appelle sa fonction de rappel. L’initialisation seule ne configure ni le LCD ni les sources d’interruption.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
result[3]=system_get_frame();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple lit trois après trois attentes. Pour tester le rebouclage, il fixe explicitement le compteur à 65535 et vérifie qu’il vaut zéro après l’attente suivante.

system_get_frame: DMG
DMG
system_get_frame: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/system.h:19

Notes de déclaration (texte source)
Read the software count of completed system_wait_vblank calls.

kitaqgb/lib/system.c:31

c
u16 system_get_frame()
{
    return kq_system_frame;
}
system_get_frame8

Lit les huit bits de poids faible du compteur de trames pour gérer de courts intervalles répétitifs.

Syntaxe

c
u8 system_get_frame8();

Valeur renvoyée

Renvoie l’octet de poids faible, de 0 à 255.

Conditions et limites

Le compteur dénombre les attentes effectuées par cette fonction d’encapsulation ; il ne mesure pas automatiquement les trames réellement écoulées sur le matériel. Il revient à zéro après débordement sur 16 bits.

Sur GB, l’attente se termine immédiatement si le LCD est éteint, mais la fonction enveloppante incrémente tout de même son compteur et appelle sa fonction de rappel. L’initialisation seule ne configure ni le LCD ni les sources d’interruption.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
result[4]=system_get_frame8();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple lit trois après trois attentes, puis zéro lorsque le compteur sur 16 bits revient à zéro.

system_get_frame8: DMG
DMG
system_get_frame8: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/system.h:21

Notes de déclaration (texte source)
Return the low byte of the software frame counter for wrapping 8-bit timing.

kitaqgb/lib/system.c:37

c
u8 system_get_frame8()
{
    return (u8)kq_system_frame;
}
system_init

Initialise la gestion des trames en remettant le compteur à zéro et en supprimant la fonction de rappel enregistrée.

Syntaxe

c
void system_init();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Le compteur dénombre les attentes effectuées par cette fonction d’encapsulation ; il ne mesure pas automatiquement les trames réellement écoulées sur le matériel. Il revient à zéro après débordement sur 16 bits.

Sur GB, l’attente se termine immédiatement si le LCD est éteint, mais la fonction enveloppante incrémente tout de même son compteur et appelle sa fonction de rappel. L’initialisation seule ne configure ni le LCD ni les sources d’interruption.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
system_init();result[0]=system_get_frame();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

L’exemple vérifie que le numéro de trame initial est nul avant d’enregistrer sa fonction de rappel.

system_init: DMG
DMG
system_init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/system.h:12

Notes de déclaration (texte source)
Reset the software frame counter and remove any registered callback.

kitaqgb/lib/system.c:7

c
void system_init()
{
    kq_system_frame = 0;
    system_vblank_callback = 0;
}
system_set_vblank_callback

Enregistre, remplace ou supprime la fonction appelée après une attente de trame.

Syntaxe

c
void system_set_vblank_callback(SystemCallback callback);

Paramètres

callback

Fonction à appeler ; 0 supprime le rappel.

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Il s’agit d’un pointeur ordinaire vers une fonction sans argument ni valeur de retour. Il ne contient pas de numéro de banque ; le code cible doit rester mappé tant qu’un appel est possible.

Sur GB, l’attente se termine immédiatement si le LCD est éteint, mais la fonction enveloppante incrémente tout de même son compteur et appelle sa fonction de rappel. L’initialisation seule ne configure ni le LCD ni les sources d’interruption.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
system_set_vblank_callback(on_frame);

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Après trois appels du rappel, enregistrer 0 le désactive. L’attente suivante porte le compteur de trames à quatre, tandis que le nombre d’appels reste trois.

system_set_vblank_callback: DMG
DMG
system_set_vblank_callback: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/system.h:17

Notes de déclaration (texte source)
Replace the callback used by system_wait_vblank; null disables the callback.

kitaqgb/lib/system.c:25

c
void system_set_vblank_callback(SystemCallback callback)
{
    system_vblank_callback = callback;
}
system_wait_vblank

Attend la trame suivante, incrémente le compteur, puis appelle la fonction de rappel enregistrée.

Syntaxe

c
void system_wait_vblank();

Valeur renvoyée

Aucune valeur de retour.

Conditions et limites

Le rappel s’exécute de manière synchrone à l’intérieur de cette fonction ; son enregistrement n’installe pas de gestionnaire d’interruption. Le compteur dénombre les attentes effectuées par cette fonction d’encapsulation, sans mesurer automatiquement les trames matérielles écoulées. Il revient à zéro après débordement sur 16 bits.

Sur GB, l’attente se termine immédiatement si le LCD est éteint, mais la fonction enveloppante incrémente tout de même son compteur et appelle sa fonction de rappel. L’initialisation seule ne configure ni le LCD ni les sources d’interruption.

Compilez cet exemple complet avec l’ABI Legacy par défaut. Ses rappels utilisent des appels par pointeur de fonction, non pris en charge et refusés par le compilateur avec --abi=stack. La même restriction s’applique aux alias.

Exemple d’utilisation

c
system_wait_vblank();system_wait_vblank();system_wait_vblank();result[1]=frame_calls;result[2]=frame_seen;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Trois attentes déclenchent trois appels du rappel, et la dernière valeur du compteur observée dans celui-ci est trois.

system_wait_vblank: DMG
DMG
system_wait_vblank: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\batch_services.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\batch_services.gb --no-cache --no-disasm --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --cart=mbc5 --romsize=64k
Implémentation et source

kitaqgb/lib/system.h:15

Notes de déclaration (texte source)
Wait for VBlank, count this wrapper call, then invoke the callback synchronously.
The counter wraps at 16 bits and is not an independent hardware frame clock.

kitaqgb/lib/system.c:15

c
void system_wait_vblank()
{
    __wait_vblank();
    kq_system_frame++;
    if (system_vblank_callback != 0) {
        system_vblank_callback();
    }
}

vram.h — Mises à jour et transferts VRAM en file

Initialise à vide la file des écritures VRAM différées et efface son indicateur de débordement. Ne vide pas l’écran, ne charge pas de graphismes et n’alloue pas de VRAM physique.

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Attend avec __wait_vblank, puis appelle vram_flush_now. Convient à un lot modéré de changements d’écran. Une seule attente n’impose pas de budget de transfert et ne garantit pas la fin de tout le lot dans un VBlank.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

vram_clear_queue

Abandonne les commandes VRAM en attente et efface le débordement sans effectuer les écritures.

Syntaxe

c
void vram_clear_queue();

Valeur renvoyée

Aucune (void).

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Exemple d’utilisation

c
vram_clear_queue();
if (vram_get_queue_used()!=0 || vram_get_overflowed()!=0) failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_clear_queue: DMG
DMG
vram_clear_queue: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:41

Notes de déclaration (texte source)
Discard pending commands and clear the latched overflow flag without writing VRAM.

kitaqgb/lib/vram.c:41

c
void vram_clear_queue()
{
    kq_vram_queue_used = 0;
    kq_vram_queue_overflowed = 0;
}
vram_flush

Attend avec __wait_vblank, puis appelle vram_flush_now. Convient à un lot modéré de changements d’écran. Une seule attente n’impose pas de budget de transfert et ne garantit pas la fin de tout le lot dans un VBlank.

Syntaxe

c
void vram_flush();

Valeur renvoyée

Aucune (void).

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Adresse de destination en octets dans la VRAM (0x8000–0x9FFF), dans la banque sélectionnée à l’exécution. Le transfert est contigu, sans saut de ligne. Toute la plage doit être valide. LCD actif, les chemins d’écriture sûrs peuvent activer les interruptions ; ils ne préservent pas un état d’appel où elles étaient désactivées.

Exemple d’utilisation

c
vram_flush(); // One small write through the VBlank/NMI path.

if (vram_get_queue_used()!=0) failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_flush: DMG
DMG
vram_flush: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:64

Notes de déclaration (texte source)
Wait for VBlank before executing the queue. Waiting once does not itself limit
the queued workload to the available VBlank duration.

kitaqgb/lib/vram.c:148

c
void vram_flush()
{
    __wait_vblank();
    vram_flush_now();
}
vram_flush_now

Exécute tous les ordres dans leur ordre d’ajout, puis remet le nombre utilisé à zéro. N’attend pas elle-même le VBlank. LCD actif, les fonctions intrinsèques sûres attendent les périodes d’écriture, mais une grande file peut s’étendre sur plusieurs lignes ou images. L’indicateur de débordement reste mémorisé.

Syntaxe

c
void vram_flush_now();

Valeur renvoyée

Aucune (void).

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Adresse de destination en octets dans la VRAM (0x8000–0x9FFF), dans la banque sélectionnée à l’exécution. Le transfert est contigu, sans saut de ligne. Toute la plage doit être valide. LCD actif, les chemins d’écriture sûrs peuvent activer les interruptions ; ils ne préservent pas un état d’appel où elles étaient désactivées.

Exemple d’utilisation

c
// Rendering is stopped here. On FC, commit readiness before direct execution.

vram_flush_now();
after_flush=vram_get_queue_used();
if (after_flush!=0) failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_flush_now: DMG
DMG
vram_flush_now: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:61

Notes de déclaration (texte source)
Execute pending commands in insertion order without waiting for VBlank here.
The caller must arrange suitable VRAM access timing and a sufficient transfer budget.
Only the used count is cleared; overflow stays latched until an explicit reset.

kitaqgb/lib/vram.c:125

c
void vram_flush_now()
{
    u8 i = 0;
    while (i < kq_vram_queue_used) {
        VramCommand* cmd = &kq_vram_queue[(__safe_index u8)i];
        if (cmd->kind == VRAM_CMD_BG_TILE) {
            __settile_xy(cmd->x, cmd->y, cmd->value);
        } else if (cmd->kind == VRAM_CMD_BG_RECT) {
            __settile_rect(cmd->x, cmd->y, cmd->w, cmd->h, cmd->value);
        } else if (cmd->kind == VRAM_CMD_BG_BLOCK) {
            __settilemap_rect(cmd->dst, cmd->x, cmd->y, cmd->w, cmd->h, cmd->src);
        } else if (cmd->kind == VRAM_CMD_MEMCPY) {
            __vram_copy(cmd->dst, cmd->src, cmd->len);
        } else if (cmd->kind == VRAM_CMD_MEMSET) {
            __vram_fill(cmd->dst, cmd->value, cmd->len);
        }
        i++;
    }
    kq_vram_queue_used = 0;
}
vram_get_overflowed

Lit le drapeau de débordement sans l’effacer ; il peut conserver un échec antérieur.

Syntaxe

c
u8 vram_get_overflowed();

Valeur renvoyée

0 si aucun débordement n’est mémorisé ; 1 après un ajout rejeté, jusqu’à une remise à zéro explicite. L’exécution de la file ne l’efface pas.

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Exemple d’utilisation

c
overflow_seen=vram_get_overflowed();
if (overflow_seen!=1) failures++;
// Reading the latch again does not clear it.
if (vram_get_overflowed()!=1) failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_get_overflowed: DMG
DMG
vram_get_overflowed: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:73

Notes de déclaration (texte source)
Read the overflow latch without clearing it.

kitaqgb/lib/vram.c:175

c
u8 vram_get_overflowed()
{
    return kq_vram_queue_overflowed;
}
vram_get_queue_capacity

Consultez les changements et vérifications du 2026-10-03 pour les différences locales de cette API.

Renvoie la capacité totale du tampon d’ordres, quelle que soit son occupation actuelle.

Syntaxe

c
u8 vram_get_queue_capacity();

Valeur renvoyée

Un octet non signé dans les unités propres à la plateforme décrites ici. Sa lecture ne modifie ni n’exécute la file.

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Exemple d’utilisation

c
capacity=vram_get_queue_capacity();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_get_queue_capacity: DMG
DMG
vram_get_queue_capacity: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:69

Notes de déclaration (texte source)
Return the total number of command slots, independent of queue usage.
This is command-buffer capacity, not free space in hardware VRAM.

kitaqgb/lib/vram.c:162

c
u8 vram_get_queue_capacity()
{
    return VRAM_QUEUE_MAX;
}
vram_get_queue_free

Renvoie la capacité totale moins l’occupation actuelle. Vérifiez avant l’ajout que le prochain enregistrement ou lot tient entièrement ; cette lecture ne réserve aucune place.

Syntaxe

c
u8 vram_get_queue_free();

Valeur renvoyée

Un octet non signé dans les unités propres à la plateforme décrites ici. Sa lecture ne modifie ni n’exécute la file.

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Exemple d’utilisation

c
available=vram_get_queue_free();
if (used+available!=capacity) failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_get_queue_free: DMG
DMG
vram_get_queue_free: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:71

Notes de déclaration (texte source)
Return the remaining command-slot capacity.

kitaqgb/lib/vram.c:169

c
u8 vram_get_queue_free()
{
    return (u8)(VRAM_QUEUE_MAX - kq_vram_queue_used);
}
vram_get_queue_used

Renvoie l’espace du tampon occupé par les ordres en attente, pas le nombre d’octets qui seront écrits en mémoire vidéo.

Syntaxe

c
u8 vram_get_queue_used();

Valeur renvoyée

Un octet non signé dans les unités propres à la plateforme décrites ici. Sa lecture ne modifie ni n’exécute la file.

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Exemple d’utilisation

c
used=vram_get_queue_used();

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_get_queue_used: DMG
DMG
vram_get_queue_used: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:66

Notes de déclaration (texte source)
Return the number of queued commands, not the number of transfer bytes.

kitaqgb/lib/vram.c:155

c
u8 vram_get_queue_used()
{
    return kq_vram_queue_used;
}
vram_init

Initialise à vide la file des écritures VRAM différées et efface son indicateur de débordement. Ne vide pas l’écran, ne charge pas de graphismes et n’alloue pas de VRAM physique.

Syntaxe

c
void vram_init();

Valeur renvoyée

Aucune (void).

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Exemple d’utilisation

c
vram_init();
if (vram_get_queue_used()!=0 || vram_get_overflowed()!=0) failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_init: DMG
DMG
vram_init: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:39

Notes de déclaration (texte source)
Start with an empty command queue and a clear overflow flag.

kitaqgb/lib/vram.c:34

c
void vram_init()
{
    kq_vram_queue_used = 0;
    kq_vram_queue_overflowed = 0;
}
vram_queue_bg_block

Ajoute à la file un rectangle de w × h numéros de tuile de src vers la carte en base. Chaque ligne source contient w octets contigus ; les lignes de destination sont espacées de 32 octets. Le pointeur est conservé : modifier la source avant l’exécution change le bloc affiché.

Syntaxe

c
u8 vram_queue_bg_block(u16 base, u8 x, u8 y, u8 w, u8 h, const u8* src);

Paramètres

base

Les ordres de tuile et de rectangle choisissent la carte de fond selon le bit 3 de LCDC à l’exécution. Sur CGB, utilisez la banque VRAM 0 pour les indices de tuile. Le bloc utilise la base indiquée, normalement 0x9800 ou 0x9C00. Le pas entre lignes est de 32 octets ; les coordonnées ne sont pas bornées automatiquement.

x, y

Coordonnées du coin supérieur gauche en tuiles de 8×8, pas en pixels. Aucun découpage. Gardez x + w <= 32 et y + h <= 32 sur GB, ou <= 30 dans la zone de tuiles d’une nametable FC. Une tuile seule a une largeur et une hauteur de 1.

w, h

Largeur et hauteur en tuiles, sur des octets non signés. Le bloc source contient w * h octets par lignes. Une dimension nulle ne produit aucune écriture visible, mais l’occupation de la file suit les règles de la plateforme.

src

Pointeur proche vers des octets lisibles, conservé jusqu’à l’exécution. Gardez les données vivantes et leur banque mémoire ou ROM accessible pendant tout le traitement ; aucun numéro de banque ni copie n’est mémorisé. Un transfert non vide exige une source valide. N’utilisez pas un tableau local dont la durée de vie est terminée.

Valeur renvoyée

1 si cet ordre a été ajouté, 0 si aucune place n’était libre. Un échec mémorise le débordement sans toucher aux ordres existants. Un débordement antérieur ne fait pas renvoyer 0 à un ajout ultérieur réussi.

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Les ordres de tuile et de rectangle choisissent la carte de fond selon le bit 3 de LCDC à l’exécution. Sur CGB, utilisez la banque VRAM 0 pour les indices de tuile. Le bloc utilise la base indiquée, normalement 0x9800 ou 0x9C00. Le pas entre lignes est de 32 octets ; les coordonnées ne sont pas bornées automatiquement.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Exemple d’utilisation

c
check_result=vram_queue_bg_block(MAP_BASE,10,4,3,2,block);
block[0]=1; // The queued pointer sees this change when the queue executes.
if (check_result!=1) failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_queue_bg_block: DMG
DMG
vram_queue_bg_block: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:50

Notes de déclaration (texte source)
Queue a tile-map rectangle while retaining src rather than copying its bytes.
Keep the source data and its ROM bank accessible until the queue is flushed.

kitaqgb/lib/vram.c:79

c
u8 vram_queue_bg_block(u16 base, u8 x, u8 y, u8 w, u8 h, const u8* src)
{
    VramCommand* cmd = vram_push(VRAM_CMD_BG_BLOCK);
    if (cmd == 0) return 0;
    cmd->dst = base;
    cmd->x = x;
    cmd->y = y;
    cmd->w = w;
    cmd->h = h;
    cmd->src = src;
    return 1;
}
vram_queue_bg_rect

Ajoute à la file un rectangle de carte de fond rempli du même numéro de tuile. Son coin supérieur gauche est (x, y) et sa taille est w × h tuiles. Une tuile unie forme un rectangle plein ; une tuile dessinée répète son motif dans chaque case.

Syntaxe

c
u8 vram_queue_bg_rect(u8 x, u8 y, u8 w, u8 h, u8 tile);

Paramètres

x, y

Coordonnées du coin supérieur gauche en tuiles de 8×8, pas en pixels. Aucun découpage. Gardez x + w <= 32 et y + h <= 32 sur GB, ou <= 30 dans la zone de tuiles d’une nametable FC. Une tuile seule a une largeur et une hauteur de 1.

w, h

Largeur et hauteur en tuiles, sur des octets non signés. Le bloc source contient w * h octets par lignes. Une dimension nulle ne produit aucune écriture visible, mais l’occupation de la file suit les règles de la plateforme.

tile

Octet de carte, de 0 à 255. Chargez le graphisme séparément et choisissez la table de motifs ou le mode d’adressage voulu. Ce numéro n’est ni un pointeur ni une couleur.

Valeur renvoyée

1 si cet ordre a été ajouté, 0 si aucune place n’était libre. Un échec mémorise le débordement sans toucher aux ordres existants. Un débordement antérieur ne fait pas renvoyer 0 à un ajout ultérieur réussi.

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Les ordres de tuile et de rectangle choisissent la carte de fond selon le bit 3 de LCDC à l’exécution. Sur CGB, utilisez la banque VRAM 0 pour les indices de tuile. Le bloc utilise la base indiquée, normalement 0x9800 ou 0x9C00. Le pas entre lignes est de 32 octets ; les coordonnées ne sont pas bornées automatiquement.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Exemple d’utilisation

c
check_result=vram_queue_bg_rect(2,4,4,3,1); // A filled 32x24 rectangle at (16,32).
if (check_result!=1) failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_queue_bg_rect: DMG
DMG
vram_queue_bg_rect: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:47

Notes de déclaration (texte source)
Queue a rectangle filled with one tile value; coordinates and dimensions are in tiles.

kitaqgb/lib/vram.c:65

c
u8 vram_queue_bg_rect(u8 x, u8 y, u8 w, u8 h, u8 tile)
{
    VramCommand* cmd = vram_push(VRAM_CMD_BG_RECT);
    if (cmd == 0) return 0;
    cmd->x = x;
    cmd->y = y;
    cmd->w = w;
    cmd->h = h;
    cmd->value = tile;
    return 1;
}
vram_queue_bg_tile

Ajoute à la file l’écriture d’un numéro de tuile de fond en (x, y). La modification devient visible à l’exécution de la file. Écrit une entrée de carte, sans charger les pixels de la tuile ni modifier ses attributs de palette.

Syntaxe

c
u8 vram_queue_bg_tile(u8 x, u8 y, u8 tile);

Paramètres

x, y

Coordonnées du coin supérieur gauche en tuiles de 8×8, pas en pixels. Aucun découpage. Gardez x + w <= 32 et y + h <= 32 sur GB, ou <= 30 dans la zone de tuiles d’une nametable FC. Une tuile seule a une largeur et une hauteur de 1.

tile

Octet de carte, de 0 à 255. Chargez le graphisme séparément et choisissez la table de motifs ou le mode d’adressage voulu. Ce numéro n’est ni un pointeur ni une couleur.

Valeur renvoyée

1 si cet ordre a été ajouté, 0 si aucune place n’était libre. Un échec mémorise le débordement sans toucher aux ordres existants. Un débordement antérieur ne fait pas renvoyer 0 à un ajout ultérieur réussi.

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Les ordres de tuile et de rectangle choisissent la carte de fond selon le bit 3 de LCDC à l’exécution. Sur CGB, utilisez la banque VRAM 0 pour les indices de tuile. Le bloc utilise la base indiquée, normalement 0x9800 ou 0x9C00. Le pas entre lignes est de 32 octets ; les coordonnées ne sont pas bornées automatiquement.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Exemple d’utilisation

c
check_result=vram_queue_bg_tile(2,2,1); // A solid 8x8 tile at pixel (16,16).
if (check_result!=1) failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_queue_bg_tile: DMG
DMG
vram_queue_bg_tile: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:43

Notes de déclaration (texte source)
Queue a single background tile write; return zero if no command slot is available.

kitaqgb/lib/vram.c:48

c
u8 vram_queue_bg_tile(u8 x, u8 y, u8 tile)
{
    VramCommand* cmd = vram_push(VRAM_CMD_BG_TILE);
    if (cmd == 0) return 0;
    cmd->x = x;
    cmd->y = y;
    cmd->value = tile;
    return 1;
}
vram_queue_memcpy

Ajoute à la file une copie de len octets consécutifs de src vers dst. Les deux adresses avancent octet par octet, sans saut de ligne de tuiles. Peut transférer des octets de carte ou de motifs modifiables, sans conversion de format ni calcul du nombre d’octets d’une tuile.

Syntaxe

c
u8 vram_queue_memcpy(u16 dst, const void* src, u16 len);

Paramètres

dst

Adresse de destination en octets dans la VRAM (0x8000–0x9FFF), dans la banque sélectionnée à l’exécution. Le transfert est contigu, sans saut de ligne. Toute la plage doit être valide. LCD actif, les chemins d’écriture sûrs peuvent activer les interruptions ; ils ne préservent pas un état d’appel où elles étaient désactivées.

src

Pointeur proche vers des octets lisibles, conservé jusqu’à l’exécution. Gardez les données vivantes et leur banque mémoire ou ROM accessible pendant tout le traitement ; aucun numéro de banque ni copie n’est mémorisé. Un transfert non vide exige une source valide. N’utilisez pas un tableau local dont la durée de vie est terminée.

len

Nombre d’octets consécutifs, de 0 à 65535, pas de tuiles. Gardez toute la plage dans une source valide et une destination modifiable ; l’API ne vérifie pas les limites et n’empêche pas le bouclage d’adresse sur 16 bits.

Valeur renvoyée

1 si cet ordre a été ajouté, 0 si aucune place n’était libre. Un échec mémorise le débordement sans toucher aux ordres existants. Un débordement antérieur ne fait pas renvoyer 0 à un ajout ultérieur réussi.

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Exemple d’utilisation

c
check_result=vram_queue_memcpy(MAP_BASE+8*32+2,strip,3);
if (check_result!=1) failures++; // Copy three map bytes, not three tile patterns.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_queue_memcpy: DMG
DMG
vram_queue_memcpy: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:53

Notes de déclaration (texte source)
Queue a byte transfer and retain the source pointer. The source must remain
valid and visible until flush; len is measured in bytes, not tiles.

kitaqgb/lib/vram.c:94

c
u8 vram_queue_memcpy(u16 dst, const void* src, u16 len)
{
    VramCommand* cmd = vram_push(VRAM_CMD_MEMCPY);
    if (cmd == 0) return 0;
    cmd->dst = dst;
    cmd->src = (const u8*)src;
    cmd->len = len;
    return 1;
}
vram_queue_memset

Ajoute à la file le remplissage de len octets consécutifs en dst par l’octet value. Répète un octet, pas un motif de tuile de plusieurs octets, sans introduire de saut de ligne de carte de 32 octets.

Syntaxe

c
u8 vram_queue_memset(u16 dst, u8 value, u16 len);

Paramètres

dst

Adresse de destination en octets dans la VRAM (0x8000–0x9FFF), dans la banque sélectionnée à l’exécution. Le transfert est contigu, sans saut de ligne. Toute la plage doit être valide. LCD actif, les chemins d’écriture sûrs peuvent activer les interruptions ; ils ne préservent pas un état d’appel où elles étaient désactivées.

value

Un octet de 0 à 255 répété. Son effet visible dépend du contenu de destination : indices de tuiles, plans de pixels ou autre structure d’octets.

len

Nombre d’octets consécutifs, de 0 à 65535, pas de tuiles. Gardez toute la plage dans une source valide et une destination modifiable ; l’API ne vérifie pas les limites et n’empêche pas le bouclage d’adresse sur 16 bits.

Valeur renvoyée

1 si cet ordre a été ajouté, 0 si aucune place n’était libre. Un échec mémorise le débordement sans toucher aux ordres existants. Un débordement antérieur ne fait pas renvoyer 0 à un ajout ultérieur réussi.

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Exemple d’utilisation

c
check_result=vram_queue_memset(MAP_BASE+8*32+10,1,5);
if (check_result!=1) failures++; // Five solid tiles form a 40x8 horizontal bar.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_queue_memset: DMG
DMG
vram_queue_memset: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:57

Notes de déclaration (texte source)
Queue a byte fill and return zero if the command queue is full.

kitaqgb/lib/vram.c:111

c
u8 vram_queue_memset(u16 dst, u8 value, u16 len)
{
    VramCommand* cmd = vram_push(VRAM_CMD_MEMSET);
    if (cmd == 0) return 0;
    cmd->dst = dst;
    cmd->value = value;
    cmd->len = len;
    return 1;
}
vram_queue_tile

vram_queue_tile appelle directement vram_queue_bg_tile avec les mêmes arguments et renvoie son résultat. C’est le nom court pour une entrée de carte de fond, pas une opération sur un sprite ni un chargement de graphismes.

Syntaxe

c
u8 vram_queue_tile(u8 x, u8 y, u8 tile);

Paramètres

x, y

Coordonnées du coin supérieur gauche en tuiles de 8×8, pas en pixels. Aucun découpage. Gardez x + w <= 32 et y + h <= 32 sur GB, ou <= 30 dans la zone de tuiles d’une nametable FC. Une tuile seule a une largeur et une hauteur de 1.

tile

Octet de carte, de 0 à 255. Chargez le graphisme séparément et choisissez la table de motifs ou le mode d’adressage voulu. Ce numéro n’est ni un pointeur ni une couleur.

Valeur renvoyée

1 si cet ordre a été ajouté, 0 si aucune place n’était libre. Un échec mémorise le débordement sans toucher aux ordres existants. Un débordement antérieur ne fait pas renvoyer 0 à un ajout ultérieur réussi.

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Les ordres de tuile et de rectangle choisissent la carte de fond selon le bit 3 de LCDC à l’exécution. Sur CGB, utilisez la banque VRAM 0 pour les indices de tuile. Le bloc utilise la base indiquée, normalement 0x9800 ou 0x9C00. Le pas entre lignes est de 32 octets ; les coordonnées ne sont pas bornées automatiquement.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Exemple d’utilisation

c
check_result=vram_queue_tile(4,2,1); // The short alias draws at pixel (32,16).
if (check_result!=1) failures++;

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_queue_tile: DMG
DMG
vram_queue_tile: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:45

Notes de déclaration (texte source)
Provide the short alias for a queued background tile write.

kitaqgb/lib/vram.c:59

c
u8 vram_queue_tile(u8 x, u8 y, u8 tile)
{
    return vram_queue_bg_tile(x, y, tile);
}
vram_queue_tiles

vram_queue_tiles appelle directement vram_queue_memcpy. len compte toujours des octets, pas des tuiles. Le pointeur source, les enregistrements, la valeur renvoyée et le moment d’exécution sont identiques.

Syntaxe

c
u8 vram_queue_tiles(u16 dst, const void* src, u16 len);

Paramètres

dst

Adresse de destination en octets dans la VRAM (0x8000–0x9FFF), dans la banque sélectionnée à l’exécution. Le transfert est contigu, sans saut de ligne. Toute la plage doit être valide. LCD actif, les chemins d’écriture sûrs peuvent activer les interruptions ; ils ne préservent pas un état d’appel où elles étaient désactivées.

src

Pointeur proche vers des octets lisibles, conservé jusqu’à l’exécution. Gardez les données vivantes et leur banque mémoire ou ROM accessible pendant tout le traitement ; aucun numéro de banque ni copie n’est mémorisé. Un transfert non vide exige une source valide. N’utilisez pas un tableau local dont la durée de vie est terminée.

len

Nombre d’octets consécutifs, de 0 à 65535, pas de tuiles. Gardez toute la plage dans une source valide et une destination modifiable ; l’API ne vérifie pas les limites et n’empêche pas le bouclage d’adresse sur 16 bits.

Valeur renvoyée

1 si cet ordre a été ajouté, 0 si aucune place n’était libre. Un échec mémorise le débordement sans toucher aux ordres existants. Un débordement antérieur ne fait pas renvoyer 0 à un ajout ultérieur réussi.

Conditions et limites

GB compte des emplacements d’ordre : la capacité par défaut est 32. Chaque fonction d’ajout en utilise un, même pour un transfert long ou nul. Définissez VRAM_QUEUE_MAX uniformément dans toutes les unités, entre 1 et 255. Une file vide a used=0 et free=capacity.

Coordonnez la construction et la consommation de la file. N’ajoutez rien pendant son exécution par une interruption, ne modifiez pas directement ses compteurs et n’écrasez pas involontairement les sources conservées. Ces API n’offrent ni verrouillage ni double tampon. La capacité concerne le tampon d’ordres, pas les octets libres de VRAM physique.

Exemple d’utilisation

c
check_result=vram_queue_tiles(MAP_BASE+8*32+6,strip+1,2);
if (check_result!=1) failures++; // This alias also measures length in bytes.

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Le programme complet présente les écritures différées, le suivi de capacité et la reprise après débordement. Sept appels de dessin occupent 7 des 32 emplacements sur GB, ou 52 des 128 octets sur FC : CAPACITY/USED/FREE affiche 032/007/025 ou 128/052/076. AFTER FLUSH et FAILED CHECKS doivent valoir 000, et OVERFLOW SEEN, 001. Un ajout volontaire à une file pleine teste l’indicateur : ni la lecture ni l’exécution ne l’effacent, contrairement à la remise à zéro de la file. Sur FC, l’exécution directe sans validation doit laisser la file intacte.

Les coordonnées sont en pixels depuis le coin supérieur gauche. On attend des carrés pleins de 8 × 8 en (16,16) et (32,16), un rectangle plein de 32 × 24 en (16,32) et une barre horizontale de 40 × 8 en (80,64). L’écriture finale en VBlank ajoute un carré de 8 × 8 en (144,80). L’écriture annulée en (144,24) doit laisser cette case vide. Le DMG affiche des formes noires sur blanc, le CGB des formes rouges, bleues et vertes sur blanc, et le FC des formes rouges, bleues et vertes sur noir. Ces images d’émulateur ne constituent pas une validation sur matériel réel.

Trois motifs originaux de 8 × 8 distinguent les copies : le 1 est plein, le 2 remplit les quatre colonnes de gauche et le 3 est un triangle aligné à gauche, large d’un pixel en haut et de huit en bas. Le bloc de 3 × 2 tuiles en (80,32) doit afficher [1,2,3] / [3,0,2], où 0 est vide. Son premier octet change après l’ajout ; la tuile pleine en haut à gauche prouve que le pointeur est conservé. La copie en (16,64) affiche [1,2,3] ; l’alias tiles en (48,64), [2,3]. Leurs tailles respectives sont de 24 × 16, 24 × 8 et 16 × 8 pixels.

Sur CGB, les deux carrés du haut, la copie de trois motifs et le dernier carré du VBlank sont rouges. Le rectangle de 32 × 24 et la copie de deux motifs sont bleus. Le bloc de 3 × 2 tuiles et la barre de 40 × 8 sont verts. Le texte reste noir sur blanc. La couleur de chaque pixel dessiné est vérifiée en plus de la géométrie.

vram_queue_tiles: DMG
DMG
vram_queue_tiles: CGB
CGB

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaqgb\lib\vram.c .\kitaq-docs\samples\api-examples\gb\vram_queue_shapes.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\vram_queue_shapes.gb --profile=dev --rst-disable --stack-bank=fixed --cgb=cgb --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/vram.h:55

Notes de déclaration (texte source)
Alias the queued byte-copy operation; this does not convert a tile count to bytes.

kitaqgb/lib/vram.c:105

c
u8 vram_queue_tiles(u16 dst, const void* src, u16 len)
{
    return vram_queue_memcpy(dst, src, len);
}

wire3d.h — Rendu filaire pour DMG

Dessin de lignes 3D monochromes. Fournissez sommets, arêtes et faces du modèle, ainsi que position, rotation et échelle de l’objet. Suivez l’ordre initialisation, début d’image, dessin, transfert. La physique est séparée. Les angles ont seize pas par tour ; l’échelle de modèle 256 vaut l’unité.

Vec3 contient x/y/z, Edge les indices de sommets a/b, et Face les indices de triangle a/b/c. Les champs vertices, edges et faces de Model pointent vers ces tableaux ; chaque compteur en donne la longueur. edge_faces contient les indices des faces adjacentes f0/f1, avec FACE_NONE pour une face absente. MODEL_HIDDEN_LINES dans flags demande une sélection d’arêtes fondée sur les faces. L’aire projetée signée détermine l’orientation d’une face : l’ordre des sommets compte.

Object mémorise une référence au modèle, la position x/y/z, les angles rx/ry/rz, scale_q8 et visible. Les objets peuvent partager un modèle, mais le dessin ne copie pas les tables et ne change pas automatiquement leurs banques ROM. Gardez les données référencées lisibles pendant tout le dessin. L’Object CGB possède aussi un indice de couleur.

Le Model de hauteur 96 contient aussi edge_masks et edge_mask_count. Fournissez une table RAM de masques d’arêtes sur 16 bits sélectionnés selon le lacet de l’objet, ou mettez les deux champs à zéro si inutilisés.

Wire3D_BeginFrame

Commence le dessin d’une image et désactive le test d’occlusion.

Syntaxe

c
void Wire3D_BeginFrame();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Efface les pixels préparés et le masque d’occlusion, puis désactive le filtrage d’occlusion. L’image VRAM affichée et la file de tuiles BG en attente restent inchangées.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3D_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3D_SetCamera(0,0,0,0,0,0);
    Wire3D_BeginFrame();
    Wire3D_DrawLine2D(8,8,56,8);
    Wire3D_DrawLine2D(56,8,56,40);
    Wire3D_DrawLine2D(56,40,8,40);
    Wire3D_DrawLine2D(8,40,8,8);
    Wire3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3D_PutBgTile(18,1,157);
    Wire3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Wire3D_BeginFrame: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
Wire3D_BeginFrame: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_raster.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:34

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Clear staged pixels and occlusion mask and disable occlusion filtering.
This leaves the displayed VRAM frame and pending BG tile queue unchanged.

kitaqgb/lib/wire3d_dmg.c:2641

c
void Wire3DDMG_BeginFrame()
{

    w3ddmg_clear_stage_asm();
    w3ddmg_clear_occlusion_mask();




    w3ddmg_occlusion_active = 0;
}
Wire3D_DrawLine2D

Trace dans la zone de préparation une ligne en coordonnées écran à connexité 4, extrémités incluses.

Syntaxe

c
void Wire3D_DrawLine2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by);

Paramètres

ax

Coordonnée X du sommet A en pixels du viewport.

ay

Coordonnée Y du sommet A en pixels du viewport.

bx

Coordonnée X du sommet B en pixels du viewport.

by

Coordonnée Y du sommet B en pixels du viewport.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Trace une ligne connexe dans la zone de préparation de 128×96, extrémités incluses. Pendant DrawScene, utilise le rejet d’occlusion grossier à cinq échantillons ; sinon, trace directement. Fournissez des coordonnées du viewport. Seul EndFrame met à jour la VRAM.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3D_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3D_SetCamera(0,0,0,0,0,0);
    Wire3D_BeginFrame();
    Wire3D_DrawLine2D(8,8,56,8);
    Wire3D_DrawLine2D(56,8,56,40);
    Wire3D_DrawLine2D(56,40,8,40);
    Wire3D_DrawLine2D(8,40,8,8);
    Wire3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3D_PutBgTile(18,1,157);
    Wire3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Wire3D_DrawLine2D: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
Wire3D_DrawLine2D: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_raster.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:35

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Draw a connected line into the 128x96 stage, including endpoints. During
DrawScene, use the coarse five-sample occlusion rejection; otherwise draw directly.
Supply viewport coordinates. VRAM is updated only by EndFrame.

kitaqgb/lib/wire3d_dmg.c:2685

c
void Wire3DDMG_DrawLine2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by)
{




    if (w3ddmg_occlusion_active)
    {
        w3ddmg_line_stage_masked_c(ax, ay, bx, by);
        return;
    }

    w3ddmg_line_x0 = ax;
    w3ddmg_line_y0 = ay;
    w3ddmg_line_x1 = bx;
    w3ddmg_line_y1 = by;
    if (ax < 128 && bx < 128 && ay < WIRE3D_DMG_SCREEN_H && by < WIRE3D_DMG_SCREEN_H)
        w3ddmg_line_inside_asm();
    else
        w3ddmg_line_stage_asm();
}
Wire3D_DrawLine3D

Projette deux extrémités du monde et trace une ligne entre elles.

Syntaxe

c
void Wire3D_DrawLine3D(w3ddmg_i16 ax, w3ddmg_i16 ay, w3ddmg_i16 az, w3ddmg_i16 bx, w3ddmg_i16 by, w3ddmg_i16 bz);

Paramètres

ax

Composante X du point de départ en coordonnées du monde.

ay

Composante Y du point de départ en coordonnées du monde.

az

Composante Z du point de départ en coordonnées du monde.

bx

Composante X du point d’arrivée en coordonnées du monde.

by

Composante Y du point d’arrivée en coordonnées du monde.

bz

Composante Z du point d’arrivée en coordonnées du monde.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Projette les deux extrémités du monde et dessine uniquement si les deux passent la plage de profondeur. Ne calcule pas l’intersection d’un segment traversant avec les plans proche ou lointain ; chaque extrémité projetée est bornée indépendamment aux bords de l’écran.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3D_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3D_SetCamera(0,0,0,0,0,0);
    Wire3D_BeginFrame();
    Wire3D_DrawLine2D(8,8,56,8);
    Wire3D_DrawLine2D(56,8,56,40);
    Wire3D_DrawLine2D(56,40,8,40);
    Wire3D_DrawLine2D(8,40,8,8);
    Wire3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3D_PutBgTile(18,1,157);
    Wire3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Wire3D_DrawLine3D: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
Wire3D_DrawLine3D: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_raster.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:36

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Project both world endpoints and draw only when both pass the depth range.
Do not intersect a crossing segment with near/far planes; projected endpoints
are independently clamped to the screen edges.

kitaqgb/lib/wire3d_dmg.c:2808

c
void Wire3DDMG_DrawLine3D(w3ddmg_i16 ax, w3ddmg_i16 ay, w3ddmg_i16 az, w3ddmg_i16 bx, w3ddmg_i16 by, w3ddmg_i16 bz)
{
    w3ddmg_u8 sx0;
    w3ddmg_u8 sy0;
    w3ddmg_u8 sx1;
    w3ddmg_u8 sy1;

    if (w3ddmg_project_world(ax, ay, az, &sx0, &sy0) == 0) return;
    if (w3ddmg_project_world(bx, by, bz, &sx1, &sy1) == 0) return;
    Wire3DDMG_DrawLine2D(sx0, sy0, sx1, sy1);
}
Wire3D_DrawModel

Dessine un modèle de sommets et d’arêtes à la position et avec la rotation demandées, à l’échelle unitaire.

Syntaxe

c
void Wire3D_DrawModel(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Dessine un modèle sans redimensionnement en appelant DrawModelScaled avec l’échelle 256.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Compare direct model scaling with an object-array scene.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3D_Vec3 vertices[8]={{-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},{-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}};
__prg_rom Wire3D_Edge edges[12]={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
Wire3D_Model cube;
Wire3D_Object objects[2];
u16 masks[2];
void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;

    cube.vertices=vertices;cube.edges=edges;cube.faces=0;cube.edge_faces=0;
    cube.vertex_count=8;cube.edge_count=12;cube.face_count=0;cube.flags=0;
    cube.edge_masks=0; cube.edge_mask_count=0;
    Wire3D_BeginFrame();
    // Upper pair: direct model calls at unity and half scale.
    Wire3D_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3D_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    // Lower pair: the caller owns both object records and the model tables.
    for(i=0;i<2;i++) {
        objects[i].model=&cube;objects[i].x=-32+(s16)i*64;
        objects[i].y=-32;objects[i].z=96;
        objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256-(s16)i*128;objects[i].visible=1;
    }
    Wire3D_DrawScene(objects,2);
    // Numeric checks cover the operation supplied by this viewport profile.
    masks[0]=3;masks[1]=12;cube.edge_masks=masks; cube.edge_mask_count=2;
    result[1]=Wire3D_SelectEdgeMask(&cube,0,0,0);
    result[2]=Wire3D_SelectEdgeMask(&cube,0,8,0);
    Wire3D_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Wire3D_DrawModel: DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
Wire3D_DrawModel: CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_models.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:37

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Draw an unscaled model by delegating to DrawModelScaled with scale 256.

kitaqgb/lib/wire3d_dmg.c:2825

c
void Wire3DDMG_DrawModel(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz)



{
    Wire3DDMG_DrawModelScaled(model, x, y, z, rx, ry, rz, 256);
}
Wire3D_DrawModelScaled

Redimensionne un modèle, le tourne dans l’ordre Y/X/Z, translate et projette ses sommets, puis trace ses arêtes.

Syntaxe

c
void Wire3D_DrawModelScaled(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz, w3ddmg_i16 scale_q8);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

scale_q8

Échelle dont l’unité vaut 256 ; les valeurs nulles ou négatives signifient aussi l’unité.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Redimensionne au plus 24 sommets, les tourne dans l’ordre Y/X/Z, les translate et les projette ; trace ensuite au plus 16 arêtes filtrées par masques de lacet et, éventuellement, par faces avant. Une échelle non positive devient l’unité (256). Les pointeurs de modèle, sommets ou arêtes nuls sont ignorés ; les tables référencées doivent rester lisibles. Produits d’échelle et translations doivent tenir sur 16 bits signés. Les arêtes traversant une limite de profondeur sont rejetées, pas découpées.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Compare direct model scaling with an object-array scene.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3D_Vec3 vertices[8]={{-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},{-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}};
__prg_rom Wire3D_Edge edges[12]={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
Wire3D_Model cube;
Wire3D_Object objects[2];
u16 masks[2];
void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;

    cube.vertices=vertices;cube.edges=edges;cube.faces=0;cube.edge_faces=0;
    cube.vertex_count=8;cube.edge_count=12;cube.face_count=0;cube.flags=0;
    cube.edge_masks=0; cube.edge_mask_count=0;
    Wire3D_BeginFrame();
    // Upper pair: direct model calls at unity and half scale.
    Wire3D_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3D_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    // Lower pair: the caller owns both object records and the model tables.
    for(i=0;i<2;i++) {
        objects[i].model=&cube;objects[i].x=-32+(s16)i*64;
        objects[i].y=-32;objects[i].z=96;
        objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256-(s16)i*128;objects[i].visible=1;
    }
    Wire3D_DrawScene(objects,2);
    // Numeric checks cover the operation supplied by this viewport profile.
    masks[0]=3;masks[1]=12;cube.edge_masks=masks; cube.edge_mask_count=2;
    result[1]=Wire3D_SelectEdgeMask(&cube,0,0,0);
    result[2]=Wire3D_SelectEdgeMask(&cube,0,8,0);
    Wire3D_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Wire3D_DrawModelScaled: DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
Wire3D_DrawModelScaled: CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_models.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:38

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Scale, rotate in Y/X/Z order, translate and project at most 24 vertices;
then draw up to 16 edges filtered by yaw masks and optional front-facing faces.
Nonpositive scale becomes unity (256). Null model/vertex/edge pointers are
ignored; referenced tables must remain readable. Keep scale products and
translations in signed 16-bit range. Depth-crossing edges are dropped, not clipped.

kitaqgb/lib/wire3d_dmg.c:2965

c
void Wire3DDMG_DrawModelScaled(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz, w3ddmg_i16 scale_q8)








{
    w3ddmg_u8 i;
    w3ddmg_u8 count;
    w3ddmg_u8 edge_count;
    w3ddmg_u8 face_count;

    if (model == 0) return;
    if (model->vertices == 0) return;
    if (model->edges == 0) return;
    if (scale_q8 <= 0) scale_q8 = 256;

    count = model->vertex_count;
    if (count > WIRE3D_DMG_MODEL_VERTEX_LIMIT) count = WIRE3D_DMG_MODEL_VERTEX_LIMIT;

    i = 0;
    while (i < count)
    {
        const Wire3DDMG_Vec3* v;
        w3ddmg_i16 vx;
        w3ddmg_i16 vy;
        w3ddmg_i16 vz;
        w3ddmg_u8 sx;
        w3ddmg_u8 sy;

        v = &model->vertices[(__safe_index w3ddmg_u8)i];
        vx = (w3ddmg_i16)((v->x * scale_q8) >> 8);
        vy = (w3ddmg_i16)((v->y * scale_q8) >> 8);
        vz = (w3ddmg_i16)((v->z * scale_q8) >> 8);


        w3ddmg_rotate_y(&vx, &vz, (w3ddmg_i8)ry);
        w3ddmg_rotate_x(&vy, &vz, (w3ddmg_i8)rx);
        w3ddmg_rotate_z(&vx, &vy, (w3ddmg_i8)rz);






        vx = (w3ddmg_i16)(vx + x);
        vy = (w3ddmg_i16)(vy + y);
        vz = (w3ddmg_i16)(vz + z);

        if (w3ddmg_project_world(vx, vy, vz, &sx, &sy))
        {
            w3ddmg_screen_x[(__safe_index w3ddmg_u8)i] = sx;
            w3ddmg_screen_y[(__safe_index w3ddmg_u8)i] = sy;
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 1;
        }
        else
        {
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 0;
        }
        i = (w3ddmg_u8)(i + 1);
    }

    face_count = model->face_count;
    if (face_count > WIRE3D_DMG_MODEL_FACE_LIMIT) face_count = WIRE3D_DMG_MODEL_FACE_LIMIT;
    if ((model->flags & WIRE3D_DMG_MODEL_HIDDEN_LINES) && (model->faces != 0) && (model->edge_faces != 0))
    {
        w3ddmg_build_face_visibility(model, count, face_count);
    }

    edge_count = model->edge_count;

    if (edge_count > WIRE3D_DMG_MODEL_EDGE_LIMIT) edge_count = WIRE3D_DMG_MODEL_EDGE_LIMIT;
    w3ddmg_build_edge_flags(model, edge_count, face_count, rx, ry, rz);

    i = 0;
    while (i < edge_count)
    {
        const Wire3DDMG_Edge* e;
        e = &model->edges[(__safe_index w3ddmg_u8)i];
        if ((e->a < count) && (e->b < count))
        {
            if (w3ddmg_screen_visible[(__safe_index w3ddmg_u8)e->a] &&
                w3ddmg_screen_visible[(__safe_index w3ddmg_u8)e->b] &&

                w3ddmg_edge_flags[(__safe_index w3ddmg_u8)i])



            {
                Wire3DDMG_DrawLine2D(
                    w3ddmg_screen_x[(__safe_index w3ddmg_u8)e->a],
                    w3ddmg_screen_y[(__safe_index w3ddmg_u8)e->a],
                    w3ddmg_screen_x[(__safe_index w3ddmg_u8)e->b],
                    w3ddmg_screen_y[(__safe_index w3ddmg_u8)e->b]);
            }
        }
        i = (w3ddmg_u8)(i + 1);
    }
}
Wire3D_DrawScene

Dessine au plus huit objets du plus proche au plus lointain, les faces proches masquant les arêtes suivantes.

Syntaxe

c
void Wire3D_DrawScene(Wire3DDMG_Object* objects, w3ddmg_u8 count);

Paramètres

objects

Tableau d’objets contenant positions, rotations, échelles et indicateurs de visibilité.

count

Nombre d’entrées fournies ; consultez la limite de traitement propre à l’opération.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Traite au plus les huit premiers objets, triés du plus proche au plus lointain selon la profondeur de leur origine transformée. Dessine les modèles visibles et valides, puis marque les rectangles englobants de leurs faces avant pour rejeter les lignes suivantes dont tous les points échantillonnés sont masqués. C’est une approximation de l’occlusion entre objets, pas un tampon de profondeur. Efface son masque mais conserve les pixels déjà préparés. Ignore les tableaux null ; les objets et leurs données doivent rester lisibles.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Compare direct model scaling with an object-array scene.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3D_Vec3 vertices[8]={{-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},{-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}};
__prg_rom Wire3D_Edge edges[12]={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
Wire3D_Model cube;
Wire3D_Object objects[2];
u16 masks[2];
void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;

    cube.vertices=vertices;cube.edges=edges;cube.faces=0;cube.edge_faces=0;
    cube.vertex_count=8;cube.edge_count=12;cube.face_count=0;cube.flags=0;
    cube.edge_masks=0; cube.edge_mask_count=0;
    Wire3D_BeginFrame();
    // Upper pair: direct model calls at unity and half scale.
    Wire3D_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3D_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    // Lower pair: the caller owns both object records and the model tables.
    for(i=0;i<2;i++) {
        objects[i].model=&cube;objects[i].x=-32+(s16)i*64;
        objects[i].y=-32;objects[i].z=96;
        objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256-(s16)i*128;objects[i].visible=1;
    }
    Wire3D_DrawScene(objects,2);
    // Numeric checks cover the operation supplied by this viewport profile.
    masks[0]=3;masks[1]=12;cube.edge_masks=masks; cube.edge_mask_count=2;
    result[1]=Wire3D_SelectEdgeMask(&cube,0,0,0);
    result[2]=Wire3D_SelectEdgeMask(&cube,0,8,0);
    Wire3D_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Wire3D_DrawScene: DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
Wire3D_DrawScene: CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_models.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:39

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Process at most the first eight objects, sorted near to far by transformed
origin depth. Draw visible valid models, then mark their front-face bounding
rectangles to reject fully sampled later lines. This approximates inter-object
occlusion, not a depth buffer. It clears its mask but retains existing staged
pixels. Null arrays are ignored; objects and their data must remain readable.

kitaqgb/lib/wire3d_dmg.c:2723

c
void Wire3DDMG_DrawScene(Wire3DDMG_Object* objects, w3ddmg_u8 count)
{
    w3ddmg_u8 scene_count;
    w3ddmg_u8 i;

    if (objects == 0) return;

    scene_count = count;
    if (scene_count > WIRE3D_DMG_SCENE_OBJECT_LIMIT) scene_count = WIRE3D_DMG_SCENE_OBJECT_LIMIT;




    i = 0;
    while (i < scene_count)
    {
        w3ddmg_scene_order[(__safe_index w3ddmg_u8)i] = i;
        w3ddmg_scene_depth[(__safe_index w3ddmg_u8)i] = w3ddmg_scene_object_depth(&objects[(__safe_index w3ddmg_u8)i]);
        i = (w3ddmg_u8)(i + 1);
    }

    i = 0;
    while (i < scene_count)
    {
        w3ddmg_u8 j;
        j = (w3ddmg_u8)(i + 1);
        while (j < scene_count)
        {
            w3ddmg_u8 oi;
            w3ddmg_u8 oj;
            oi = w3ddmg_scene_order[(__safe_index w3ddmg_u8)i];
            oj = w3ddmg_scene_order[(__safe_index w3ddmg_u8)j];


            // Put the nearer origin first so its face bounds can suppress later lines.
            // The array itself stays in caller order; only the scratch index list is sorted.

            if (w3ddmg_scene_depth[(__safe_index w3ddmg_u8)oj] < w3ddmg_scene_depth[(__safe_index w3ddmg_u8)oi])
            {
                w3ddmg_scene_order[(__safe_index w3ddmg_u8)i] = oj;
                w3ddmg_scene_order[(__safe_index w3ddmg_u8)j] = oi;
            }
            j = (w3ddmg_u8)(j + 1);
        }
        i = (w3ddmg_u8)(i + 1);
    }

    w3ddmg_clear_occlusion_mask();

    w3ddmg_occlusion_active = 1;




    i = 0;
    while (i < scene_count)
    {
        Wire3DDMG_Object* obj;
        obj = &objects[(__safe_index w3ddmg_u8)w3ddmg_scene_order[(__safe_index w3ddmg_u8)i]];
        if ((obj->visible != 0) && (obj->model != 0))
        {

            Wire3DDMG_DrawModelScaled(obj->model, obj->x, obj->y, obj->z, (w3ddmg_i8)obj->rx, (w3ddmg_i8)obj->ry, (w3ddmg_i8)obj->rz, obj->scale_q8);
            w3ddmg_mark_model_occluder(obj->model);








        }
        i = (w3ddmg_u8)(i + 1);
    }

    w3ddmg_occlusion_active = 0;
}
Wire3D_EndFrame

Soumet à la VRAM les écritures du fond en attente et le dessin préparé.

Syntaxe

c
void Wire3D_EndFrame();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Attend le prochain VBlank, applique les écritures BG en attente, puis copie la zone de préparation en VRAM en interrogeant les fenêtres d’accès. La copie consomme les pixels préparés. Le transfert peut dépasser le VBlank ; ce n’est pas un échange atomique d’image.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3D_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3D_SetCamera(0,0,0,0,0,0);
    Wire3D_BeginFrame();
    Wire3D_DrawLine2D(8,8,56,8);
    Wire3D_DrawLine2D(56,8,56,40);
    Wire3D_DrawLine2D(56,40,8,40);
    Wire3D_DrawLine2D(8,40,8,8);
    Wire3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3D_PutBgTile(18,1,157);
    Wire3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Wire3D_EndFrame: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
Wire3D_EndFrame: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_raster.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:42

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Wait for the next VBlank, flush pending BG map writes, then copy the stage
to VRAM while polling access windows. Copying consumes the staged pixels.
The transfer may extend beyond VBlank; this is not an atomic frame swap.

kitaqgb/lib/wire3d_dmg.c:3081

c
void Wire3DDMG_EndFrame()
{
    w3ddmg_wait_vblank_start();
    w3ddmg_flush_bg_queue();

    w3ddmg_transfer_stage_asm();














}
Wire3D_EraseModelFaces

Projette les triangles avant du modèle et efface les pixels préparés à l’intérieur.

Syntaxe

c
void Wire3D_EraseModelFaces(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz, w3ddmg_i16 scale_q8);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

scale_q8

Échelle dont l’unité vaut 256 ; les valeurs nulles ou négatives signifient aussi l’unité.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Projette au plus 24 sommets et efface l’intérieur des triangles avant dans la zone de préparation, pour un modèle doté d’indicateurs de lignes cachées et de données de faces. Une échelle non positive signifie 256, soit l’unité. Examine au plus 16 faces ; celles traversant une limite de profondeur sont ignorées. Remplace aussi les caches de projection partagés, sans mettre à jour la VRAM.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Erase a screen triangle and a projected model face from separate filled panels.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3D_Vec3 vertices[4]={{-24,-24,0},{24,-24,0},{24,24,0},{-24,24,0}};
__prg_rom Wire3D_Edge edges[4]={{0,1},{1,2},{2,3},{3,0}};
__prg_rom Wire3D_Face faces[2]={{0,2,1},{0,3,2}};
Wire3D_Model plane;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        plane.vertices=vertices;plane.edges=edges;plane.faces=faces;plane.edge_faces=0;
    plane.vertex_count=4;plane.edge_count=4;plane.face_count=2;plane.flags=1;plane.edge_masks=0;plane.edge_mask_count=0;
    Wire3D_BeginFrame();
    // Separate panels show a direct screen triangle and a projected square face.
    for(i=8;i<=32;i++) Wire3D_DrawLine2D(8,i,32,i);
    for(i=24;i<=72;i++) Wire3D_DrawLine2D(40,i,88,i);
    Wire3D_EraseTriangle2D(12,12,28,12,12,28);
    Wire3D_EraseModelFaces(&plane,0,0,64,0,0,0,256);

    Wire3D_EndFrame(); result[7]=0xA55A; while(1) {}
}

Résultat attendu

Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.

Wire3D_EraseModelFaces: DMG — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.
DMG — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.
Wire3D_EraseModelFaces: CGB — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.
CGB — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_faces.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_faces.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:43

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Project up to 24 vertices and erase front-facing triangle interiors from
the stage for a model with hidden-line flags and face data. Nonpositive scale
means 256 (unity). Up to 16 faces are considered; depth-crossing faces are
skipped. This also replaces shared projection caches, but does not update VRAM.

kitaqgb/lib/wire3d_dmg.c:2841

c
void Wire3DDMG_EraseModelFaces(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz, w3ddmg_i16 scale_q8)



{
    w3ddmg_u8 i;
    w3ddmg_u8 count;
    w3ddmg_u8 face_count;

    if (model == 0) return;
    if (model->vertices == 0) return;
    if (model->faces == 0) return;
    if ((model->flags & WIRE3D_DMG_MODEL_HIDDEN_LINES) == 0) return;
    if (scale_q8 <= 0) scale_q8 = 256;

    count = model->vertex_count;
    if (count > WIRE3D_DMG_MODEL_VERTEX_LIMIT) count = WIRE3D_DMG_MODEL_VERTEX_LIMIT;

    i = 0;
    while (i < count)
    {
        const Wire3DDMG_Vec3* v;
        w3ddmg_i16 vx;
        w3ddmg_i16 vy;
        w3ddmg_i16 vz;
        w3ddmg_u8 sx;
        w3ddmg_u8 sy;

        v = &model->vertices[(__safe_index w3ddmg_u8)i];
        vx = (w3ddmg_i16)((v->x * scale_q8) >> 8);
        vy = (w3ddmg_i16)((v->y * scale_q8) >> 8);
        vz = (w3ddmg_i16)((v->z * scale_q8) >> 8);


        w3ddmg_rotate_y(&vx, &vz, (w3ddmg_i8)ry);
        w3ddmg_rotate_x(&vy, &vz, (w3ddmg_i8)rx);
        w3ddmg_rotate_z(&vx, &vy, (w3ddmg_i8)rz);






        vx = (w3ddmg_i16)(vx + x);
        vy = (w3ddmg_i16)(vy + y);
        vz = (w3ddmg_i16)(vz + z);

        if (w3ddmg_project_world(vx, vy, vz, &sx, &sy))
        {
            w3ddmg_screen_x[(__safe_index w3ddmg_u8)i] = sx;
            w3ddmg_screen_y[(__safe_index w3ddmg_u8)i] = sy;
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 1;
        }
        else
        {
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 0;
        }
        i = (w3ddmg_u8)(i + 1);
    }

    face_count = model->face_count;
    if (face_count > WIRE3D_DMG_MODEL_FACE_LIMIT) face_count = WIRE3D_DMG_MODEL_FACE_LIMIT;
    w3ddmg_build_face_visibility(model, count, face_count);

    i = 0;
    while (i < face_count)
    {
        const Wire3DDMG_Face* f;
        f = &model->faces[(__safe_index w3ddmg_u8)i];
        if (w3ddmg_face_visible[(__safe_index w3ddmg_u8)i] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)f->a] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)f->b] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)f->c])
        {
            w3ddmg_clear_triangle(
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)f->a],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)f->a],
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)f->b],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)f->b],
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)f->c],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)f->c]);
        }
        i = (w3ddmg_u8)(i + 1);
    }
}
Wire3D_EraseSpan2D

Efface un segment horizontal, bornes incluses, sur une ligne préparée.

Syntaxe

c
void Wire3D_EraseSpan2D(w3ddmg_u8 y, w3ddmg_u8 x0, w3ddmg_u8 x1);

Paramètres

y

Coordonnée Y en pixels de la ligne à effacer.

x0

Borne X inférieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

x1

Borne X supérieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Ordonne les extrémités X et efface le segment préparé, bornes incluses. Les deux extrémités doivent être dans 0..127 ; un Y invalide est ignoré. La routine ne découpe pas X à votre place.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3D_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3D_SetCamera(0,0,0,0,0,0);
    Wire3D_BeginFrame();
    Wire3D_DrawLine2D(8,8,56,8);
    Wire3D_DrawLine2D(56,8,56,40);
    Wire3D_DrawLine2D(56,40,8,40);
    Wire3D_DrawLine2D(8,40,8,8);
    Wire3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3D_PutBgTile(18,1,157);
    Wire3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Wire3D_EraseSpan2D: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
Wire3D_EraseSpan2D: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_raster.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:44

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Order the X endpoints and erase the inclusive staged span. Both endpoints
must be in 0..127; invalid Y is ignored. The routine does not clip X for you.

kitaqgb/lib/wire3d_dmg.c:2943

c
void Wire3DDMG_EraseSpan2D(w3ddmg_u8 y, w3ddmg_u8 x0, w3ddmg_u8 x1)
{
    w3ddmg_u8 tx;

    if (x0 > x1)
    {
        tx = x0;
        x0 = x1;
        x1 = tx;
    }
    w3ddmg_stage_clear_span(y, x0, x1);
}
Wire3D_EraseTriangle2D

Efface un triangle en coordonnées écran dans la zone de préparation, par segments horizontaux de lignes de balayage.

Syntaxe

c
void Wire3D_EraseTriangle2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by, w3ddmg_u8 cx, w3ddmg_u8 cy);

Paramètres

ax

Coordonnée X du sommet A en pixels du viewport.

ay

Coordonnée Y du sommet A en pixels du viewport.

bx

Coordonnée X du sommet B en pixels du viewport.

by

Coordonnée Y du sommet B en pixels du viewport.

cx

Coordonnée X du sommet C en pixels du viewport.

cy

Coordonnée Y du sommet C en pixels du viewport.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Efface un triangle dans les pixels préparés à l’aide d’intersections entières avec les lignes de balayage. Fournissez des coordonnées du viewport. Les triangles dégénérés sont ignorés ; masque d’occlusion et VRAM restent inchangés.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Erase a screen triangle and a projected model face from separate filled panels.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3D_Vec3 vertices[4]={{-24,-24,0},{24,-24,0},{24,24,0},{-24,24,0}};
__prg_rom Wire3D_Edge edges[4]={{0,1},{1,2},{2,3},{3,0}};
__prg_rom Wire3D_Face faces[2]={{0,2,1},{0,3,2}};
Wire3D_Model plane;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        plane.vertices=vertices;plane.edges=edges;plane.faces=faces;plane.edge_faces=0;
    plane.vertex_count=4;plane.edge_count=4;plane.face_count=2;plane.flags=1;plane.edge_masks=0;plane.edge_mask_count=0;
    Wire3D_BeginFrame();
    // Separate panels show a direct screen triangle and a projected square face.
    for(i=8;i<=32;i++) Wire3D_DrawLine2D(8,i,32,i);
    for(i=24;i<=72;i++) Wire3D_DrawLine2D(40,i,88,i);
    Wire3D_EraseTriangle2D(12,12,28,12,12,28);
    Wire3D_EraseModelFaces(&plane,0,0,64,0,0,0,256);

    Wire3D_EndFrame(); result[7]=0xA55A; while(1) {}
}

Résultat attendu

Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.

Wire3D_EraseTriangle2D: DMG — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.
DMG — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.
Wire3D_EraseTriangle2D: CGB — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.
CGB — Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_faces.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_faces.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:45

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Erase a triangle from staged pixels using integer scanline intersections.
Supply viewport coordinates. Degenerate triangles are ignored; the occlusion
mask and VRAM are unchanged.

kitaqgb/lib/wire3d_dmg.c:2933

c
void Wire3DDMG_EraseTriangle2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by, w3ddmg_u8 cx, w3ddmg_u8 cy)
{
    w3ddmg_clear_triangle(ax, ay, bx, by, cx, cy);
}
Wire3D_Init

Initialise le LCD, les tuiles et la carte du fond pour un viewport filaire monochrome.

Syntaxe

c
void Wire3D_Init();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Prend le contrôle du LCD : attend le VBlank, l’éteint, efface 6144 octets de tuiles et la carte BG, installe les tuiles HUD et le viewport 128×96 à numéros de tuiles signés, puis active le fond avec défilement nul et BGP=0xB4. Réinitialise caméra, file BG et zone de préparation. Réservez 0xD000..0xDFFF pour cette zone et conservez son mappage de banque WRAM. Appelez BeginFrame avant de dessiner pour initialiser aussi l’occlusion.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3D_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3D_SetCamera(0,0,0,0,0,0);
    Wire3D_BeginFrame();
    Wire3D_DrawLine2D(8,8,56,8);
    Wire3D_DrawLine2D(56,8,56,40);
    Wire3D_DrawLine2D(56,40,8,40);
    Wire3D_DrawLine2D(8,40,8,8);
    Wire3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3D_PutBgTile(18,1,157);
    Wire3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Wire3D_Init: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
Wire3D_Init: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_raster.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:47

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Take over the LCD: wait for VBlank, switch it off, clear 6144 tile bytes and
the BG map, install HUD tiles and the 128x96 signed-tile viewport, then enable
BG display with scroll zero and BGP=0xB4. Reset camera, BG queue and stage.
Reserve 0xD000..0xDFFF for staging and retain its WRAM bank mapping.
Call BeginFrame before drawing to initialize the occlusion state as well.

kitaqgb/lib/wire3d_dmg.c:2572

c
void Wire3DDMG_Init()
{
    w3ddmg_u8 row;
    w3ddmg_u8 col;
    w3ddmg_u8 tid;
    w3ddmg_u16 off;

    w3ddmg_wait_vblank_start();
    w3ddmg_reg_lcdc = 0;

    w3ddmg_clear_vram_asm();

    w3ddmg_load_hud_tiles();

    w3ddmg_fill_bg_map_asm();

    row = 0;
    tid = 0x90;
    while (row < WIRE3D_DMG_TILE_H)
    {

        off = (w3ddmg_u16)((w3ddmg_u16)row << 5);



        col = 0;
        while (col < WIRE3D_DMG_TILE_W)
        {
            w3ddmg_bg_map_9800[(w3ddmg_u16)(off + (w3ddmg_u16)col)] = tid;
            tid = (w3ddmg_u8)(tid + WIRE3D_DMG_TILE_H);
            col = (w3ddmg_u8)(col + 1);
        }
        row = (w3ddmg_u8)(row + 1);
        tid = (w3ddmg_u8)(0x90 + row);
    }


    w3ddmg_reg_scx = 0;



    w3ddmg_reg_scy = 0;
    w3ddmg_reg_bgp = 0xB4;
    w3ddmg_reg_lcdc = 0x81;
    w3ddmg_bgq_count = 0;





    Wire3DDMG_SetCamera(0, 0, 0, 0, 0, 0);
    w3ddmg_clear_stage_asm();




}
Wire3D_ProjectPoint

Projette un point du monde par la caméra vers les coordonnées du viewport.

Syntaxe

c
w3ddmg_u8 Wire3D_ProjectPoint(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8* sx, w3ddmg_u8* sy);

Paramètres

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

sx

Pointeur u8 valide et accessible en écriture recevant la coordonnée X projetée.

sy

Pointeur u8 valide et accessible en écriture recevant la coordonnée Y projetée.

Valeur renvoyée

Renvoie 1 si la projection réussit, 0 si la profondeur est rejetée.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Projette un point du monde avec la caméra courante. Une profondeur rejetée renvoie zéro sans changer les sorties ; le succès écrit des coordonnées bornées à 128×96. Les pointeurs de sortie doivent être valides. Borner à l’écran n’est pas un découpage géométrique.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3D_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3D_SetCamera(0,0,0,0,0,0);
    Wire3D_BeginFrame();
    Wire3D_DrawLine2D(8,8,56,8);
    Wire3D_DrawLine2D(56,8,56,40);
    Wire3D_DrawLine2D(56,40,8,40);
    Wire3D_DrawLine2D(8,40,8,8);
    Wire3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3D_PutBgTile(18,1,157);
    Wire3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Wire3D_ProjectPoint: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
Wire3D_ProjectPoint: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_raster.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:50

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Project a world point with the current camera. Return zero for rejected
depth, leaving outputs unchanged; success writes clamped 128x96 coordinates.
Output pointers must be valid. Screen clamping is not geometric clipping.

kitaqgb/lib/wire3d_dmg.c:549

c
w3ddmg_u8 Wire3DDMG_ProjectPoint(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8* sx, w3ddmg_u8* sy)
{
    return w3ddmg_project_world(x, y, z, sx, sy);
}
Wire3D_PutBgTile

Met en file une écriture de numéro de tuile dans une case de la carte du fond.

Syntaxe

c
void Wire3D_PutBgTile(w3ddmg_u8 x, w3ddmg_u8 y, w3ddmg_u8 tile);

Paramètres

x

Coordonnée X en tuiles dans la carte de fond de 32×32.

y

Coordonnée Y en tuiles dans la carte de fond de 32×32.

tile

Numéro de tuile sur huit bits pour la case du fond.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Met en file une écriture de tuile dans la carte 32×32 en 0x9800 pour EndFrame. Les coordonnées invalides et les soumissions au-delà de 48 écritures en attente sont ignorées sans signalement. Cette file est distincte de celle de la bibliothèque vram générale.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3D_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3D_SetCamera(0,0,0,0,0,0);
    Wire3D_BeginFrame();
    Wire3D_DrawLine2D(8,8,56,8);
    Wire3D_DrawLine2D(56,8,56,40);
    Wire3D_DrawLine2D(56,40,8,40);
    Wire3D_DrawLine2D(8,40,8,8);
    Wire3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3D_PutBgTile(18,1,157);
    Wire3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Wire3D_PutBgTile: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
Wire3D_PutBgTile: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_raster.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:51

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Queue a tile write to the 32x32 map at 0x9800 for EndFrame. Invalid map
coordinates and submissions beyond 48 pending writes are silently ignored.
This queue is separate from the general vram library queue.

kitaqgb/lib/wire3d_dmg.c:582

c
void Wire3DDMG_PutBgTile(w3ddmg_u8 x, w3ddmg_u8 y, w3ddmg_u8 tile)
{
    if (x >= 32) return;
    if (y >= 32) return;
    if (w3ddmg_bgq_count >= WIRE3D_DMG_BG_QUEUE_LIMIT) return;
    w3ddmg_bgq_x[(__safe_index w3ddmg_u8)w3ddmg_bgq_count] = x;
    w3ddmg_bgq_y[(__safe_index w3ddmg_u8)w3ddmg_bgq_count] = y;
    w3ddmg_bgq_tile[(__safe_index w3ddmg_u8)w3ddmg_bgq_count] = tile;
    w3ddmg_bgq_count = (w3ddmg_u8)(w3ddmg_bgq_count + 1);
}
Wire3D_SelectEdgeMask

Choisit un masque précalculé de visibilité des arêtes selon le lacet de l’objet.

Syntaxe

c
w3ddmg_u16 Wire3D_SelectEdgeMask(const Wire3DDMG_Model* model, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

Valeur renvoyée

Masque de visibilité des arêtes sur 16 bits, ou 0xFFFF si aucune table n’est fournie.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Choisit un masque précalculé d’après les quatre bits faibles du lacet de l’objet ; tangage, roulis et orientation de caméra sont ignorés. Utilisez 16, 8, 4 ou 2 secteurs ; les autres nombres positifs sélectionnent l’entrée zéro, sauf qu’un nombre >=16 utilise les 16 premières. Sans données, renvoie 0xFFFF. La table de masques doit rester lisible avec le mappage courant des pointeurs de données.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Compare direct model scaling with an object-array scene.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3D_Vec3 vertices[8]={{-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},{-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}};
__prg_rom Wire3D_Edge edges[12]={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
Wire3D_Model cube;
Wire3D_Object objects[2];
u16 masks[2];
void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;

    cube.vertices=vertices;cube.edges=edges;cube.faces=0;cube.edge_faces=0;
    cube.vertex_count=8;cube.edge_count=12;cube.face_count=0;cube.flags=0;
    cube.edge_masks=0; cube.edge_mask_count=0;
    Wire3D_BeginFrame();
    // Upper pair: direct model calls at unity and half scale.
    Wire3D_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3D_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    // Lower pair: the caller owns both object records and the model tables.
    for(i=0;i<2;i++) {
        objects[i].model=&cube;objects[i].x=-32+(s16)i*64;
        objects[i].y=-32;objects[i].z=96;
        objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256-(s16)i*128;objects[i].visible=1;
    }
    Wire3D_DrawScene(objects,2);
    // Numeric checks cover the operation supplied by this viewport profile.
    masks[0]=3;masks[1]=12;cube.edge_masks=masks; cube.edge_mask_count=2;
    result[1]=Wire3D_SelectEdgeMask(&cube,0,0,0);
    result[2]=Wire3D_SelectEdgeMask(&cube,0,8,0);
    Wire3D_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Wire3D_SelectEdgeMask: DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
DMG — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
Wire3D_SelectEdgeMask: CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.
CGB — Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_models.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:52

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Select a precomputed mask from the low four bits of object yaw; pitch,
roll and camera orientation are ignored. Use 16, 8, 4 or 2 bins; other positive
counts select entry zero (counts >=16 use the first 16). Missing data returns
0xFFFF. Keep the mask table readable through the current data-pointer mapping.

kitaqgb/lib/wire3d_dmg.c:1109

c
w3ddmg_u16 Wire3DDMG_SelectEdgeMask(const Wire3DDMG_Model* model, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz)
{
    w3ddmg_u8 count;
    w3ddmg_u8 bin;

    if (model == 0) return 0xFFFF;
    if (model->edge_masks == 0) return 0xFFFF;
    count = model->edge_mask_count;
    if (count == 0) return 0xFFFF;

    (void)rx;
    (void)rz;

    bin = (w3ddmg_u8)(((w3ddmg_u8)ry) & 15);
    if (count >= 16) return model->edge_masks[(__safe_index w3ddmg_u8)bin];
    if (count == 8) bin = (w3ddmg_u8)(bin >> 1);
    else if (count == 4) bin = (w3ddmg_u8)(bin >> 2);
    else if (count == 2) bin = (w3ddmg_u8)(bin >> 3);
    else bin = 0;

    if (bin >= count) bin = (w3ddmg_u8)(count - 1);
    return model->edge_masks[(__safe_index w3ddmg_u8)bin];
}
Wire3D_SetCamera

Mémorise la position et l’orientation de la caméra pour les projections suivantes.

Syntaxe

c
void Wire3D_SetCamera(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 pitch, w3ddmg_i8 yaw, w3ddmg_i8 roll);

Paramètres

x

Composante X de la caméra en coordonnées du monde.

y

Composante Y de la caméra en coordonnées du monde.

z

Composante Z de la caméra en coordonnées du monde.

pitch

Rotation autour de X ; seize pas font un tour complet.

yaw

Rotation autour de Y ; seize pas font un tour complet.

roll

Rotation autour de Z ; seize pas font un tour complet.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Mémorise la position et les angles de caméra pour les dessins suivants ; un tour compte 16 pas angulaires. Ne reprojette pas les dessins existants et ne valide pas les plages d’entrée.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3D_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3D_SetCamera(0,0,0,0,0,0);
    Wire3D_BeginFrame();
    Wire3D_DrawLine2D(8,8,56,8);
    Wire3D_DrawLine2D(56,8,56,40);
    Wire3D_DrawLine2D(56,40,8,40);
    Wire3D_DrawLine2D(8,40,8,8);
    Wire3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3D_PutBgTile(18,1,157);
    Wire3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Wire3D_SetCamera: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
Wire3D_SetCamera: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_raster.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:53

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Store camera position and angles for later draws; a full turn is 16 angle
steps. No existing drawing is reprojected and no input range validation occurs.

kitaqgb/lib/wire3d_dmg.c:2659

c
void Wire3DDMG_SetCamera(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 pitch, w3ddmg_i8 yaw, w3ddmg_i8 roll)



{
    w3ddmg_cam_x = x;
    w3ddmg_cam_y = y;
    w3ddmg_cam_z = z;
    w3ddmg_cam_pitch = pitch;
    w3ddmg_cam_yaw = yaw;
    w3ddmg_cam_roll = roll;
}
Wire3D_SetPalette

Écrit la correspondance des quatre nuances dans le registre de palette du fond monochrome BGP.

Syntaxe

c
void Wire3D_SetPalette(w3ddmg_u8 bgp);

Paramètres

bgp

Valeur du registre BGP contenant quatre affectations de nuance sur deux bits.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96. Écrit immédiatement l’encodage brut de la palette DMG BGP, sans synchronisation d’image.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3D_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3D_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3D_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3D_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3D_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3D_SetCamera(0,0,0,0,0,0);
    Wire3D_BeginFrame();
    Wire3D_DrawLine2D(8,8,56,8);
    Wire3D_DrawLine2D(56,8,56,40);
    Wire3D_DrawLine2D(56,40,8,40);
    Wire3D_DrawLine2D(8,40,8,8);
    Wire3D_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3D_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3D_PutBgTile(18,1,157);
    Wire3D_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Wire3D_SetPalette: DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
DMG — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
Wire3D_SetPalette: CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.
CGB — Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_wire3d_raster.c .\kitaqgb\lib\wire3d.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_wire3d_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d.h:54

Notes de déclaration (texte source)
WIRE3D_DMG_HEIGHT = 96.
Write the raw DMG BGP palette encoding immediately; no frame synchronization occurs.

kitaqgb/lib/wire3d_dmg.c:597

c
void Wire3DDMG_SetPalette(w3ddmg_u8 bgp)
{
    w3ddmg_reg_bgp = bgp;
}

wire3d_cgb.h — Rendu filaire couleur pour CGB

Utilisation des chemins de rendu rapide

Le rendu normal en 128×96 fait avancer les adresses de dessin progressivement. Pour une ligne sans occlusion, il choisit le plan de couleur une seule fois et garde le nombre de pixels et l’erreur dans les registres CPU. Les lignes avec occlusion choisissent également les plans une fois par ligne et font avancer progressivement les adresses de dessin et de masque. Chaque pixel teste son bit de masque et n’est écrit que s’il n’est pas masqué. Le rendu en 160×144 et FastMap ont chacun leurs chemins dédiés. Les rotations de 0, 90, 180 et 270 degrés bornent les entrées, puis échangent les coordonnées et changent les signes. Les performances du jeu dépendent aussi du nombre de sommets, de la longueur des arêtes, de l’occlusion et des transferts VRAM. Mesurez séparément chaque opération et le temps nécessaire pour achever une image affichée.

Rendu filaire couleur pour CGB. Le moteur par pixels de 128×96, l’allocateur de tuiles de 160×144 et FastMap à tuiles de contour ont des séquences d’initialisation et de transfert distinctes. L’appelant possède sommets, arêtes et faces triangulaires. Ce module ne simule pas la physique.

Vec3 contient x/y/z, Edge les indices de sommets a/b, et Face les indices de triangle a/b/c. Les champs vertices, edges et faces de Model pointent vers ces tableaux ; chaque compteur en donne la longueur. edge_faces contient les indices des faces adjacentes f0/f1, avec FACE_NONE pour une face absente. MODEL_HIDDEN_LINES dans flags demande une sélection d’arêtes fondée sur les faces. L’aire projetée signée détermine l’orientation d’une face : l’ordre des sommets compte.

Object mémorise une référence au modèle, la position x/y/z, les angles rx/ry/rz, scale_q8 et visible. Les objets peuvent partager un modèle, mais le dessin ne copie pas les tables et ne change pas automatiquement leurs banques ROM. Gardez les données référencées lisibles pendant tout le dessin. L’Object CGB possède aussi un indice de couleur.

Les x/y de FastCube sont des décalages par rapport au centre de l’écran ; z choisit la taille ou l’ordre de dessin. FastCubes ignore les angles, tandis que FastCubeFrame utilise rx/ry/rz pour choisir parmi quatre variantes de motifs. Ces affichages simplifiés ont un autre usage que DrawModel, qui projette par la caméra.

Wire3DCGB_BeginFrame

Commence une nouvelle image vide dans le mode de rendu choisi.

Syntaxe

c
void Wire3DCGB_BeginFrame();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

En mode normal, sélectionne le transfert intégral de la zone de préparation, efface tous ses pixels et le masque bitmap, réinitialise les limites du masque et désactive l’occlusion. En plein écran, réinitialise à la place l’allocateur et les segments de ce mode. Les écritures BG en attente restent dans la file. Nécessite une compilation avec le runtime complet.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Au démarrage sparse CGB, la première utilisation de chaque banque cible (les deux premières images) actualise tout le viewport et efface les tuiles d’initialisation. Cette charge est incluse dans les mesures. DrawLine2D ne déclare pas de zone sparse : utilisez DrawLineClipped2D ou MarkDirtyRect2D explicitement.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:122

kitaqgb/lib/wire3d_cgb.c:8154

c
void Wire3DCGB_BeginFrame()
{
    if (w3dcgb_full_mode != 0)
    {
        w3dcgb_full_begin_asm();
        return;
    }
    w3dcgb_full_frame_transfer = 1;
    w3dcgb_clear_stage_asm();
    w3dcgb_clear_occlusion_mask_asm();
    w3dcgb_occ_min_x = (w3dcgb_u8)(WIRE3DCGB_SCREEN_W - 1);
    w3dcgb_occ_min_y = (w3dcgb_u8)(WIRE3DCGB_SCREEN_H - 1);
    w3dcgb_occ_max_x = 0;
    w3dcgb_occ_max_y = 0;
    w3dcgb_occlusion_active = 0;
}
Wire3DCGB_BeginFrameFast

Commence une image effacée et invalide les anciennes plages partielles en les étendant à tout le viewport.

Syntaxe

c
void Wire3DCGB_BeginFrameFast();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Effectue la même réinitialisation d’image normale ou plein écran que BeginFrame, mais étend d’abord chacune des deux plages de l’historique partiel à la totalité des 192 tuiles du viewport. Ainsi, le prochain transfert partiel ne se fie pas à des banques périmées.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Au démarrage sparse CGB, la première utilisation de chaque banque cible (les deux premières images) actualise tout le viewport et efface les tuiles d’initialisation. Cette charge est incluse dans les mesures. DrawLine2D ne déclare pas de zone sparse : utilisez DrawLineClipped2D ou MarkDirtyRect2D explicitement.

Exemple d’utilisation

c
#pragma bank 0
// Reuse both VRAM banks and remove old geometry while presenting sparse frames.
#include "wire_cgb_example.h"
void main() {
    wire_results_clear(); Wire3DCGB_Init();
    Wire3DCGB_ClearFrameTiles();
    Wire3DCGB_EnableAtomicMaps(); wire_colors();
    // First frame: red on the left. Fast begin invalidates both bank histories.
    Wire3DCGB_BeginFrameFast(); wire_frame(8,8,32,32,1);
    Wire3DCGB_EndFrameFast();
    // Second frame: blue in the middle, with the old red frame removed.
    Wire3DCGB_BeginFrameSparse(); wire_frame(40,40,64,64,2);
    Wire3DCGB_EndFrameSparse();
    // Third frame: explicitly clearing a stage discards its first green point.
    Wire3DCGB_BeginFrameSparse();
    Wire3DCGB_SetLineColor(3); Wire3DCGB_DrawPoint2D(4,4);
    Wire3DCGB_ClearSparseStageFast();
    // The final image contains only this green frame on the right.
    wire_frame(80,8,112,32,3);
    Wire3DCGB_MarkDirtyRect2D(80,8,112,32);
    Wire3DCGB_InvalidateFrameHistory();
    Wire3DCGB_EndFrameSparseNow();
    result[0]=Wire3DCGB_GetLineColor();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Les cadres rouge et bleu dessinés précédemment disparaissent ; seul reste le cadre vert final de (80,8) à (112,32), ce qui illustre le transfert partiel et la gestion de l’historique.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_sparse.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_sparse.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:123

kitaqgb/lib/wire3d_cgb.c:8175

c
void Wire3DCGB_BeginFrameFast()
{
    w3dcgb_older_dirty_min_tile = 0;
    w3dcgb_older_dirty_max_tile = (w3dcgb_u8)(WIRE3DCGB_TILE_COUNT - 1);
    w3dcgb_prev_dirty_min_tile = 0;
    w3dcgb_prev_dirty_max_tile = (w3dcgb_u8)(WIRE3DCGB_TILE_COUNT - 1);
    if (w3dcgb_full_mode != 0)
    {
        w3dcgb_full_begin_asm();
        return;
    }
    w3dcgb_full_frame_transfer = 1;
    w3dcgb_clear_stage_asm();
    w3dcgb_clear_occlusion_mask_asm();
    w3dcgb_occ_min_x = (w3dcgb_u8)(WIRE3DCGB_SCREEN_W - 1);
    w3dcgb_occ_min_y = (w3dcgb_u8)(WIRE3DCGB_SCREEN_H - 1);
    w3dcgb_occ_max_x = 0;
    w3dcgb_occ_max_y = 0;
    w3dcgb_occlusion_active = 0;
}
Wire3DCGB_BeginFrameSparse

Commence une image destinée au transfert de plages partielles.

Syntaxe

c
void Wire3DCGB_BeginFrameSparse();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Sélectionne le transfert partiel et efface toute la zone de préparation de 128×96 pour éviter les anciens pixels lorsque la plage modifiée s’agrandit. Réinitialise les limites du masque et désactive l’occlusion ; les builds PAINTER_ONLY n’effacent pas le masque bitmap inutilisé. Le mode plein écran délègue à la réinitialisation de son propre allocateur.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Au démarrage sparse CGB, la première utilisation de chaque banque cible (les deux premières images) actualise tout le viewport et efface les tuiles d’initialisation. Cette charge est incluse dans les mesures. DrawLine2D ne déclare pas de zone sparse : utilisez DrawLineClipped2D ou MarkDirtyRect2D explicitement.

Exemple d’utilisation

c
#pragma bank 0
// Reuse both VRAM banks and remove old geometry while presenting sparse frames.
#include "wire_cgb_example.h"
void main() {
    wire_results_clear(); Wire3DCGB_Init();
    Wire3DCGB_ClearFrameTiles();
    Wire3DCGB_EnableAtomicMaps(); wire_colors();
    // First frame: red on the left. Fast begin invalidates both bank histories.
    Wire3DCGB_BeginFrameFast(); wire_frame(8,8,32,32,1);
    Wire3DCGB_EndFrameFast();
    // Second frame: blue in the middle, with the old red frame removed.
    Wire3DCGB_BeginFrameSparse(); wire_frame(40,40,64,64,2);
    Wire3DCGB_EndFrameSparse();
    // Third frame: explicitly clearing a stage discards its first green point.
    Wire3DCGB_BeginFrameSparse();
    Wire3DCGB_SetLineColor(3); Wire3DCGB_DrawPoint2D(4,4);
    Wire3DCGB_ClearSparseStageFast();
    // The final image contains only this green frame on the right.
    wire_frame(80,8,112,32,3);
    Wire3DCGB_MarkDirtyRect2D(80,8,112,32);
    Wire3DCGB_InvalidateFrameHistory();
    Wire3DCGB_EndFrameSparseNow();
    result[0]=Wire3DCGB_GetLineColor();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Les cadres rouge et bleu dessinés précédemment disparaissent ; seul reste le cadre vert final de (80,8) à (112,32), ce qui illustre le transfert partiel et la gestion de l’historique.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_sparse.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_sparse.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:124

kitaqgb/lib/wire3d_cgb.c:8200

c
void Wire3DCGB_BeginFrameSparse()
{
    if (w3dcgb_full_mode != 0)
    {
        w3dcgb_full_begin_asm();
        return;
    }
    w3dcgb_full_frame_transfer = 0;
    w3dcgb_dirty_count = 0;
    /* One ASM pass is faster than repeated range-growth clears and guarantees
       that newly exposed dirty tiles can never copy stale stage pixels. */
    w3dcgb_clear_stage_asm();
#ifndef WIRE3DCGB_PAINTER_ONLY
    /* A Z-sorted painter erases silhouettes directly in the stage and never
       reads the separate front-to-back coverage mask. */
    w3dcgb_clear_occlusion_mask_asm();
#endif
    w3dcgb_occ_min_x = (w3dcgb_u8)(WIRE3DCGB_SCREEN_W - 1);
    w3dcgb_occ_min_y = (w3dcgb_u8)(WIRE3DCGB_SCREEN_H - 1);
    w3dcgb_occ_max_x = 0;
    w3dcgb_occ_max_y = 0;
    w3dcgb_occlusion_active = 0;
}
Wire3DCGB_ClearFrameTiles

Efface les tuiles de l’image affichée en 128×96 et la zone de préparation.

Syntaxe

c
void Wire3DCGB_ClearFrameTiles();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Pour le moteur de 128×96, attend le VBlank, éteint le LCD, efface la zone de préparation et les plages de tuiles de l’image dans les deux banques, réinitialise les attributs de carte, puis active LCDC 0x81. Efface les indicateurs et compteurs de modification, mais conserve l’historique min/max des transferts partiels. Ne réinitialise pas full_mode et ne réinitialise pas le mode plein écran.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Au démarrage sparse CGB, la première utilisation de chaque banque cible (les deux premières images) actualise tout le viewport et efface les tuiles d’initialisation. Cette charge est incluse dans les mesures. DrawLine2D ne déclare pas de zone sparse : utilisez DrawLineClipped2D ou MarkDirtyRect2D explicitement.

Exemple d’utilisation

c
#pragma bank 0
// Reuse both VRAM banks and remove old geometry while presenting sparse frames.
#include "wire_cgb_example.h"
void main() {
    wire_results_clear(); Wire3DCGB_Init();
    Wire3DCGB_ClearFrameTiles();
    Wire3DCGB_EnableAtomicMaps(); wire_colors();
    // First frame: red on the left. Fast begin invalidates both bank histories.
    Wire3DCGB_BeginFrameFast(); wire_frame(8,8,32,32,1);
    Wire3DCGB_EndFrameFast();
    // Second frame: blue in the middle, with the old red frame removed.
    Wire3DCGB_BeginFrameSparse(); wire_frame(40,40,64,64,2);
    Wire3DCGB_EndFrameSparse();
    // Third frame: explicitly clearing a stage discards its first green point.
    Wire3DCGB_BeginFrameSparse();
    Wire3DCGB_SetLineColor(3); Wire3DCGB_DrawPoint2D(4,4);
    Wire3DCGB_ClearSparseStageFast();
    // The final image contains only this green frame on the right.
    wire_frame(80,8,112,32,3);
    Wire3DCGB_MarkDirtyRect2D(80,8,112,32);
    Wire3DCGB_InvalidateFrameHistory();
    Wire3DCGB_EndFrameSparseNow();
    result[0]=Wire3DCGB_GetLineColor();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Les cadres rouge et bleu dessinés précédemment disparaissent ; seul reste le cadre vert final de (80,8) à (112,32), ce qui illustre le transfert partiel et la gestion de l’historique.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_sparse.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_sparse.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:121

kitaqgb/lib/wire3d_cgb.c:8240

c
void Wire3DCGB_ClearFrameTiles()
{
    w3dcgb_u8 i;

    w3dcgb_wait_vblank_start();
    w3dcgb_reg_lcdc = 0;
    w3dcgb_clear_stage_asm();
    w3dcgb_clear_frame_tiles_vram_asm();
    w3dcgb_fill_attr_map_asm();
    w3dcgb_reg_lcdc = 0x81;

    i = 0;
    while (i < W3DCGB_DIRTY_TILE_LIMIT)
    {
        w3dcgb_dirty_flags[(__safe_index w3dcgb_u8)i] = 0;
        w3dcgb_prev_dirty_flags[(__safe_index w3dcgb_u8)i] = 0;
        i = (w3dcgb_u8)(i + 1);
    }
    w3dcgb_dirty_count = 0;
    w3dcgb_prev_dirty_count = 0;
}
Wire3DCGB_ClearOcclusionMask

Efface le bitmap d’occlusion ou l’historique des segments plein écran.

Syntaxe

c
void Wire3DCGB_ClearOcclusionMask();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Si full_mode est actif, efface l’historique des segments plein écran ; sinon, efface le masque bitmap de 128×96 et ses limites. N’efface pas les pixels affichés ou préparés et ne change pas l’activation du test d’occlusion.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Red/blue scanlines stop inside masks; green outlines identify the triangle.
#include "wire_cgb_example.h"
__prg_rom u8 silhouette[5]={0x73,0x74,0xFF,0x75,0x73};
void main() {
    u8 y;
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    // Clearing this first test mask must leave the upper-left scanline intact.
    Wire3DCGB_MarkTriangle2D(8,8,16,8,8,16);
    Wire3DCGB_ClearOcclusionMask();
    Wire3DCGB_MarkTriangle2D(32,16,64,16,32,48);
    Wire3DCGB_MarkPackedSilhouette2D(silhouette,5,-2,104,32);
    Wire3DCGB_SetOcclusionActive(1);
    for(y=8;y<=56;y=y+4) Wire3DCGB_DrawLine2DColor(8,y,88,y,1);
    for(y=28;y<=36;y++) Wire3DCGB_DrawLine2DColor(92,y,120,y,2);
    Wire3DCGB_SetOcclusionActive(0);
    Wire3DCGB_DrawLine2DColor(32,16,64,16,3);
    Wire3DCGB_DrawLine2DColor(64,16,32,48,3);
    Wire3DCGB_DrawLine2DColor(32,48,32,16,3);
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Un triangle masque le milieu des lignes de balayage rouges ; une silhouette compactée masque les lignes bleues. Les contours verts situent la région occultante.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_mask.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_mask.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:148

kitaqgb/lib/wire3d_cgb.c:1962

c
void Wire3DCGB_ClearOcclusionMask()
{
    if (w3dcgb_full_mode != 0) w3dcgb_full_clear_spans_asm();
    else w3dcgb_clear_occlusion_mask();
}
Wire3DCGB_ClearSparseStageFast

Efface toute la zone de préparation et marque tout le viewport de 128×96 pour transfert.

Syntaxe

c
void Wire3DCGB_ClearSparseStageFast();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Efface toute la zone de préparation de la banque 2 et marque l’intégralité du viewport de 128×96 comme modifiée. Malgré son nom, ce n’est pas un effacement partiel et aucun pixel préparé n’est conservé. Ne réinitialise pas l’occlusion et ne choisit pas de mode de transfert.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Reuse both VRAM banks and remove old geometry while presenting sparse frames.
#include "wire_cgb_example.h"
void main() {
    wire_results_clear(); Wire3DCGB_Init();
    Wire3DCGB_ClearFrameTiles();
    Wire3DCGB_EnableAtomicMaps(); wire_colors();
    // First frame: red on the left. Fast begin invalidates both bank histories.
    Wire3DCGB_BeginFrameFast(); wire_frame(8,8,32,32,1);
    Wire3DCGB_EndFrameFast();
    // Second frame: blue in the middle, with the old red frame removed.
    Wire3DCGB_BeginFrameSparse(); wire_frame(40,40,64,64,2);
    Wire3DCGB_EndFrameSparse();
    // Third frame: explicitly clearing a stage discards its first green point.
    Wire3DCGB_BeginFrameSparse();
    Wire3DCGB_SetLineColor(3); Wire3DCGB_DrawPoint2D(4,4);
    Wire3DCGB_ClearSparseStageFast();
    // The final image contains only this green frame on the right.
    wire_frame(80,8,112,32,3);
    Wire3DCGB_MarkDirtyRect2D(80,8,112,32);
    Wire3DCGB_InvalidateFrameHistory();
    Wire3DCGB_EndFrameSparseNow();
    result[0]=Wire3DCGB_GetLineColor();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Les cadres rouge et bleu dessinés précédemment disparaissent ; seul reste le cadre vert final de (80,8) à (112,32), ce qui illustre le transfert partiel et la gestion de l’historique.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_sparse.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_sparse.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:125

kitaqgb/lib/wire3d_cgb.c:8227

c
void Wire3DCGB_ClearSparseStageFast()
{
    w3dcgb_clear_stage_asm();
    w3dcgb_mark_dirty_rect(0, 0,
                           (w3dcgb_u8)(WIRE3DCGB_SCREEN_W - 1),
                           (w3dcgb_u8)(WIRE3DCGB_SCREEN_H - 1));
}
Wire3DCGB_DrawEdgeList2D

Trace au plus 64 arêtes à partir de décalages de sommets préprojetés sur octets signés.

Syntaxe

c
void Wire3DCGB_DrawEdgeList2D(const Wire3DCGB_Edge* edges, w3dcgb_u8 edge_count, const w3dcgb_i8* vertex_x, const w3dcgb_i8* vertex_y, w3dcgb_u8 x, w3dcgb_u8 y, w3dcgb_u8 color);

Paramètres

edges

Indices des sommets de chaque arête, dans le format déclaré de structure ou de paire d’octets.

edge_count

Nombre d’arêtes.

vertex_x

Tableau des décalages X des sommets préprojetés.

vertex_y

Tableau des décalages Y des sommets préprojetés.

x

Coordonnée X du centre en pixels du viewport.

y

Coordonnée Y du centre en pixels du viewport.

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Trace au plus 64 arêtes indexées à partir de décalages sur octets signés autour de (cx,cy). Ignore les tableaux null ; les indices doivent désigner des sommets lisibles. Gardez les extrémités translatées dans le viewport avant la conversion en octets, qui boucle. Choisit selon le mode et préserve l’ancienne couleur ; aucun contrôle du nombre de sommets n’est effectué.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Preprojected edge arrays, a clipped square, a tiny marker and a projectile.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Edge edges[4]={{0,1},{1,2},{2,3},{3,0}};
__prg_rom s8 vx8[4]={-8,8,8,-8};
__prg_rom s8 vy8[4]={-8,-8,8,8};
__prg_rom s16 vx16[4]={-12,12,12,-12};
__prg_rom s16 vy16[4]={-8,-8,8,8};
__prg_rom u8 mask[1]={5};
Wire3DCGB_Model shape;
void main() {
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    shape.vertices=0;shape.edges=edges;shape.faces=0;shape.edge_faces=0;
    shape.vertex_count=4;shape.edge_count=4;shape.face_count=0;shape.flags=0;
    Wire3DCGB_SetLineColor(2);
    Wire3DCGB_DrawMaskedModel2D(&shape,vx8,vy8,mask,24,24,1);
    Wire3DCGB_DrawEdgeList2D(edges,4,vx8,vy8,64,24,2);
    Wire3DCGB_DrawEdgeListClipped2D(edges,4,vx16,vy16,4,4,64,3);
    Wire3DCGB_DrawTinyModel2D(104,24,16,3);
    result[0]=Wire3DCGB_ProjectAxis48(48,96);
    result[1]=Wire3DCGB_ProjectAxis48(-48,96);
    Wire3DCGB_DrawFastProjectile(96,64,64,0,1);
    result[2]=Wire3DCGB_GetLineColor();
    Wire3DCGB_EndFrame();result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Deux arêtes horizontales rouges, un carré bleu, un cadre vert découpé, un repère vert de six pixels et un projectile rouge permettent de comparer les formats de listes.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_lists.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_lists.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:183

kitaqgb/lib/wire3d_cgb.c:8524

c
void Wire3DCGB_DrawEdgeList2D(const Wire3DCGB_Edge* edges, w3dcgb_u8 edge_count,
                             const w3dcgb_i8* vertex_x, const w3dcgb_i8* vertex_y,
                             w3dcgb_u8 x, w3dcgb_u8 y, w3dcgb_u8 color)
{
    w3dcgb_u8 i;
    w3dcgb_u8 a;
    w3dcgb_u8 b;
    w3dcgb_u8 old_color;

    if (edges == 0) return;
    if (vertex_x == 0) return;
    if (vertex_y == 0) return;
    if (edge_count > WIRE3DCGB_MODEL_EDGE_LIMIT) edge_count = WIRE3DCGB_MODEL_EDGE_LIMIT;

    old_color = w3dcgb_line_color;
    w3dcgb_line_color = (w3dcgb_u8)(color & 3);
    if (w3dcgb_full_mode == 0)
    {
        w3dcgb_edge_list_ptr = edges;
        w3dcgb_edge_x_ptr = vertex_x;
        w3dcgb_edge_y_ptr = vertex_y;
        w3dcgb_edge_remaining = edge_count;
        w3dcgb_edge_center_x = x;
        w3dcgb_edge_center_y = y;
        w3dcgb_edge_list_asm();
        w3dcgb_line_color = old_color;
        return;
    }
    i = 0;
    while (i < edge_count)
    {
        a = edges[(__safe_index w3dcgb_u8)i].a;
        b = edges[(__safe_index w3dcgb_u8)i].b;
        w3dcgb_line_x0 = (w3dcgb_u8)((w3dcgb_i16)x + (w3dcgb_i16)vertex_x[(__safe_index w3dcgb_u8)a]);
        w3dcgb_line_y0 = (w3dcgb_u8)((w3dcgb_i16)y + (w3dcgb_i16)vertex_y[(__safe_index w3dcgb_u8)a]);
        w3dcgb_line_x1 = (w3dcgb_u8)((w3dcgb_i16)x + (w3dcgb_i16)vertex_x[(__safe_index w3dcgb_u8)b]);
        w3dcgb_line_y1 = (w3dcgb_u8)((w3dcgb_i16)y + (w3dcgb_i16)vertex_y[(__safe_index w3dcgb_u8)b]);
        if (w3dcgb_full_mode != 0) w3dcgb_full_line_fast_asm();
        else w3dcgb_line_stage_asm();
        i = (w3dcgb_u8)(i + 1);
    }
    w3dcgb_line_color = old_color;
}
Wire3DCGB_DrawEdgeListClipped2D

Valide les sommets projetés signés et les arêtes, puis découpe et trace la liste d’arêtes.

Syntaxe

c
void Wire3DCGB_DrawEdgeListClipped2D(const Wire3DCGB_Edge* edges, w3dcgb_u8 edge_count, const w3dcgb_i16* vx, const w3dcgb_i16* vy, w3dcgb_u8 vertex_count, w3dcgb_i16 cx, w3dcgb_i16 cy, w3dcgb_u8 color);

Paramètres

edges

Indices des sommets de chaque arête, dans le format déclaré de structure ou de paire d’octets.

edge_count

Nombre d’arêtes.

vx

Tableau de décalages X signés sur 16 bits avant découpage.

vy

Tableau de décalages Y signés sur 16 bits avant découpage.

vertex_count

Nombre d’entrées du tableau de sommets.

cx

Coordonnée X du centre en pixels du viewport.

cy

Coordonnée Y du centre en pixels du viewport.

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Avant de dessiner, valide les pointeurs, 1 à 24 sommets, au plus 64 arêtes, chaque indice et les coordonnées et centres d’entrée dans ±2047. La géométrie entièrement visible utilise un tampon temporaire d’octets signés et le chemin indexé rapide ; les autres arêtes passent par le découpage de lignes signées. Celui-ci peut rejeter des extrémités translatées hors de ±2047 même si chaque entrée a passé la validation. Remplace le tampon d’écran partagé et préserve la couleur précédente via les API de lignes appelées.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Preprojected edge arrays, a clipped square, a tiny marker and a projectile.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Edge edges[4]={{0,1},{1,2},{2,3},{3,0}};
__prg_rom s8 vx8[4]={-8,8,8,-8};
__prg_rom s8 vy8[4]={-8,-8,8,8};
__prg_rom s16 vx16[4]={-12,12,12,-12};
__prg_rom s16 vy16[4]={-8,-8,8,8};
__prg_rom u8 mask[1]={5};
Wire3DCGB_Model shape;
void main() {
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    shape.vertices=0;shape.edges=edges;shape.faces=0;shape.edge_faces=0;
    shape.vertex_count=4;shape.edge_count=4;shape.face_count=0;shape.flags=0;
    Wire3DCGB_SetLineColor(2);
    Wire3DCGB_DrawMaskedModel2D(&shape,vx8,vy8,mask,24,24,1);
    Wire3DCGB_DrawEdgeList2D(edges,4,vx8,vy8,64,24,2);
    Wire3DCGB_DrawEdgeListClipped2D(edges,4,vx16,vy16,4,4,64,3);
    Wire3DCGB_DrawTinyModel2D(104,24,16,3);
    result[0]=Wire3DCGB_ProjectAxis48(48,96);
    result[1]=Wire3DCGB_ProjectAxis48(-48,96);
    Wire3DCGB_DrawFastProjectile(96,64,64,0,1);
    result[2]=Wire3DCGB_GetLineColor();
    Wire3DCGB_EndFrame();result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Deux arêtes horizontales rouges, un carré bleu, un cadre vert découpé, un repère vert de six pixels et un projectile rouge permettent de comparer les formats de listes.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_lists.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_lists.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:138

kitaqgb/lib/wire3d_cgb.c:9806

c
void Wire3DCGB_DrawEdgeListClipped2D(const Wire3DCGB_Edge* edges, w3dcgb_u8 edge_count,
    const w3dcgb_i16* vx, const w3dcgb_i16* vy, w3dcgb_u8 vertex_count,
    w3dcgb_i16 cx, w3dcgb_i16 cy, w3dcgb_u8 color)
{
    w3dcgb_u8 i;
    w3dcgb_u8 a;
    w3dcgb_u8 b;
    w3dcgb_u8 inside;
    w3dcgb_i16 x;
    w3dcgb_i16 y;
    w3dcgb_i16 min_x;
    w3dcgb_i16 min_y;
    w3dcgb_i16 max_x;
    w3dcgb_i16 max_y;
    if ((edges == 0) || (vx == 0) || (vy == 0)) return;
    if ((cx < -2047) || (cx > 2047) || (cy < -2047) || (cy > 2047)) return;
    if ((vertex_count == 0) || (vertex_count > WIRE3DCGB_MODEL_VERTEX_LIMIT) ||
        (edge_count > WIRE3DCGB_MODEL_EDGE_LIMIT)) return;
    i = 0;
    while (i < edge_count)
    {
        if ((edges[(__safe_index w3dcgb_u8)i].a >= vertex_count) ||
            (edges[(__safe_index w3dcgb_u8)i].b >= vertex_count)) return;
        i = (w3dcgb_u8)(i + 1);
    }
    min_x = 32767;
    min_y = 32767;
    max_x = -32767;
    max_y = -32767;
    inside = 1;
    i = 0;
    while (i < vertex_count)
    {
        if ((vx[(__safe_index w3dcgb_u8)i] < -2047) ||
            (vx[(__safe_index w3dcgb_u8)i] > 2047) ||
            (vy[(__safe_index w3dcgb_u8)i] < -2047) ||
            (vy[(__safe_index w3dcgb_u8)i] > 2047)) return;
        x = (w3dcgb_i16)(cx + vx[(__safe_index w3dcgb_u8)i]);
        y = (w3dcgb_i16)(cy + vy[(__safe_index w3dcgb_u8)i]);
        if (x < min_x) min_x = x;
        if (x > max_x) max_x = x;
        if (y < min_y) min_y = y;
        if (y > max_y) max_y = y;
        /* Reuse projected-vertex scratch; drawing is non-reentrant. */
        w3dcgb_screen_x[(__safe_index w3dcgb_u8)i] = (w3dcgb_u8)(x - 64);
        w3dcgb_screen_y[(__safe_index w3dcgb_u8)i] = (w3dcgb_u8)(y - 48);
        i = (w3dcgb_u8)(i + 1);
    }
    if ((w3dcgb_clip_outcode(min_x, min_y) | w3dcgb_clip_outcode(max_x, max_y)) != 0) inside = 0;
    if (inside != 0)
    {
        if (w3dcgb_full_mode == 0) w3dcgb_mark_dirty_rect((w3dcgb_u8)min_x,
            (w3dcgb_u8)min_y, (w3dcgb_u8)max_x, (w3dcgb_u8)max_y);
        Wire3DCGB_DrawEdgeList2D(edges, edge_count, (const w3dcgb_i8*)w3dcgb_screen_x,
            (const w3dcgb_i8*)w3dcgb_screen_y, 64, 48, color);
        return;
    }
    i = 0;
    while (i < edge_count)
    {
        a = edges[(__safe_index w3dcgb_u8)i].a;
        b = edges[(__safe_index w3dcgb_u8)i].b;
        Wire3DCGB_DrawLineClipped2D((w3dcgb_i16)(cx + vx[(__safe_index w3dcgb_u8)a]),
            (w3dcgb_i16)(cy + vy[(__safe_index w3dcgb_u8)a]),
            (w3dcgb_i16)(cx + vx[(__safe_index w3dcgb_u8)b]),
            (w3dcgb_i16)(cy + vy[(__safe_index w3dcgb_u8)b]), color);
        i = (w3dcgb_u8)(i + 1);
    }
}
Wire3DCGB_DrawFastCubeFrame

Remplace l’image précédente de motifs de cube et transfère au plus trois motifs avec leurs indicateurs d’état.

Syntaxe

c
void Wire3DCGB_DrawFastCubeFrame(Wire3DCGB_FastCube* cubes, w3dcgb_u8 count, w3dcgb_u8 hidden_enabled, w3dcgb_u8 selected);

Paramètres

cubes

Tableau de positions, angles et couleurs pour le dessin rapide de cubes.

count

Nombre d’entrées fournies ; consultez la limite de traitement propre à l’opération.

hidden_enabled

Zéro inclut les arêtes cachées ; une valeur non nulle choisit leur suppression simplifiée.

selected

Indice de l’objet sélectionné dans le tableau original ; l’API de motifs l’utilise pour un indicateur d’état.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Prépare la carte, efface les anciennes limites et cases d’état, trie au plus trois motifs de cube du plus loin au plus près selon le Z brut, puis dessine et transfère numéros et attributs au VBlank. Le tableau de l’appelant reste dans son ordre. Avec un tableau non nul, count zéro efface les anciens motifs ; un tableau null ne fait rien. selected & 3 choisit seulement la case d’état, pas une mise en évidence du cube. Nécessite les motifs chargés, le runtime complet et un mappage WRAM FastMap cohérent ; ne les initialise pas.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Au démarrage sparse CGB, la première utilisation de chaque banque cible (les deux premières images) actualise tout le viewport et efface les tuiles d’initialisation. Cette charge est incluse dans les mesures. DrawLine2D ne déclare pas de zone sparse : utilisez DrawLineClipped2D ou MarkDirtyRect2D explicitement.

Exemple d’utilisation

c
#pragma bank 0
// A complete cube-stamp frame removes the preceding stamp's old map cells.
#include "wire_cgb_example.h"
Wire3DCGB_FastCube cube[1];
void main() {
    u8 bank;
    wire_results_clear(); Wire3DCGB_Init(); wire_colors();
    cube[0].x=-24;cube[0].y=0;cube[0].z=96;
    cube[0].rx=0;cube[0].ry=0;cube[0].rz=0;cube[0].color=1;
    bank=sample_svbk;sample_svbk=2;
    Wire3DCGB_DrawFastCubeFrame(cube,1,1,0);
    cube[0].x=24;
    Wire3DCGB_DrawFastCubeFrame(cube,1,1,0);
    sample_svbk=bank;result[0]=cube[0].x;result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

L’ancien motif de cube disparaît. Un cube rouge de 32×32 commence en (72,32), avec des indicateurs d’état verts en haut.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_stamp.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_stamp.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:158

kitaqgb/lib/wire3d_cgb.c:10800

c
void Wire3DCGB_DrawFastCubeFrame(Wire3DCGB_FastCube* cubes, w3dcgb_u8 count, w3dcgb_u8 hidden_enabled, w3dcgb_u8 selected)
{
    w3dcgb_u8 i;
    w3dcgb_u8 scene_count;
    w3dcgb_u8 a;
    w3dcgb_u8 b;
    w3dcgb_u8 c;
    w3dcgb_u8 x;

    if (cubes == 0) return;
    scene_count = count;
    if (scene_count > 3) scene_count = 3;

    w3dcgb_fast_map_prepare();

    i = 0;
    while (i < w3dcgb_fast_prev_count)
    {
        w3dcgb_fast_map_clear_rect(
            w3dcgb_fast_prev_x[(__safe_index w3dcgb_u8)i],
            w3dcgb_fast_prev_y[(__safe_index w3dcgb_u8)i],
            w3dcgb_fast_prev_w[(__safe_index w3dcgb_u8)i],
            w3dcgb_fast_prev_h[(__safe_index w3dcgb_u8)i]);
        i = (w3dcgb_u8)(i + 1);
    }
    w3dcgb_fast_map_clear_rect(0, 0, 4, 1);
    w3dcgb_fast_map_clear_rect(14, 0, 2, 1);

    if (scene_count == 0)
    {
        w3dcgb_fast_prev_count = 0;
        w3dcgb_wait_vblank_start();
        w3dcgb_fast_map_flush_gdma_asm();
        return;
    }

    a = 0;
    b = 1;
    c = 2;
    if (scene_count == 1)
    {
        w3dcgb_fast_map_draw_cube_one(&cubes[0], hidden_enabled, (w3dcgb_u8)(selected == 0), 0);
        w3dcgb_fast_prev_count = 1;
    }
    else if (scene_count == 2)
    {
        if (cubes[0].z < cubes[1].z)
        {
            w3dcgb_fast_map_draw_cube_one(&cubes[1], hidden_enabled, (w3dcgb_u8)(selected == 1), 1);
            w3dcgb_fast_map_draw_cube_one(&cubes[0], hidden_enabled, (w3dcgb_u8)(selected == 0), 0);
        }
        else
        {
            w3dcgb_fast_map_draw_cube_one(&cubes[0], hidden_enabled, (w3dcgb_u8)(selected == 0), 0);
            w3dcgb_fast_map_draw_cube_one(&cubes[1], hidden_enabled, (w3dcgb_u8)(selected == 1), 1);
        }
        w3dcgb_fast_prev_count = 2;
    }
    else
    {
        if (cubes[a].z < cubes[b].z)
        {
            w3dcgb_u8 t;
            t = a;
            a = b;
            b = t;
        }
        if (cubes[b].z < cubes[c].z)
        {
            w3dcgb_u8 t;
            t = b;
            b = c;
            c = t;
        }
        if (cubes[a].z < cubes[b].z)
        {
            w3dcgb_u8 t;
            t = a;
            a = b;
            b = t;
        }
        w3dcgb_fast_map_draw_cube_one(&cubes[a], hidden_enabled, (w3dcgb_u8)(selected == a), a);
        w3dcgb_fast_map_draw_cube_one(&cubes[b], hidden_enabled, (w3dcgb_u8)(selected == b), b);
        w3dcgb_fast_map_draw_cube_one(&cubes[c], hidden_enabled, (w3dcgb_u8)(selected == c), c);
        w3dcgb_fast_prev_count = 3;
    }

    x = (w3dcgb_u8)(selected & 3);
    w3dcgb_fast_map_or_cell((w3dcgb_i16)x, (w3dcgb_i16)0, WIRE3DCGB_COLOR_HIGH, 15);
    if (hidden_enabled != 0) w3dcgb_fast_map_or_cell((w3dcgb_i16)15, (w3dcgb_i16)0, WIRE3DCGB_COLOR_HIGH, 15);
    else w3dcgb_fast_map_or_cell((w3dcgb_i16)14, (w3dcgb_i16)0, WIRE3DCGB_COLOR_LOW, 15);

    w3dcgb_wait_vblank_start();
    w3dcgb_fast_map_flush_gdma_asm();
}
Wire3DCGB_DrawFastCubes

Dessine au plus trois cubes sous forme de contours 2D dimensionnés selon la profondeur.

Syntaxe

c
void Wire3DCGB_DrawFastCubes(Wire3DCGB_FastCube* cubes, w3dcgb_u8 count, w3dcgb_u8 hidden_enabled, w3dcgb_u8 selected);

Paramètres

cubes

Tableau de positions, angles et couleurs pour le dessin rapide de cubes.

count

Nombre d’entrées fournies ; consultez la limite de traitement propre à l’opération.

hidden_enabled

Zéro inclut les arêtes cachées ; une valeur non nulle choisit leur suppression simplifiée.

selected

Indice de l’objet sélectionné dans le tableau original ; l’API de motifs l’utilise pour un indicateur d’état.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Dessine au plus trois approximations 2D de cubes, triées du plus loin au plus près selon le Z brut sans réordonner le tableau de l’appelant. Ignore null ou une entrée vide. selected est un indice du tableau original. Caméra et rotation ne sont pas utilisées ; la couleur n’est pas restaurée.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Fast cube approximations use screen offsets and depth size bands, not a camera.
#include "wire_cgb_example.h"
Wire3DCGB_FastCube cubes[2];
void main() {
    u8 i;
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    for(i=0;i<2;i++){cubes[i].rx=0;cubes[i].ry=0;cubes[i].rz=0;}
    cubes[0].x=-32;cubes[0].y=-8;cubes[0].z=90;cubes[0].color=1;
    cubes[1].x=32;cubes[1].y=8;cubes[1].z=160;cubes[1].color=2;
    Wire3DCGB_SetCamera(100,0,0,4,4,4); // FastCubes intentionally ignores this.
    Wire3DCGB_DrawFastCubes(cubes,2,1,0);
    Wire3DCGB_DrawFastStatus(1,0);
    result[0]=Wire3DCGB_GetLineColor();
    result[1]=cubes[0].z;result[2]=cubes[1].z;
    Wire3DCGB_EndFrame();result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Le cube rouge proche à gauche est plus grand que le cube bleu lointain à droite. Une croix verte marque le cube rouge sélectionné.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_cubes.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_cubes.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:156

kitaqgb/lib/wire3d_cgb.c:8765

c
void Wire3DCGB_DrawFastCubes(Wire3DCGB_FastCube* cubes, w3dcgb_u8 count, w3dcgb_u8 hidden_enabled, w3dcgb_u8 selected)
{
    w3dcgb_u8 scene_count;
    w3dcgb_u8 a;
    w3dcgb_u8 b;
    w3dcgb_u8 c;
    w3dcgb_u8 x;

    if (cubes == 0) return;
    scene_count = count;
    if (scene_count == 0) return;
    if (scene_count > 3) scene_count = 3;

    a = 0;
    b = 1;
    c = 2;
    if (scene_count == 1)
    {
        w3dcgb_draw_fast_cube_one(&cubes[0], hidden_enabled, (w3dcgb_u8)(selected == 0));
        return;
    }

    if (scene_count == 2)
    {
        if (cubes[0].z < cubes[1].z)
        {
            w3dcgb_draw_fast_cube_one(&cubes[1], hidden_enabled, (w3dcgb_u8)(selected == 1));
            w3dcgb_draw_fast_cube_one(&cubes[0], hidden_enabled, (w3dcgb_u8)(selected == 0));
        }
        else
        {
            w3dcgb_draw_fast_cube_one(&cubes[0], hidden_enabled, (w3dcgb_u8)(selected == 0));
            w3dcgb_draw_fast_cube_one(&cubes[1], hidden_enabled, (w3dcgb_u8)(selected == 1));
        }
        return;
    }

    if (cubes[a].z < cubes[b].z)
    {
        w3dcgb_u8 t;
        t = a;
        a = b;
        b = t;
    }
    if (cubes[b].z < cubes[c].z)
    {
        w3dcgb_u8 t;
        t = b;
        b = c;
        c = t;
    }
    if (cubes[a].z < cubes[b].z)
    {
        w3dcgb_u8 t;
        t = a;
        a = b;
        b = t;
    }

    w3dcgb_draw_fast_cube_one(&cubes[a], hidden_enabled, (w3dcgb_u8)(selected == a));
    w3dcgb_draw_fast_cube_one(&cubes[b], hidden_enabled, (w3dcgb_u8)(selected == b));
    w3dcgb_draw_fast_cube_one(&cubes[c], hidden_enabled, (w3dcgb_u8)(selected == c));
}
Wire3DCGB_DrawFastProjectile

Dessine un projectile à six arêtes autour d’un centre déjà projeté, la profondeur et la phase choisissant sa taille et son orientation.

Syntaxe

c
void Wire3DCGB_DrawFastProjectile(w3dcgb_u8 x, w3dcgb_u8 y, w3dcgb_i16 z, w3dcgb_u8 phase, w3dcgb_u8 color);

Paramètres

x

Coordonnée X du centre en pixels du viewport.

y

Coordonnée Y du centre en pixels du viewport.

z

Profondeur utilisée pour choisir la taille ou calculer la projection.

phase

Phase de rotation ; passe à l’orientation suivante tous les huit comptes.

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Dessine un projectile à six arêtes autour d’un centre déjà projeté, avec quatre tailles selon la profondeur et quatre orientations selon la phase. Rejette les centres hors de X=10..117 ou Y=10..85, marque les limites modifiées et laisse la couleur demandée sélectionnée. Utilise le rastériseur normal sans appliquer la caméra.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Preprojected edge arrays, a clipped square, a tiny marker and a projectile.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Edge edges[4]={{0,1},{1,2},{2,3},{3,0}};
__prg_rom s8 vx8[4]={-8,8,8,-8};
__prg_rom s8 vy8[4]={-8,-8,8,8};
__prg_rom s16 vx16[4]={-12,12,12,-12};
__prg_rom s16 vy16[4]={-8,-8,8,8};
__prg_rom u8 mask[1]={5};
Wire3DCGB_Model shape;
void main() {
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    shape.vertices=0;shape.edges=edges;shape.faces=0;shape.edge_faces=0;
    shape.vertex_count=4;shape.edge_count=4;shape.face_count=0;shape.flags=0;
    Wire3DCGB_SetLineColor(2);
    Wire3DCGB_DrawMaskedModel2D(&shape,vx8,vy8,mask,24,24,1);
    Wire3DCGB_DrawEdgeList2D(edges,4,vx8,vy8,64,24,2);
    Wire3DCGB_DrawEdgeListClipped2D(edges,4,vx16,vy16,4,4,64,3);
    Wire3DCGB_DrawTinyModel2D(104,24,16,3);
    result[0]=Wire3DCGB_ProjectAxis48(48,96);
    result[1]=Wire3DCGB_ProjectAxis48(-48,96);
    Wire3DCGB_DrawFastProjectile(96,64,64,0,1);
    result[2]=Wire3DCGB_GetLineColor();
    Wire3DCGB_EndFrame();result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Deux arêtes horizontales rouges, un carré bleu, un cadre vert découpé, un repère vert de six pixels et un projectile rouge permettent de comparer les formats de listes.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_lists.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_lists.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:159

kitaqgb/lib/wire3d_cgb.c:8833

c
void Wire3DCGB_DrawFastProjectile(w3dcgb_u8 x, w3dcgb_u8 y, w3dcgb_i16 z,
                                  w3dcgb_u8 phase, w3dcgb_u8 color)
{
    w3dcgb_u8 radius;
    w3dcgb_u8 half;
    w3dcgb_u8 depth;
    w3dcgb_u8 ax;
    w3dcgb_u8 ay;
    w3dcgb_u8 bx;
    w3dcgb_u8 by;
    w3dcgb_u8 cx;
    w3dcgb_u8 cy;
    w3dcgb_u8 dx;
    w3dcgb_u8 dy;
    w3dcgb_u8 spin;

    if ((x < 10) || (x > 117) || (y < 10) || (y > 85)) return;
    radius = 3;
    depth = 1;
    if (z <= 160) { radius = 4; depth = 2; }
    if (z <= 112) { radius = 5; depth = 3; }
    if (z <= 64) { radius = 7; depth = 4; }
    half = (w3dcgb_u8)(radius >> 1);

    ax = x;
    ay = (w3dcgb_u8)(y - radius);
    bx = (w3dcgb_u8)(x - radius);
    by = (w3dcgb_u8)(y + half);
    cx = (w3dcgb_u8)(x + radius);
    cy = by;
    spin = (w3dcgb_u8)((phase >> 3) & 3);
    dx = (w3dcgb_u8)(x + depth);
    dy = (w3dcgb_u8)(y - depth);
    if (spin == 1) dy = (w3dcgb_u8)(y + depth);
    else if (spin == 2)
    {
        dx = (w3dcgb_u8)(x - depth);
        dy = (w3dcgb_u8)(y + depth);
    }
    else if (spin == 3) dx = (w3dcgb_u8)(x - depth);

    w3dcgb_mark_dirty_rect((w3dcgb_u8)(x - radius), (w3dcgb_u8)(y - radius),
                           (w3dcgb_u8)(x + radius), (w3dcgb_u8)(y + radius));
    w3dcgb_line_color = color;
    w3dcgb_draw_line_raw(ax, ay, bx, by);
    w3dcgb_draw_line_raw(bx, by, cx, cy);
    w3dcgb_draw_line_raw(cx, cy, ax, ay);
    w3dcgb_draw_line_raw(ax, ay, dx, dy);
    w3dcgb_draw_line_raw(bx, by, dx, dy);
    w3dcgb_draw_line_raw(cx, cy, dx, dy);
}
Wire3DCGB_DrawFastStatus

Dessine de petits indicateurs en lignes pour la sélection d’objet et le mode de lignes cachées.

Syntaxe

c
void Wire3DCGB_DrawFastStatus(w3dcgb_u8 hidden_enabled, w3dcgb_u8 selected);

Paramètres

hidden_enabled

Zéro inclut les arêtes cachées ; une valeur non nulle choisit leur suppression simplifiée.

selected

Indice de l’objet sélectionné dans le tableau original ; l’API de motifs l’utilise pour un indicateur d’état.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Dessine de petits indicateurs de sélection et de mode de lignes cachées en couleur 3, et marque leurs limites normales comme modifiées. selected doit valoir 0..2, sans vérification. Ces indicateurs utilisent des lignes, pas des tuiles de police ; la couleur précédente n’est pas restaurée.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Fast cube approximations use screen offsets and depth size bands, not a camera.
#include "wire_cgb_example.h"
Wire3DCGB_FastCube cubes[2];
void main() {
    u8 i;
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    for(i=0;i<2;i++){cubes[i].rx=0;cubes[i].ry=0;cubes[i].rz=0;}
    cubes[0].x=-32;cubes[0].y=-8;cubes[0].z=90;cubes[0].color=1;
    cubes[1].x=32;cubes[1].y=8;cubes[1].z=160;cubes[1].color=2;
    Wire3DCGB_SetCamera(100,0,0,4,4,4); // FastCubes intentionally ignores this.
    Wire3DCGB_DrawFastCubes(cubes,2,1,0);
    Wire3DCGB_DrawFastStatus(1,0);
    result[0]=Wire3DCGB_GetLineColor();
    result[1]=cubes[0].z;result[2]=cubes[1].z;
    Wire3DCGB_EndFrame();result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Le cube rouge proche à gauche est plus grand que le cube bleu lointain à droite. Une croix verte marque le cube rouge sélectionné.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_cubes.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_cubes.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:157

kitaqgb/lib/wire3d_cgb.c:8888

c
void Wire3DCGB_DrawFastStatus(w3dcgb_u8 hidden_enabled, w3dcgb_u8 selected)
{
    w3dcgb_u8 x;

    w3dcgb_mark_dirty_rect(0, 0, 31, 7);
    w3dcgb_mark_dirty_rect(116, 0, 127, 7);

    x = (w3dcgb_u8)(4 + (selected * 8));
    w3dcgb_line_color = WIRE3DCGB_COLOR_HIGH;
    w3dcgb_draw_line_raw(x, 3, (w3dcgb_u8)(x + 5), 3);
    w3dcgb_draw_line_raw(x, 6, (w3dcgb_u8)(x + 5), 6);
    if (hidden_enabled != 0)
    {
        w3dcgb_draw_line_raw(118, 3, 124, 3);
        w3dcgb_draw_line_raw(118, 6, 124, 6);
    }
    else
    {
        w3dcgb_draw_line_raw(118, 3, 124, 6);
        w3dcgb_draw_line_raw(118, 6, 124, 3);
    }
}
Wire3DCGB_DrawLine2D

Trace une ligne en coordonnées écran, extrémités incluses, avec le moteur actif.

Syntaxe

c
void Wire3DCGB_DrawLine2D(w3dcgb_u8 ax, w3dcgb_u8 ay, w3dcgb_u8 bx, w3dcgb_u8 by);

Paramètres

ax

Coordonnée X du sommet A en pixels du viewport.

ay

Coordonnée Y du sommet A en pixels du viewport.

bx

Coordonnée X du sommet B en pixels du viewport.

by

Coordonnée Y du sommet B en pixels du viewport.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Mémorise les extrémités sur octets et appelle le rastériseur de lignes normal ou plein écran. Les coordonnées doivent être dans le viewport choisi ; utilisez DrawLineClipped2D pour une géométrie signée ou hors écran. Les lignes normales combinent les plans de couleur par OR sans marquer les limites partielles ; utilisez l’API avec découpage ou InvalidateFrameHistory avant un transfert partiel. Les lignes plein écran remplacent les couleurs et allouent des tuiles. Les deux chemins traitent la couleur zéro comme 3, pas comme un effacement.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:177

kitaqgb/lib/wire3d_cgb.c:8363

c
void Wire3DCGB_DrawLine2D(w3dcgb_u8 ax, w3dcgb_u8 ay, w3dcgb_u8 bx, w3dcgb_u8 by)
{
    w3dcgb_line_x0 = ax;
    w3dcgb_line_y0 = ay;
    w3dcgb_line_x1 = bx;
    w3dcgb_line_y1 = by;
    if (w3dcgb_full_mode != 0) w3dcgb_full_line_fast_asm();
    else w3dcgb_line_stage_asm();
}
Wire3DCGB_DrawLine2DColor

Trace une ligne en coordonnées écran dans une couleur temporaire, en préservant la couleur sélectionnée.

Syntaxe

c
void Wire3DCGB_DrawLine2DColor(w3dcgb_u8 ax, w3dcgb_u8 ay, w3dcgb_u8 bx, w3dcgb_u8 by, w3dcgb_u8 color);

Paramètres

ax

Coordonnée X du sommet A en pixels du viewport.

ay

Coordonnée Y du sommet A en pixels du viewport.

bx

Coordonnée X du sommet B en pixels du viewport.

by

Coordonnée Y du sommet B en pixels du viewport.

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Définit color & 3 pour DrawLine2D, puis restaure la couleur précédente. Respectez son contrat de coordonnées, de combinaison des couleurs et de plages partielles ; zéro n’efface une ligne dans aucun des deux moteurs actifs.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:178

kitaqgb/lib/wire3d_cgb.c:8376

c
void Wire3DCGB_DrawLine2DColor(w3dcgb_u8 ax, w3dcgb_u8 ay, w3dcgb_u8 bx, w3dcgb_u8 by, w3dcgb_u8 color)
{
    w3dcgb_u8 old_color;
    old_color = w3dcgb_line_color;
    Wire3DCGB_SetLineColor(color);
    Wire3DCGB_DrawLine2D(ax, ay, bx, by);
    w3dcgb_line_color = old_color;
}
Wire3DCGB_DrawLine3D

Projette les extrémités du monde par la caméra et trace une ligne dans la couleur courante.

Syntaxe

c
void Wire3DCGB_DrawLine3D(w3dcgb_i16 ax, w3dcgb_i16 ay, w3dcgb_i16 az, w3dcgb_i16 bx, w3dcgb_i16 by, w3dcgb_i16 bz);

Paramètres

ax

Composante X du point de départ en coordonnées du monde.

ay

Composante Y du point de départ en coordonnées du monde.

az

Composante Z du point de départ en coordonnées du monde.

bx

Composante X du point d’arrivée en coordonnées du monde.

by

Composante Y du point d’arrivée en coordonnées du monde.

bz

Composante Z du point d’arrivée en coordonnées du monde.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Projette les deux extrémités par la caméra vers le viewport de 128×96. Rejette toute la ligne si une extrémité échoue au test de profondeur ; ne découpe pas les traversées du plan proche. DrawLine2D choisit selon le mode, mais la projection reste en 128×96. Les lignes normales cumulent les plans de couleur sans marquer les limites partielles ; utilisez un transfert complet ou invalidez explicitement l’historique avant un transfert partiel.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Four cubes compare unity/half scale and persistent/temporary line colors.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Vec3 vertices[8]={
    {-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},
    {-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}
};
__prg_rom Wire3DCGB_Edge edges[12]={
    {0,1},{1,2},{2,3},{3,0},{4,5},{5,6},
    {6,7},{7,4},{0,4},{1,5},{2,6},{3,7}
};
Wire3DCGB_Model cube;
u8 sx;
u8 sy;
void main() {
    wire_results_clear();
    cube.vertices=vertices; cube.edges=edges;
    cube.faces=0; cube.edge_faces=0;
    cube.vertex_count=8; cube.edge_count=12; cube.face_count=0; cube.flags=0;
    Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DCGB_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    Wire3DCGB_DrawModelColor(&cube,-32,-32,96,0,0,0,2);
    Wire3DCGB_DrawModelScaledColor(&cube,32,-32,96,0,0,0,128,3);
    result[0]=Wire3DCGB_GetLineColor();
    Wire3DCGB_DrawLine3D(0,56,96,0,-56,96);
    Wire3DCGB_DrawLine3DColor(-80,0,96,80,0,96,3);
    result[1]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[2]=sx; result[3]=sy;
    // Camera setters affect future projection, leaving the staged cubes intact.
    Wire3DCGB_SetCamera(0,0,0,0,4,0);
    result[4]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[5]=Wire3DCGB_ProjectPointNoRotation(0,0,96,&sx,&sy);
    result[6]=sx;
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Compare les modèles à l’échelle unitaire et redimensionnés en rouge, bleu et vert, ainsi que des lignes 3D qui se croisent. Les valeurs en RAM vérifient aussi la projection de caméra et sa variante sans rotation.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_models.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:172

kitaqgb/lib/wire3d_cgb.c:8992

c
void Wire3DCGB_DrawLine3D(w3dcgb_i16 ax, w3dcgb_i16 ay, w3dcgb_i16 az, w3dcgb_i16 bx, w3dcgb_i16 by, w3dcgb_i16 bz)
{
    w3dcgb_u8 sx0;
    w3dcgb_u8 sy0;
    w3dcgb_u8 sx1;
    w3dcgb_u8 sy1;

    if (w3dcgb_project_world(ax, ay, az, &sx0, &sy0) == 0) return;
    if (w3dcgb_project_world(bx, by, bz, &sx1, &sy1) == 0) return;
    Wire3DCGB_DrawLine2D(sx0, sy0, sx1, sy1);
}
Wire3DCGB_DrawLine3DColor

Trace une ligne 3D dans une couleur temporaire.

Syntaxe

c
void Wire3DCGB_DrawLine3DColor(w3dcgb_i16 ax, w3dcgb_i16 ay, w3dcgb_i16 az, w3dcgb_i16 bx, w3dcgb_i16 by, w3dcgb_i16 bz, w3dcgb_u8 color);

Paramètres

ax

Composante X du point de départ en coordonnées du monde.

ay

Composante Y du point de départ en coordonnées du monde.

az

Composante Z du point de départ en coordonnées du monde.

bx

Composante X du point d’arrivée en coordonnées du monde.

by

Composante Y du point d’arrivée en coordonnées du monde.

bz

Composante Z du point d’arrivée en coordonnées du monde.

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Sélectionne temporairement color & 3 pour DrawLine3D, puis restaure l’ancienne couleur.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Four cubes compare unity/half scale and persistent/temporary line colors.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Vec3 vertices[8]={
    {-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},
    {-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}
};
__prg_rom Wire3DCGB_Edge edges[12]={
    {0,1},{1,2},{2,3},{3,0},{4,5},{5,6},
    {6,7},{7,4},{0,4},{1,5},{2,6},{3,7}
};
Wire3DCGB_Model cube;
u8 sx;
u8 sy;
void main() {
    wire_results_clear();
    cube.vertices=vertices; cube.edges=edges;
    cube.faces=0; cube.edge_faces=0;
    cube.vertex_count=8; cube.edge_count=12; cube.face_count=0; cube.flags=0;
    Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DCGB_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    Wire3DCGB_DrawModelColor(&cube,-32,-32,96,0,0,0,2);
    Wire3DCGB_DrawModelScaledColor(&cube,32,-32,96,0,0,0,128,3);
    result[0]=Wire3DCGB_GetLineColor();
    Wire3DCGB_DrawLine3D(0,56,96,0,-56,96);
    Wire3DCGB_DrawLine3DColor(-80,0,96,80,0,96,3);
    result[1]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[2]=sx; result[3]=sy;
    // Camera setters affect future projection, leaving the staged cubes intact.
    Wire3DCGB_SetCamera(0,0,0,0,4,0);
    result[4]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[5]=Wire3DCGB_ProjectPointNoRotation(0,0,96,&sx,&sy);
    result[6]=sx;
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Compare les modèles à l’échelle unitaire et redimensionnés en rouge, bleu et vert, ainsi que des lignes 3D qui se croisent. Les valeurs en RAM vérifient aussi la projection de caméra et sa variante sans rotation.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_models.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:173

kitaqgb/lib/wire3d_cgb.c:9005

c
void Wire3DCGB_DrawLine3DColor(w3dcgb_i16 ax, w3dcgb_i16 ay, w3dcgb_i16 az, w3dcgb_i16 bx, w3dcgb_i16 by, w3dcgb_i16 bz, w3dcgb_u8 color)
{
    w3dcgb_u8 old_color;
    old_color = w3dcgb_line_color;
    Wire3DCGB_SetLineColor(color);
    Wire3DCGB_DrawLine3D(ax, ay, az, bx, by, bz);
    w3dcgb_line_color = old_color;
}
Wire3DCGB_DrawLineClipped2D

Découpe les coordonnées d’écran signées au viewport et trace une ligne dans la couleur demandée.

Syntaxe

c
void Wire3DCGB_DrawLineClipped2D(w3dcgb_i16 x0, w3dcgb_i16 y0, w3dcgb_i16 x1, w3dcgb_i16 y1, w3dcgb_u8 color);

Paramètres

x0

Borne X inférieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

y0

Borne Y inférieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

x1

Borne X supérieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

y1

Borne Y supérieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Les extrémités signées sont découpées avant conversion vers l’ABI u8 du rastériseur. Découpe une ligne 2D signée au viewport choisi, puis la trace avec une couleur temporaire. Rejette les entrées hors de ±2047. Les lignes entièrement dans 128×96 utilisent un chemin rapide ; les autres utilisent des codes de région et des intersections entières bornées, avec une limite de huit itérations. Les lignes acceptées en mode normal marquent les limites modifiées. Ce n’est qu’un découpage à l’écran, sans projection 3D ni découpage en profondeur.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:136

Notes de déclaration (texte source)
Signed endpoints, clipped before conversion to the rasterizer's u8 ABI.

kitaqgb/lib/wire3d_cgb.c:9745

c
void Wire3DCGB_DrawLineClipped2D(w3dcgb_i16 x0, w3dcgb_i16 y0,
                               w3dcgb_i16 x1, w3dcgb_i16 y1, w3dcgb_u8 color)
{
    w3dcgb_u8 c0;
    w3dcgb_u8 c1;
    w3dcgb_u8 outside;
    w3dcgb_u8 guard;
    w3dcgb_i16 x;
    w3dcgb_i16 y;
    c0 = 0;
    c1 = 0;
    if ((((x0 | y0 | x1 | y1) & 0xFF80) != 0) || (y0 >= WIRE3DCGB_SCREEN_H) || (y1 >= WIRE3DCGB_SCREEN_H))
    {
        if ((x0 < -2047) || (x0 > 2047) || (y0 < -2047) || (y0 > 2047) ||
            (x1 < -2047) || (x1 > 2047) || (y1 < -2047) || (y1 > 2047)) return;
        c0 = w3dcgb_clip_outcode(x0, y0);
        c1 = w3dcgb_clip_outcode(x1, y1);
    }
    guard = 0;
    while (guard < 8)
    {
        if ((c0 | c1) == 0)
        {
            /* The existing ASM rasterizer handles the hot, in-window path. */
            if (w3dcgb_full_mode == 0) w3dcgb_mark_dirty_line((w3dcgb_u8)x0, (w3dcgb_u8)y0,
                                  (w3dcgb_u8)x1, (w3dcgb_u8)y1);
            Wire3DCGB_DrawLine2DColor((w3dcgb_u8)x0, (w3dcgb_u8)y0,
                                    (w3dcgb_u8)x1, (w3dcgb_u8)y1, color);
            return;
        }
        if ((c0 & c1) != 0) return;
        outside = c0;
        if (outside == 0) outside = c1;
        if ((outside & 12) != 0)
        {
            y = 0;
            if ((outside & 8) != 0) y = WIRE3DCGB_SCREEN_H - 1;
            if (((outside & 8) != 0) && (w3dcgb_full_mode != 0)) y = WIRE3DCGB_FULL_SCREEN_H - 1;
            x = (w3dcgb_i16)(x0 + w3dcgb_clip_muldiv((w3dcgb_i16)(x1 - x0),
                (w3dcgb_i16)(y - y0), (w3dcgb_i16)(y1 - y0)));
        }
        else
        {
            x = 0;
            if ((outside & 2) != 0) x = WIRE3DCGB_SCREEN_W - 1;
            if (((outside & 2) != 0) && (w3dcgb_full_mode != 0)) x = WIRE3DCGB_FULL_SCREEN_W - 1;
            y = (w3dcgb_i16)(y0 + w3dcgb_clip_muldiv((w3dcgb_i16)(y1 - y0),
                (w3dcgb_i16)(x - x0), (w3dcgb_i16)(x1 - x0)));
        }
        if (outside == c0) { x0 = x; y0 = y; c0 = w3dcgb_clip_outcode(x0, y0); }
        else { x1 = x; y1 = y; c1 = w3dcgb_clip_outcode(x1, y1); }
        guard = (w3dcgb_u8)(guard + 1);
    }
}
Wire3DCGB_DrawLineList2DColor

Trace une liste de lignes en coordonnées écran, à quatre octets par enregistrement, dans la couleur choisie.

Syntaxe

c
void Wire3DCGB_DrawLineList2DColor(const w3dcgb_u8* line_xy, w3dcgb_u8 line_count, w3dcgb_u8 color);

Paramètres

line_xy

Tableau d’octets d’enregistrements x0,y0,x1,y1.

line_count

Nombre d’enregistrements de lignes ; au plus 64 sont traités.

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Trace au plus 64 enregistrements de quatre octets (x0,y0,x1,y1), en ignorant une liste null. Les extrémités doivent être dans le viewport choisi. Préserve la couleur précédente et envoie chaque ligne au rastériseur normal ou plein écran.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:186

kitaqgb/lib/wire3d_cgb.c:8571

c
void Wire3DCGB_DrawLineList2DColor(const w3dcgb_u8* line_xy,
                                  w3dcgb_u8 line_count, w3dcgb_u8 color)
{
    w3dcgb_u8 i;
    w3dcgb_u8 offset;
    w3dcgb_u8 old_color;
    if (line_xy == 0) return;
    if (line_count > WIRE3DCGB_MODEL_EDGE_LIMIT) line_count = WIRE3DCGB_MODEL_EDGE_LIMIT;

    old_color = w3dcgb_line_color;
    w3dcgb_line_color = (w3dcgb_u8)(color & 3);
    i = 0;
    offset = 0;
    while (i < line_count)
    {
        w3dcgb_line_x0 = line_xy[(__safe_index w3dcgb_u8)offset];
        offset = (w3dcgb_u8)(offset + 1);
        w3dcgb_line_y0 = line_xy[(__safe_index w3dcgb_u8)offset];
        offset = (w3dcgb_u8)(offset + 1);
        w3dcgb_line_x1 = line_xy[(__safe_index w3dcgb_u8)offset];
        offset = (w3dcgb_u8)(offset + 1);
        w3dcgb_line_y1 = line_xy[(__safe_index w3dcgb_u8)offset];
        offset = (w3dcgb_u8)(offset + 1);
        if (w3dcgb_full_mode != 0) w3dcgb_full_line_fast_asm();
        else w3dcgb_line_stage_asm();
        i = (w3dcgb_u8)(i + 1);
    }
    w3dcgb_line_color = old_color;
}
Wire3DCGB_DrawMaskedModel2D

Trace les arêtes activées à partir de sommets préprojetés et d’un masque de bits d’arêtes.

Syntaxe

c
void Wire3DCGB_DrawMaskedModel2D(const Wire3DCGB_Model* model, const w3dcgb_i8* vertex_x, const w3dcgb_i8* vertex_y, const w3dcgb_u8* edge_mask, w3dcgb_u8 x, w3dcgb_u8 y, w3dcgb_u8 color);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

vertex_x

Tableau des décalages X des sommets préprojetés.

vertex_y

Tableau des décalages Y des sommets préprojetés.

edge_mask

Tableau d’octets avec un bit de visibilité par arête, bit de poids faible en premier.

x

Coordonnée X du centre en pixels du viewport.

y

Coordonnée Y du centre en pixels du viewport.

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Trace les arêtes activées du modèle à partir de décalages préprojetés sur octets signés autour de (x,y). Les bits du masque commencent par le moins significatif, huit arêtes par octet. Tous les pointeurs et indices doivent être valides ; edge_mask[0] est lu même pour zéro arête. Aucun compteur n’est plafonné. Les extrémités translatées doivent rester dans le viewport avant conversion en octets ; les valeurs négatives boucleraient. Préserve la couleur précédente et choisit le chemin selon le mode actif.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Preprojected edge arrays, a clipped square, a tiny marker and a projectile.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Edge edges[4]={{0,1},{1,2},{2,3},{3,0}};
__prg_rom s8 vx8[4]={-8,8,8,-8};
__prg_rom s8 vy8[4]={-8,-8,8,8};
__prg_rom s16 vx16[4]={-12,12,12,-12};
__prg_rom s16 vy16[4]={-8,-8,8,8};
__prg_rom u8 mask[1]={5};
Wire3DCGB_Model shape;
void main() {
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    shape.vertices=0;shape.edges=edges;shape.faces=0;shape.edge_faces=0;
    shape.vertex_count=4;shape.edge_count=4;shape.face_count=0;shape.flags=0;
    Wire3DCGB_SetLineColor(2);
    Wire3DCGB_DrawMaskedModel2D(&shape,vx8,vy8,mask,24,24,1);
    Wire3DCGB_DrawEdgeList2D(edges,4,vx8,vy8,64,24,2);
    Wire3DCGB_DrawEdgeListClipped2D(edges,4,vx16,vy16,4,4,64,3);
    Wire3DCGB_DrawTinyModel2D(104,24,16,3);
    result[0]=Wire3DCGB_ProjectAxis48(48,96);
    result[1]=Wire3DCGB_ProjectAxis48(-48,96);
    Wire3DCGB_DrawFastProjectile(96,64,64,0,1);
    result[2]=Wire3DCGB_GetLineColor();
    Wire3DCGB_EndFrame();result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Deux arêtes horizontales rouges, un carré bleu, un cadre vert découpé, un repère vert de six pixels et un projectile rouge permettent de comparer les formats de listes.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_lists.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_lists.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:179

kitaqgb/lib/wire3d_cgb.c:8392

c
void Wire3DCGB_DrawMaskedModel2D(const Wire3DCGB_Model* model,
                                 const w3dcgb_i8* vertex_x, const w3dcgb_i8* vertex_y,
                                 const w3dcgb_u8* edge_mask,
                                 w3dcgb_u8 x, w3dcgb_u8 y, w3dcgb_u8 color)
{
    w3dcgb_u8 i;
    w3dcgb_u8 bit;
    w3dcgb_u8 mask_index;
    w3dcgb_u8 mask;
    w3dcgb_u8 a;
    w3dcgb_u8 b;
    w3dcgb_u8 old_color;

    old_color = w3dcgb_line_color;
    w3dcgb_line_color = (w3dcgb_u8)(color & 3);
    i = 0;
    bit = 1;
    mask_index = 0;
    mask = edge_mask[0];
    while (i < model->edge_count)
    {
        if ((mask & bit) != 0)
        {
            a = model->edges[(__safe_index w3dcgb_u8)i].a;
            b = model->edges[(__safe_index w3dcgb_u8)i].b;
            w3dcgb_line_x0 = (w3dcgb_u8)((w3dcgb_i16)x + (w3dcgb_i16)vertex_x[(__safe_index w3dcgb_u8)a]);
            w3dcgb_line_y0 = (w3dcgb_u8)((w3dcgb_i16)y + (w3dcgb_i16)vertex_y[(__safe_index w3dcgb_u8)a]);
            w3dcgb_line_x1 = (w3dcgb_u8)((w3dcgb_i16)x + (w3dcgb_i16)vertex_x[(__safe_index w3dcgb_u8)b]);
            w3dcgb_line_y1 = (w3dcgb_u8)((w3dcgb_i16)y + (w3dcgb_i16)vertex_y[(__safe_index w3dcgb_u8)b]);
            if (w3dcgb_full_mode != 0) w3dcgb_full_line_fast_asm();
            else w3dcgb_line_stage_asm();
        }
        i = (w3dcgb_u8)(i + 1);
        bit = (w3dcgb_u8)(bit << 1);
        if ((bit == 0) && (i < model->edge_count))
        {
            bit = 1;
            mask_index = (w3dcgb_u8)(mask_index + 1);
            mask = edge_mask[(__safe_index w3dcgb_u8)mask_index];
        }
    }
    w3dcgb_line_color = old_color;
}
Wire3DCGB_DrawModel

Dessine un modèle 3D à la position et avec la rotation fournies, à l’échelle unitaire.

Syntaxe

c
void Wire3DCGB_DrawModel(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Dessine un modèle à l’échelle Q8 unitaire (256), selon le contrat de DrawModelScaled.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Four cubes compare unity/half scale and persistent/temporary line colors.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Vec3 vertices[8]={
    {-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},
    {-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}
};
__prg_rom Wire3DCGB_Edge edges[12]={
    {0,1},{1,2},{2,3},{3,0},{4,5},{5,6},
    {6,7},{7,4},{0,4},{1,5},{2,6},{3,7}
};
Wire3DCGB_Model cube;
u8 sx;
u8 sy;
void main() {
    wire_results_clear();
    cube.vertices=vertices; cube.edges=edges;
    cube.faces=0; cube.edge_faces=0;
    cube.vertex_count=8; cube.edge_count=12; cube.face_count=0; cube.flags=0;
    Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DCGB_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    Wire3DCGB_DrawModelColor(&cube,-32,-32,96,0,0,0,2);
    Wire3DCGB_DrawModelScaledColor(&cube,32,-32,96,0,0,0,128,3);
    result[0]=Wire3DCGB_GetLineColor();
    Wire3DCGB_DrawLine3D(0,56,96,0,-56,96);
    Wire3DCGB_DrawLine3DColor(-80,0,96,80,0,96,3);
    result[1]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[2]=sx; result[3]=sy;
    // Camera setters affect future projection, leaving the staged cubes intact.
    Wire3DCGB_SetCamera(0,0,0,0,4,0);
    result[4]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[5]=Wire3DCGB_ProjectPointNoRotation(0,0,96,&sx,&sy);
    result[6]=sx;
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Compare les modèles à l’échelle unitaire et redimensionnés en rouge, bleu et vert, ainsi que des lignes 3D qui se croisent. Les valeurs en RAM vérifient aussi la projection de caméra et sa variante sans rotation.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_models.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:128

kitaqgb/lib/wire3d_cgb.c:9015

c
void Wire3DCGB_DrawModel(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz)
{
    Wire3DCGB_DrawModelScaled(model, x, y, z, rx, ry, rz, 256);
}
Wire3DCGB_DrawModelColor

Dessine un modèle à l’échelle unitaire dans une couleur temporaire.

Syntaxe

c
void Wire3DCGB_DrawModelColor(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz, w3dcgb_u8 color);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Dessine un modèle à l’échelle Q8 unitaire avec une couleur temporaire, puis rétablit la couleur d’entrée.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Four cubes compare unity/half scale and persistent/temporary line colors.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Vec3 vertices[8]={
    {-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},
    {-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}
};
__prg_rom Wire3DCGB_Edge edges[12]={
    {0,1},{1,2},{2,3},{3,0},{4,5},{5,6},
    {6,7},{7,4},{0,4},{1,5},{2,6},{3,7}
};
Wire3DCGB_Model cube;
u8 sx;
u8 sy;
void main() {
    wire_results_clear();
    cube.vertices=vertices; cube.edges=edges;
    cube.faces=0; cube.edge_faces=0;
    cube.vertex_count=8; cube.edge_count=12; cube.face_count=0; cube.flags=0;
    Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DCGB_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    Wire3DCGB_DrawModelColor(&cube,-32,-32,96,0,0,0,2);
    Wire3DCGB_DrawModelScaledColor(&cube,32,-32,96,0,0,0,128,3);
    result[0]=Wire3DCGB_GetLineColor();
    Wire3DCGB_DrawLine3D(0,56,96,0,-56,96);
    Wire3DCGB_DrawLine3DColor(-80,0,96,80,0,96,3);
    result[1]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[2]=sx; result[3]=sy;
    // Camera setters affect future projection, leaving the staged cubes intact.
    Wire3DCGB_SetCamera(0,0,0,0,4,0);
    result[4]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[5]=Wire3DCGB_ProjectPointNoRotation(0,0,96,&sx,&sy);
    result[6]=sx;
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Compare les modèles à l’échelle unitaire et redimensionnés en rouge, bleu et vert, ainsi que des lignes 3D qui se croisent. Les valeurs en RAM vérifient aussi la projection de caméra et sa variante sans rotation.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_models.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:130

kitaqgb/lib/wire3d_cgb.c:9021

c
void Wire3DCGB_DrawModelColor(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz, w3dcgb_u8 color)
{
    Wire3DCGB_DrawModelScaledColor(model, x, y, z, rx, ry, rz, 256, color);
}
Wire3DCGB_DrawModelScaled

Redimensionne, tourne et projette un modèle, puis trace les arêtes sélectionnées dans la couleur courante.

Syntaxe

c
void Wire3DCGB_DrawModelScaled(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz, w3dcgb_i16 scale_q8);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

scale_q8

Échelle dont l’unité vaut 256 ; les valeurs nulles ou négatives signifient aussi l’unité.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Projette au plus 24 sommets avec une échelle Q8 positive ; une échelle nulle ou négative vaut l’unité. Évite la multiplication à l’unité et les rotations d’angle nul. Les intermédiaires doivent tenir dans s16. Si le filtrage par adjacence est disponible, construit jusqu’à 16 indicateurs de face avant, puis trace les arêtes dont la profondeur et les indices de sommets sont valides. Le nombre d’arêtes n’est pas plafonné à 64. Aucun découpage au plan proche n’est effectué. Remplace le cache de projection partagé et combine par OR les couleurs de ligne dans la zone normale de 128×96. Ce chemin ne marque pas les limites partielles ; prévoyez un transfert complet ou invalidez explicitement l’historique avant un transfert partiel.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Four cubes compare unity/half scale and persistent/temporary line colors.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Vec3 vertices[8]={
    {-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},
    {-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}
};
__prg_rom Wire3DCGB_Edge edges[12]={
    {0,1},{1,2},{2,3},{3,0},{4,5},{5,6},
    {6,7},{7,4},{0,4},{1,5},{2,6},{3,7}
};
Wire3DCGB_Model cube;
u8 sx;
u8 sy;
void main() {
    wire_results_clear();
    cube.vertices=vertices; cube.edges=edges;
    cube.faces=0; cube.edge_faces=0;
    cube.vertex_count=8; cube.edge_count=12; cube.face_count=0; cube.flags=0;
    Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DCGB_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    Wire3DCGB_DrawModelColor(&cube,-32,-32,96,0,0,0,2);
    Wire3DCGB_DrawModelScaledColor(&cube,32,-32,96,0,0,0,128,3);
    result[0]=Wire3DCGB_GetLineColor();
    Wire3DCGB_DrawLine3D(0,56,96,0,-56,96);
    Wire3DCGB_DrawLine3DColor(-80,0,96,80,0,96,3);
    result[1]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[2]=sx; result[3]=sy;
    // Camera setters affect future projection, leaving the staged cubes intact.
    Wire3DCGB_SetCamera(0,0,0,0,4,0);
    result[4]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[5]=Wire3DCGB_ProjectPointNoRotation(0,0,96,&sx,&sy);
    result[6]=sx;
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Compare les modèles à l’échelle unitaire et redimensionnés en rouge, bleu et vert, ainsi que des lignes 3D qui se croisent. Les valeurs en RAM vérifient aussi la projection de caméra et sa variante sans rotation.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_models.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:129

kitaqgb/lib/wire3d_cgb.c:9396

c
void Wire3DCGB_DrawModelScaled(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz, w3dcgb_i16 scale_q8)
{
    w3dcgb_u8 i;
    w3dcgb_u8 count;
    w3dcgb_u8 edge_count;
    w3dcgb_u8 face_count;
    w3dcgb_u8 camera_unrotated;
    w3dcgb_u8 unit_scale;

    if (model == 0) return;
    if (model->vertices == 0) return;
    if (model->edges == 0) return;
    if (scale_q8 <= 0) scale_q8 = 256;

    count = model->vertex_count;
    if (count > WIRE3DCGB_MODEL_VERTEX_LIMIT) count = WIRE3DCGB_MODEL_VERTEX_LIMIT;
    unit_scale = 0;
    if (scale_q8 == 256) unit_scale = 1;
    camera_unrotated = 0;
    if ((w3dcgb_cam_yaw == 0) && (w3dcgb_cam_pitch == 0) && (w3dcgb_cam_roll == 0))
    {
        camera_unrotated = 1;
    }

    i = 0;
    while (i < count)
    {
        const Wire3DCGB_Vec3* v;
        w3dcgb_i16 vx;
        w3dcgb_i16 vy;
        w3dcgb_i16 vz;
        w3dcgb_u8 sx;
        w3dcgb_u8 sy;
        w3dcgb_u8 projected;

        v = &model->vertices[(__safe_index w3dcgb_u8)i];
        if (unit_scale != 0)
        {
            vx = v->x;
            vy = v->y;
            vz = v->z;
        }
        else
        {
            vx = (w3dcgb_i16)((v->x * scale_q8) >> 8);
            vy = (w3dcgb_i16)((v->y * scale_q8) >> 8);
            vz = (w3dcgb_i16)((v->z * scale_q8) >> 8);
        }

        if (ry != 0) w3dcgb_rotate_y(&vx, &vz, (w3dcgb_i8)ry);
        if (rx != 0) w3dcgb_rotate_x(&vy, &vz, (w3dcgb_i8)rx);
        if (rz != 0) w3dcgb_rotate_z(&vx, &vy, (w3dcgb_i8)rz);

        vx = (w3dcgb_i16)(vx + x);
        vy = (w3dcgb_i16)(vy + y);
        vz = (w3dcgb_i16)(vz + z);

        if (camera_unrotated != 0)
        {
            vx = (w3dcgb_i16)(vx - w3dcgb_cam_x);
            vy = (w3dcgb_i16)(vy - w3dcgb_cam_y);
            vz = (w3dcgb_i16)(vz - w3dcgb_cam_z);
            projected = w3dcgb_project_camera_space(vx, vy, vz, &sx, &sy);
        }
        else
        {
            projected = w3dcgb_project_world(vx, vy, vz, &sx, &sy);
        }

        if (projected != 0)
        {
            w3dcgb_screen_x[(__safe_index w3dcgb_u8)i] = sx;
            w3dcgb_screen_y[(__safe_index w3dcgb_u8)i] = sy;
            w3dcgb_screen_visible[(__safe_index w3dcgb_u8)i] = 1;
        }
        else
        {
            w3dcgb_screen_visible[(__safe_index w3dcgb_u8)i] = 0;
        }
        i = (w3dcgb_u8)(i + 1);
    }

    face_count = model->face_count;
    if (face_count > WIRE3DCGB_MODEL_FACE_LIMIT) face_count = WIRE3DCGB_MODEL_FACE_LIMIT;
    if ((model->flags & WIRE3DCGB_MODEL_HIDDEN_LINES) && (model->faces != 0) && (model->edge_faces != 0))
    {
        w3dcgb_build_face_visibility(model, count, face_count);
    }

    edge_count = model->edge_count;
    i = 0;
    while (i < edge_count)
    {
        const Wire3DCGB_Edge* e;
        e = &model->edges[(__safe_index w3dcgb_u8)i];
        if ((e->a < count) && (e->b < count))
        {
            if (w3dcgb_screen_visible[(__safe_index w3dcgb_u8)e->a] &&
                w3dcgb_screen_visible[(__safe_index w3dcgb_u8)e->b] &&
                w3dcgb_is_edge_visible(model, i, face_count))
            {
                w3dcgb_draw_model_line(
                    w3dcgb_screen_x[(__safe_index w3dcgb_u8)e->a],
                    w3dcgb_screen_y[(__safe_index w3dcgb_u8)e->a],
                    w3dcgb_screen_x[(__safe_index w3dcgb_u8)e->b],
                    w3dcgb_screen_y[(__safe_index w3dcgb_u8)e->b]);
            }
        }
        i = (w3dcgb_u8)(i + 1);
    }
}
Wire3DCGB_DrawModelScaledColor

Dessine un modèle avec l’échelle choisie et une couleur de ligne temporaire.

Syntaxe

c
void Wire3DCGB_DrawModelScaledColor(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz, w3dcgb_i16 scale_q8, w3dcgb_u8 color);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

scale_q8

Échelle dont l’unité vaut 256 ; les valeurs nulles ou négatives signifient aussi l’unité.

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Sélectionne color & 3 pour l’appel à DrawModelScaled, puis rétablit la couleur d’entrée.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Four cubes compare unity/half scale and persistent/temporary line colors.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Vec3 vertices[8]={
    {-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},
    {-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}
};
__prg_rom Wire3DCGB_Edge edges[12]={
    {0,1},{1,2},{2,3},{3,0},{4,5},{5,6},
    {6,7},{7,4},{0,4},{1,5},{2,6},{3,7}
};
Wire3DCGB_Model cube;
u8 sx;
u8 sy;
void main() {
    wire_results_clear();
    cube.vertices=vertices; cube.edges=edges;
    cube.faces=0; cube.edge_faces=0;
    cube.vertex_count=8; cube.edge_count=12; cube.face_count=0; cube.flags=0;
    Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DCGB_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    Wire3DCGB_DrawModelColor(&cube,-32,-32,96,0,0,0,2);
    Wire3DCGB_DrawModelScaledColor(&cube,32,-32,96,0,0,0,128,3);
    result[0]=Wire3DCGB_GetLineColor();
    Wire3DCGB_DrawLine3D(0,56,96,0,-56,96);
    Wire3DCGB_DrawLine3DColor(-80,0,96,80,0,96,3);
    result[1]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[2]=sx; result[3]=sy;
    // Camera setters affect future projection, leaving the staged cubes intact.
    Wire3DCGB_SetCamera(0,0,0,0,4,0);
    result[4]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[5]=Wire3DCGB_ProjectPointNoRotation(0,0,96,&sx,&sy);
    result[6]=sx;
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Compare les modèles à l’échelle unitaire et redimensionnés en rouge, bleu et vert, ainsi que des lignes 3D qui se croisent. Les valeurs en RAM vérifient aussi la projection de caméra et sa variante sans rotation.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_models.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:131

kitaqgb/lib/wire3d_cgb.c:9510

c
void Wire3DCGB_DrawModelScaledColor(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz, w3dcgb_i16 scale_q8, w3dcgb_u8 color)
{
    w3dcgb_u8 old_color;
    old_color = w3dcgb_line_color;
    Wire3DCGB_SetLineColor(color);
    Wire3DCGB_DrawModelScaled(model, x, y, z, rx, ry, rz, scale_q8);
    w3dcgb_line_color = old_color;
}
Wire3DCGB_DrawPoint2D

Écrit un pixel dans la couleur courante.

Syntaxe

c
void Wire3DCGB_DrawPoint2D(w3dcgb_u8 x, w3dcgb_u8 y);

Paramètres

x

Coordonnée X du centre en pixels du viewport.

y

Coordonnée Y du centre en pixels du viewport.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

En mode normal, rejette les coordonnées hors de 128×96, marque les limites partielles et remplace le pixel préparé par la couleur courante, zéro compris. En plein écran, trace à la place une ligne rapide aux extrémités confondues : zéro signifie alors couleur 3 et les coordonnées invalides activent l’indicateur de débordement de l’image. Le transfert vers l’écran a lieu plus tard.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:174

kitaqgb/lib/wire3d_cgb.c:8283

c
void Wire3DCGB_DrawPoint2D(w3dcgb_u8 x, w3dcgb_u8 y)
{
    w3dcgb_u8 tile;
    if (w3dcgb_full_mode != 0)
    {
        w3dcgb_line_x0 = x;
        w3dcgb_line_y0 = y;
        w3dcgb_line_x1 = x;
        w3dcgb_line_y1 = y;
        w3dcgb_full_line_fast_asm();
        return;
    }
    if (x >= WIRE3DCGB_SCREEN_W) return;
    if (y >= WIRE3DCGB_SCREEN_H) return;
    if (w3dcgb_full_frame_transfer == 0)
    {
        tile = (w3dcgb_u8)(((x >> 3) * W3DCGB_TILE_H) + (y >> 3));
        if (tile < w3dcgb_dirty_min_tile) w3dcgb_dirty_min_tile = tile;
        if (tile > w3dcgb_dirty_max_tile) w3dcgb_dirty_max_tile = tile;
    }
    w3dcgb_plot_x = x;
    w3dcgb_plot_y = y;
    w3dcgb_plot_stage_asm();
}
Wire3DCGB_DrawScene

Dessine au plus huit objets du plus proche au plus lointain, les faces précédentes masquant les lignes suivantes.

Syntaxe

c
void Wire3DCGB_DrawScene(Wire3DCGB_Object* objects, w3dcgb_u8 count);

Paramètres

objects

Tableau d’objets contenant positions, rotations, échelles et indicateurs de visibilité.

count

Nombre d’entrées fournies ; consultez la limite de traitement propre à l’opération.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Trie au plus huit objets du plus proche au plus lointain selon la profondeur de leur origine dans l’espace caméra, sans modifier le tableau de l’appelant. Efface le masque, dessine les modèles visibles en tenant compte des zones déjà couvertes, puis ajoute leurs faces comme occultants. Les tableaux des modèles et les indices de faces doivent être valides. La couleur zéro hérite de la couleur courante, éventuellement celle de l’objet précédent. Restaure la couleur d’entrée et désactive l’occlusion à la fin. Ce chemin vise la zone normale de 128×96.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// A near square hides the middle of a farther blue line, regardless of array order.
#include "wire_cgb_example.h"
#include "wire_cgb_plane.h"
__prg_rom Wire3DCGB_Vec3 back_vertices[2]={{-96,0,0},{96,0,0}};
__prg_rom Wire3DCGB_Edge back_edges[1]={{0,1}};
Wire3DCGB_Model back;
Wire3DCGB_Object objects[2];
void main() {
    u8 i;
    wire_results_clear();wire_plane_setup();
    back.vertices=back_vertices;back.edges=back_edges;back.faces=0;back.edge_faces=0;
    back.vertex_count=2;back.edge_count=1;back.face_count=0;back.flags=0;
    for(i=0;i<2;i++) {
        objects[i].x=0;objects[i].y=0;objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256;objects[i].visible=1;
    }
    objects[0].model=&back;objects[0].z=128;objects[0].color=2;
    objects[1].model=&plane;objects[1].z=64;objects[1].color=1;
    Wire3DCGB_Init();wire_colors();Wire3DCGB_BeginFrame();Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawScene(objects,2);
    result[0]=objects[0].z;result[1]=objects[1].z;result[2]=Wire3DCGB_GetLineColor();
    Wire3DCGB_EndFrame();result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Un carré rouge proche, de (46,30) à (82,66), masque le milieu d’une ligne horizontale bleue plus lointaine ; seuls ses segments gauche et droit restent visibles.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_scene.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_scene.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:155

kitaqgb/lib/wire3d_cgb.c:8918

c
void Wire3DCGB_DrawScene(Wire3DCGB_Object* objects, w3dcgb_u8 count)
{
    w3dcgb_u8 scene_count;
    w3dcgb_u8 i;
    w3dcgb_u8 old_color;

    if (objects == 0) return;

    scene_count = count;
    if (scene_count > WIRE3DCGB_SCENE_OBJECT_LIMIT) scene_count = WIRE3DCGB_SCENE_OBJECT_LIMIT;

    i = 0;
    while (i < scene_count)
    {
        w3dcgb_scene_order[(__safe_index w3dcgb_u8)i] = i;
        w3dcgb_scene_depth[(__safe_index w3dcgb_u8)i] = w3dcgb_scene_object_depth(&objects[(__safe_index w3dcgb_u8)i]);
        i = (w3dcgb_u8)(i + 1);
    }

    i = 0;
    while (i < scene_count)
    {
        w3dcgb_u8 j;
        j = (w3dcgb_u8)(i + 1);
        while (j < scene_count)
        {
            w3dcgb_u8 oi;
            w3dcgb_u8 oj;
            oi = w3dcgb_scene_order[(__safe_index w3dcgb_u8)i];
            oj = w3dcgb_scene_order[(__safe_index w3dcgb_u8)j];

            if (w3dcgb_scene_depth[(__safe_index w3dcgb_u8)oj] < w3dcgb_scene_depth[(__safe_index w3dcgb_u8)oi])
            {
                w3dcgb_scene_order[(__safe_index w3dcgb_u8)i] = oj;
                w3dcgb_scene_order[(__safe_index w3dcgb_u8)j] = oi;
            }
            j = (w3dcgb_u8)(j + 1);
        }
        i = (w3dcgb_u8)(i + 1);
    }

    old_color = w3dcgb_line_color;
    w3dcgb_clear_occlusion_mask();
    w3dcgb_occlusion_active = 0;

    i = 0;
    while (i < scene_count)
    {
        Wire3DCGB_Object* obj;
        obj = &objects[(__safe_index w3dcgb_u8)w3dcgb_scene_order[(__safe_index w3dcgb_u8)i]];
        if ((obj->visible != 0) && (obj->model != 0))
        {
            if (i == 0) w3dcgb_occlusion_active = 0;
            else w3dcgb_occlusion_active = 1;
            if (obj->color != 0) Wire3DCGB_SetLineColor(obj->color);
            Wire3DCGB_DrawModelScaled(obj->model, obj->x, obj->y, obj->z, (w3dcgb_i8)obj->rx, (w3dcgb_i8)obj->ry, (w3dcgb_i8)obj->rz, obj->scale_q8);
            w3dcgb_occlusion_active = 0;
            w3dcgb_mark_model_occluder(obj->model);
        }
        i = (w3dcgb_u8)(i + 1);
    }

    w3dcgb_occlusion_active = 0;
    w3dcgb_line_color = old_color;
}
Wire3DCGB_DrawTinyModel2D

Dessine un repère de six pixels dont l’avant et l’arrière indiquent la direction.

Syntaxe

c
void Wire3DCGB_DrawTinyModel2D(w3dcgb_u8 x, w3dcgb_u8 y, w3dcgb_u8 turn, w3dcgb_u8 color);

Paramètres

x

Coordonnée X du centre en pixels du viewport.

y

Coordonnée Y du centre en pixels du viewport.

turn

Valeur dont les cinq bits faibles choisissent la direction du petit repère.

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Dessine un repère de six pixels via le traceur de points de 128×96, en préservant la couleur de ligne. Ignore les centres hors de X=3..124 ou Y=3..92. Les cinq bits faibles de turn choisissent les décalages avant et arrière pour gauche/tout droit/droite. Ce n’est pas une transformation 3D générale et cela n’utilise pas le moteur plein écran.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Preprojected edge arrays, a clipped square, a tiny marker and a projectile.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Edge edges[4]={{0,1},{1,2},{2,3},{3,0}};
__prg_rom s8 vx8[4]={-8,8,8,-8};
__prg_rom s8 vy8[4]={-8,-8,8,8};
__prg_rom s16 vx16[4]={-12,12,12,-12};
__prg_rom s16 vy16[4]={-8,-8,8,8};
__prg_rom u8 mask[1]={5};
Wire3DCGB_Model shape;
void main() {
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    shape.vertices=0;shape.edges=edges;shape.faces=0;shape.edge_faces=0;
    shape.vertex_count=4;shape.edge_count=4;shape.face_count=0;shape.flags=0;
    Wire3DCGB_SetLineColor(2);
    Wire3DCGB_DrawMaskedModel2D(&shape,vx8,vy8,mask,24,24,1);
    Wire3DCGB_DrawEdgeList2D(edges,4,vx8,vy8,64,24,2);
    Wire3DCGB_DrawEdgeListClipped2D(edges,4,vx16,vy16,4,4,64,3);
    Wire3DCGB_DrawTinyModel2D(104,24,16,3);
    result[0]=Wire3DCGB_ProjectAxis48(48,96);
    result[1]=Wire3DCGB_ProjectAxis48(-48,96);
    Wire3DCGB_DrawFastProjectile(96,64,64,0,1);
    result[2]=Wire3DCGB_GetLineColor();
    Wire3DCGB_EndFrame();result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Deux arêtes horizontales rouges, un carré bleu, un cadre vert découpé, un repère vert de six pixels et un projectile rouge permettent de comparer les formats de listes.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_lists.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_lists.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:175

kitaqgb/lib/wire3d_cgb.c:8313

c
void Wire3DCGB_DrawTinyModel2D(w3dcgb_u8 x, w3dcgb_u8 y,
                               w3dcgb_u8 turn, w3dcgb_u8 color)
{
    w3dcgb_u8 nose_x;
    w3dcgb_u8 tail_x;
    w3dcgb_u8 old_color;
    if ((x < 3) || (x > 124) || (y < 3) || (y > (w3dcgb_u8)(WIRE3DCGB_SCREEN_H - 4))) return;

    nose_x = x;
    tail_x = x;
    turn = (w3dcgb_u8)(turn & 31);
    if (turn < 12)
    {
        nose_x = (w3dcgb_u8)(x + 1);
        tail_x = (w3dcgb_u8)(x - 1);
    }
    else if (turn >= 20)
    {
        nose_x = (w3dcgb_u8)(x - 1);
        tail_x = (w3dcgb_u8)(x + 1);
    }

    old_color = w3dcgb_line_color;
    w3dcgb_line_color = (w3dcgb_u8)(color & 3);
    w3dcgb_plot_x = nose_x;
    w3dcgb_plot_y = (w3dcgb_u8)(y - 2);
    w3dcgb_plot_stage_asm();
    w3dcgb_plot_x = x;
    w3dcgb_plot_y = (w3dcgb_u8)(y - 1);
    w3dcgb_plot_stage_asm();
    w3dcgb_plot_x = (w3dcgb_u8)(x - 2);
    w3dcgb_plot_y = (w3dcgb_u8)(y + 1);
    w3dcgb_plot_stage_asm();
    w3dcgb_plot_x = (w3dcgb_u8)(x + 2);
    w3dcgb_plot_stage_asm();
    w3dcgb_plot_x = x;
    w3dcgb_plot_y = y;
    w3dcgb_plot_stage_asm();
    w3dcgb_plot_x = tail_x;
    w3dcgb_plot_y = (w3dcgb_u8)(y + 2);
    w3dcgb_plot_stage_asm();
    w3dcgb_line_color = old_color;
}
Wire3DCGB_DrawWhiteBorderFast

Trace un bord d’un pixel d’indice de couleur 2 autour de la zone de préparation de 128×96.

Syntaxe

c
void Wire3DCGB_DrawWhiteBorderFast();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Trace un bord d’un pixel en couleur 2 autour de la zone de préparation normale, en préservant les pixels intérieurs et la sélection de banque WRAM. La couleur visible dépend de la palette. Aucune plage modifiée n’est marquée ; les appels à transfert partiel doivent prévoir son transfert.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// A cleared 24-pixel strip and a palette-index-2 border have distinct purposes.
#include "wire_cgb_example.h"
void main() {
    u8 y;
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    for(y=0;y<96;y++) Wire3DCGB_DrawLine2D(0,y,31,y);
    Wire3DCGB_EraseLeftGuard24Fast();
    // With this example's palette, color index 2 is blue rather than white.
    Wire3DCGB_DrawWhiteBorderFast();
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Les 24 colonnes de gauche sont effacées, une bande rouge subsiste et le bord extérieur d’indice de couleur 2 est bleu.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_guard.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_guard.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:147

kitaqgb/lib/wire3d_cgb.c:9369

c
void Wire3DCGB_DrawWhiteBorderFast()
{
    w3dcgb_draw_white_border_asm();
}
Wire3DCGB_EnableAtomicMaps

Configure la présentation en 128×96 pour alterner entre deux cartes du fond.

Syntaxe

c
void Wire3DCGB_EnableAtomicMaps();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Au démarrage seulement : réserve les deux cartes BG et réplique les tuiles HUD mises en file. Active une seule fois l’alternance des cartes pendant le démarrage en 128×96 ; ignore le plein écran ou un réglage déjà actif. Si le LCD est allumé, attend le VBlank, l’éteint, copie les deux banques de 9800 vers 9C00 et affecte aux attributs des viewports les banques de tuiles 0/1 respectivement. Restaure LCDC avec la carte 9C00 sélectionnée et VBK à zéro. Les deux cartes BG sont réservées ; les numéros de tuiles HUD en file sont répliqués.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Reuse both VRAM banks and remove old geometry while presenting sparse frames.
#include "wire_cgb_example.h"
void main() {
    wire_results_clear(); Wire3DCGB_Init();
    Wire3DCGB_ClearFrameTiles();
    Wire3DCGB_EnableAtomicMaps(); wire_colors();
    // First frame: red on the left. Fast begin invalidates both bank histories.
    Wire3DCGB_BeginFrameFast(); wire_frame(8,8,32,32,1);
    Wire3DCGB_EndFrameFast();
    // Second frame: blue in the middle, with the old red frame removed.
    Wire3DCGB_BeginFrameSparse(); wire_frame(40,40,64,64,2);
    Wire3DCGB_EndFrameSparse();
    // Third frame: explicitly clearing a stage discards its first green point.
    Wire3DCGB_BeginFrameSparse();
    Wire3DCGB_SetLineColor(3); Wire3DCGB_DrawPoint2D(4,4);
    Wire3DCGB_ClearSparseStageFast();
    // The final image contains only this green frame on the right.
    wire_frame(80,8,112,32,3);
    Wire3DCGB_MarkDirtyRect2D(80,8,112,32);
    Wire3DCGB_InvalidateFrameHistory();
    Wire3DCGB_EndFrameSparseNow();
    result[0]=Wire3DCGB_GetLineColor();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Les cadres rouge et bleu dessinés précédemment disparaissent ; seul reste le cadre vert final de (80,8) à (112,32), ce qui illustre le transfert partiel et la gestion de l’historique.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_sparse.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_sparse.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:144

Notes de déclaration (texte source)
Startup-only: reserves both BG maps; queued HUD tiles are mirrored.

kitaqgb/lib/wire3d_cgb.c:7912

c
void Wire3DCGB_EnableAtomicMaps()
{
    if ((w3dcgb_full_mode != 0) || (w3dcgb_atomic_maps != 0)) return;
    __asm {
w3dam_wait:
        LDH_A_MEM 68
        CP_IMM 144
        JR_C w3dam_wait
        LDH_A_MEM 64
        PUSH_AF
        XOR_A
        LDH_MEM_A 64
        LDH_MEM_A 79
        LD_HL_IMM 0x9800
        LD_DE_IMM 0x9C00
        LD_B_IMM 4
w3dam_copy_page:
        LD_C_IMM 0
w3dam_copy_byte:
        LD_A_HL
        INC_HL
        LD_DE_A
        INC_DE
        DEC_C
        JR_NZ w3dam_copy_byte
        DEC_B
        JR_NZ w3dam_copy_page
        LDH_A_MEM 79
        AND_IMM 1
        JR_NZ w3dam_attrs
        LD_A_IMM 1
        LDH_MEM_A 79
        LD_HL_IMM 0x9800
        LD_DE_IMM 0x9C00
        LD_B_IMM 4
        JR w3dam_copy_page
w3dam_attrs:
        LD_HL_IMM 0x9800
        LD_DE_IMM 0x9C00
        LD_B_IMM 12
w3dam_row:
        LD_C_IMM 16
w3dam_cell:
        XOR_A
        LDI_HL_A
        LD_A_IMM 8
        LD_DE_A
        INC_DE
        DEC_C
        JR_NZ w3dam_cell
        LD_A_L
        ADD_A_IMM 16
        LD_L_A
        JR_NC w3dam_hl_ready
        INC_H
w3dam_hl_ready:
        LD_A_E
        ADD_A_IMM 16
        LD_E_A
        JR_NC w3dam_de_ready
        INC_D
w3dam_de_ready:
        DEC_B
        JR_NZ w3dam_row
        LD_A_IMM 1
        LD_MEM_A w3dcgb_atomic_maps
        XOR_A
        LDH_MEM_A 79
        POP_AF
        OR_IMM 8
        LDH_MEM_A 64
        RET
    }
}
Wire3DCGB_EnableDoubleSpeed

Passe le processeur CGB en double vitesse.

Syntaxe

c
void Wire3DCGB_EnableDoubleSpeed();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Sur CGB, retourne immédiatement si KEY1 indique déjà la double vitesse ; sinon, demande le changement de vitesse et appelle l’auxiliaire STOP. Cette API suppose un matériel CGB et ne propose aucun repli pour les modèles monochromes.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:116

kitaqgb/lib/wire3d_cgb.c:1081

c
void Wire3DCGB_EnableDoubleSpeed()
{
    if ((w3dcgb_reg_key1 & 0x80) != 0) return;
    w3dcgb_reg_key1 = 1;
    w3dcgb_cgb_speed_switch_asm();
}
Wire3DCGB_EndFrame

Transfère et affiche l’image terminée.

Syntaxe

c
void Wire3DCGB_EndFrame();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

En mode normal, applique les écritures BG en file, transfère toute la zone de préparation et affiche la banque de tuiles terminée. En plein écran, transfère et affiche les tuiles allouées sans vider la file HUD. Nécessite un LCD activé et le respect des contrats de banques et d’interruptions des auxiliaires de transfert ; peut prendre plusieurs images.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Au démarrage sparse CGB, la première utilisation de chaque banque cible (les deux premières images) actualise tout le viewport et efface les tuiles d’initialisation. Cette charge est incluse dans les mesures. DrawLine2D ne déclare pas de zone sparse : utilisez DrawLineClipped2D ou MarkDirtyRect2D explicitement.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:189

kitaqgb/lib/wire3d_cgb.c:9881

c
void Wire3DCGB_EndFrame()
{
    if (w3dcgb_full_mode != 0)
    {
        w3dcgb_full_transfer_asm();
        w3dcgb_full_present_asm();
        return;
    }
    if (w3dcgb_bgq_count != 0)
    {
        w3dcgb_wait_vblank_start();
        w3dcgb_flush_bg_queue();
    }
    w3dcgb_transfer_stage_asm();
    w3dcgb_present_stage_asm();
}
Wire3DCGB_EndFrameFast

Transfère et affiche une image complète sans appliquer les écritures du fond en attente.

Syntaxe

c
void Wire3DCGB_EndFrameFast();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Transfère et affiche l’image complète du mode choisi sans vider la file BG. Ne consomme pas les écritures HUD en attente. Exige les mêmes conditions LCD, banques et interruptions qu’EndFrame ; runtime complet requis.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Au démarrage sparse CGB, la première utilisation de chaque banque cible (les deux premières images) actualise tout le viewport et efface les tuiles d’initialisation. Cette charge est incluse dans les mesures. DrawLine2D ne déclare pas de zone sparse : utilisez DrawLineClipped2D ou MarkDirtyRect2D explicitement.

Exemple d’utilisation

c
#pragma bank 0
// Reuse both VRAM banks and remove old geometry while presenting sparse frames.
#include "wire_cgb_example.h"
void main() {
    wire_results_clear(); Wire3DCGB_Init();
    Wire3DCGB_ClearFrameTiles();
    Wire3DCGB_EnableAtomicMaps(); wire_colors();
    // First frame: red on the left. Fast begin invalidates both bank histories.
    Wire3DCGB_BeginFrameFast(); wire_frame(8,8,32,32,1);
    Wire3DCGB_EndFrameFast();
    // Second frame: blue in the middle, with the old red frame removed.
    Wire3DCGB_BeginFrameSparse(); wire_frame(40,40,64,64,2);
    Wire3DCGB_EndFrameSparse();
    // Third frame: explicitly clearing a stage discards its first green point.
    Wire3DCGB_BeginFrameSparse();
    Wire3DCGB_SetLineColor(3); Wire3DCGB_DrawPoint2D(4,4);
    Wire3DCGB_ClearSparseStageFast();
    // The final image contains only this green frame on the right.
    wire_frame(80,8,112,32,3);
    Wire3DCGB_MarkDirtyRect2D(80,8,112,32);
    Wire3DCGB_InvalidateFrameHistory();
    Wire3DCGB_EndFrameSparseNow();
    result[0]=Wire3DCGB_GetLineColor();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Les cadres rouge et bleu dessinés précédemment disparaissent ; seul reste le cadre vert final de (80,8) à (112,32), ce qui illustre le transfert partiel et la gestion de l’historique.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_sparse.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_sparse.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:190

kitaqgb/lib/wire3d_cgb.c:9902

c
void Wire3DCGB_EndFrameFast()
{
    if (w3dcgb_full_mode != 0)
    {
        w3dcgb_full_transfer_asm();
        w3dcgb_full_present_asm();
        return;
    }
    w3dcgb_transfer_stage_asm();
    w3dcgb_present_stage_asm();
}
Wire3DCGB_EndFrameSparse

Attend un nouveau VBlank, puis transfère et affiche les plages partielles nécessaires.

Syntaxe

c
void Wire3DCGB_EndFrameSparse();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

En mode normal, attend un nouveau VBlank et appelle EndFrameSparseNow. En plein écran, utilise le transfert et la présentation complets de ce mode. Nécessite le runtime complet et un LCD activé ; l’achèvement en une seule image n’est pas garanti.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Au démarrage sparse CGB, la première utilisation de chaque banque cible (les deux premières images) actualise tout le viewport et efface les tuiles d’initialisation. Cette charge est incluse dans les mesures. DrawLine2D ne déclare pas de zone sparse : utilisez DrawLineClipped2D ou MarkDirtyRect2D explicitement.

Exemple d’utilisation

c
#pragma bank 0
// Reuse both VRAM banks and remove old geometry while presenting sparse frames.
#include "wire_cgb_example.h"
void main() {
    wire_results_clear(); Wire3DCGB_Init();
    Wire3DCGB_ClearFrameTiles();
    Wire3DCGB_EnableAtomicMaps(); wire_colors();
    // First frame: red on the left. Fast begin invalidates both bank histories.
    Wire3DCGB_BeginFrameFast(); wire_frame(8,8,32,32,1);
    Wire3DCGB_EndFrameFast();
    // Second frame: blue in the middle, with the old red frame removed.
    Wire3DCGB_BeginFrameSparse(); wire_frame(40,40,64,64,2);
    Wire3DCGB_EndFrameSparse();
    // Third frame: explicitly clearing a stage discards its first green point.
    Wire3DCGB_BeginFrameSparse();
    Wire3DCGB_SetLineColor(3); Wire3DCGB_DrawPoint2D(4,4);
    Wire3DCGB_ClearSparseStageFast();
    // The final image contains only this green frame on the right.
    wire_frame(80,8,112,32,3);
    Wire3DCGB_MarkDirtyRect2D(80,8,112,32);
    Wire3DCGB_InvalidateFrameHistory();
    Wire3DCGB_EndFrameSparseNow();
    result[0]=Wire3DCGB_GetLineColor();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Les cadres rouge et bleu dessinés précédemment disparaissent ; seul reste le cadre vert final de (80,8) à (112,32), ce qui illustre le transfert partiel et la gestion de l’historique.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_sparse.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_sparse.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:191

kitaqgb/lib/wire3d_cgb.c:9917

c
void Wire3DCGB_EndFrameSparse()
{
    if (w3dcgb_full_mode != 0)
    {
        w3dcgb_full_transfer_asm();
        w3dcgb_full_present_asm();
        return;
    }
    w3dcgb_wait_vblank_start();
    Wire3DCGB_EndFrameSparseNow();
}
Wire3DCGB_EndFrameSparseNow

Soumet les écritures du fond et les plages partielles courantes/N−2 sans attendre initialement un nouveau VBlank.

Syntaxe

c
void Wire3DCGB_EndFrameSparseNow();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Applique les écritures BG en file, transfère la plage partielle de tuiles courante/N−2 dans la banque arrière et l’affiche. Saute l’attente initiale d’un nouveau VBlank, mais le mode de carte normal attend encore lors de la restauration de la tuile HUD vide ; DMA et présentation peuvent aussi attendre. Le mode plein écran du runtime complet utilise son propre chemin. Le LCD doit être activé et SVBK/VBK doivent rester stables pendant le DMA.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Au démarrage sparse CGB, la première utilisation de chaque banque cible (les deux premières images) actualise tout le viewport et efface les tuiles d’initialisation. Cette charge est incluse dans les mesures. DrawLine2D ne déclare pas de zone sparse : utilisez DrawLineClipped2D ou MarkDirtyRect2D explicitement.

Exemple d’utilisation

c
#pragma bank 0
// Reuse both VRAM banks and remove old geometry while presenting sparse frames.
#include "wire_cgb_example.h"
void main() {
    wire_results_clear(); Wire3DCGB_Init();
    Wire3DCGB_ClearFrameTiles();
    Wire3DCGB_EnableAtomicMaps(); wire_colors();
    // First frame: red on the left. Fast begin invalidates both bank histories.
    Wire3DCGB_BeginFrameFast(); wire_frame(8,8,32,32,1);
    Wire3DCGB_EndFrameFast();
    // Second frame: blue in the middle, with the old red frame removed.
    Wire3DCGB_BeginFrameSparse(); wire_frame(40,40,64,64,2);
    Wire3DCGB_EndFrameSparse();
    // Third frame: explicitly clearing a stage discards its first green point.
    Wire3DCGB_BeginFrameSparse();
    Wire3DCGB_SetLineColor(3); Wire3DCGB_DrawPoint2D(4,4);
    Wire3DCGB_ClearSparseStageFast();
    // The final image contains only this green frame on the right.
    wire_frame(80,8,112,32,3);
    Wire3DCGB_MarkDirtyRect2D(80,8,112,32);
    Wire3DCGB_InvalidateFrameHistory();
    Wire3DCGB_EndFrameSparseNow();
    result[0]=Wire3DCGB_GetLineColor();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Les cadres rouge et bleu dessinés précédemment disparaissent ; seul reste le cadre vert final de (80,8) à (112,32), ce qui illustre le transfert partiel et la gestion de l’historique.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_sparse.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_sparse.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:192

kitaqgb/lib/wire3d_cgb.c:9935

c
void Wire3DCGB_EndFrameSparseNow()
{
#ifndef WIRE3DCGB_MINIMAL_RUNTIME
    if (w3dcgb_full_mode != 0)
    {
        w3dcgb_full_transfer_asm();
        w3dcgb_full_present_asm();
        return;
    }
#endif
    /* Atomic mode never writes a displayed tile and does not need a
       frame-long VBlank wait before starting an off-screen upload. */
    if (w3dcgb_atomic_maps == 0) w3dcgb_restore_hud_blank_tile_asm();
    if (w3dcgb_bgq_count != 0) w3dcgb_flush_bg_queue();
    w3dcgb_transfer_dirty_tiles();
    w3dcgb_present_stage_asm();
}
Wire3DCGB_EraseLeftGuard24Fast

Efface les 24 colonnes les plus à gauche de la zone de préparation normale.

Syntaxe

c
void Wire3DCGB_EraseLeftGuard24Fast();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Efface les 24 colonnes les plus à gauche de la zone de préparation par ASM, en préservant la sélection de banque. Aucune plage modifiée n’est marquée ; les appels à transfert partiel doivent inclure les tuiles effacées.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// A cleared 24-pixel strip and a palette-index-2 border have distinct purposes.
#include "wire_cgb_example.h"
void main() {
    u8 y;
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    for(y=0;y<96;y++) Wire3DCGB_DrawLine2D(0,y,31,y);
    Wire3DCGB_EraseLeftGuard24Fast();
    // With this example's palette, color index 2 is blue rather than white.
    Wire3DCGB_DrawWhiteBorderFast();
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Les 24 colonnes de gauche sont effacées, une bande rouge subsiste et le bord extérieur d’indice de couleur 2 est bleu.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_guard.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_guard.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:146

kitaqgb/lib/wire3d_cgb.c:9200

c
void Wire3DCGB_EraseLeftGuard24Fast()
{
    w3dcgb_erase_left_guard24_asm();
}
Wire3DCGB_EraseModelFaces

Efface les pixels préparés à l’intérieur des faces avant projetées du modèle.

Syntaxe

c
void Wire3DCGB_EraseModelFaces(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz, w3dcgb_i16 scale_q8);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

scale_q8

Échelle dont l’unité vaut 256 ; les valeurs nulles ou négatives signifient aussi l’unité.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Pour un modèle à lignes cachées contenant sommets et faces, transforme au plus 24 sommets et efface les triangles orientés vers l’avant parmi au plus 16 faces. Une échelle non positive vaut l’unité ; ce chemin multiplie encore à l’unité et exécute les trois auxiliaires de rotation même pour des angles nuls. Rejette les faces invalides ou échouant au test de profondeur. Remplace le cache de projection partagé et utilise l’effacement normal en C de la zone de préparation : l’appelant ou l’allocation doit assurer le bon mappage WRAM.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Projected model faces erase a square opening; redraw its outline in green.
#include "wire_cgb_example.h"
#include "wire_cgb_plane.h"
void main() {
    u8 y;u8 bank;
    wire_results_clear();wire_plane_setup();Wire3DCGB_Init();wire_colors();Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    for(y=8;y<=88;y++) Wire3DCGB_DrawLine2D(24,y,104,y);
    bank=sample_svbk;sample_svbk=2;
    Wire3DCGB_EraseModelFaces(&plane,0,0,64,0,0,0,256);
    sample_svbk=bank;
    Wire3DCGB_DrawModelColor(&plane,0,0,64,0,0,0,3);
    result[0]=Wire3DCGB_GetLineColor();
    Wire3DCGB_EndFrame();result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_faces.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_faces.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:132

kitaqgb/lib/wire3d_cgb.c:9033

c
void Wire3DCGB_EraseModelFaces(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz, w3dcgb_i16 scale_q8)
{
    w3dcgb_u8 i;
    w3dcgb_u8 count;
    w3dcgb_u8 face_count;

    if (model == 0) return;
    if (model->vertices == 0) return;
    if (model->faces == 0) return;
    if ((model->flags & WIRE3DCGB_MODEL_HIDDEN_LINES) == 0) return;
    if (scale_q8 <= 0) scale_q8 = 256;

    count = model->vertex_count;
    if (count > WIRE3DCGB_MODEL_VERTEX_LIMIT) count = WIRE3DCGB_MODEL_VERTEX_LIMIT;

    i = 0;
    while (i < count)
    {
        const Wire3DCGB_Vec3* v;
        w3dcgb_i16 vx;
        w3dcgb_i16 vy;
        w3dcgb_i16 vz;
        w3dcgb_u8 sx;
        w3dcgb_u8 sy;

        v = &model->vertices[(__safe_index w3dcgb_u8)i];
        vx = (w3dcgb_i16)((v->x * scale_q8) >> 8);
        vy = (w3dcgb_i16)((v->y * scale_q8) >> 8);
        vz = (w3dcgb_i16)((v->z * scale_q8) >> 8);

        w3dcgb_rotate_y(&vx, &vz, (w3dcgb_i8)ry);
        w3dcgb_rotate_x(&vy, &vz, (w3dcgb_i8)rx);
        w3dcgb_rotate_z(&vx, &vy, (w3dcgb_i8)rz);

        vx = (w3dcgb_i16)(vx + x);
        vy = (w3dcgb_i16)(vy + y);
        vz = (w3dcgb_i16)(vz + z);

        if (w3dcgb_project_world(vx, vy, vz, &sx, &sy))
        {
            w3dcgb_screen_x[(__safe_index w3dcgb_u8)i] = sx;
            w3dcgb_screen_y[(__safe_index w3dcgb_u8)i] = sy;
            w3dcgb_screen_visible[(__safe_index w3dcgb_u8)i] = 1;
        }
        else
        {
            w3dcgb_screen_visible[(__safe_index w3dcgb_u8)i] = 0;
        }
        i = (w3dcgb_u8)(i + 1);
    }

    face_count = model->face_count;
    if (face_count > WIRE3DCGB_MODEL_FACE_LIMIT) face_count = WIRE3DCGB_MODEL_FACE_LIMIT;
    w3dcgb_build_face_visibility(model, count, face_count);

    i = 0;
    while (i < face_count)
    {
        const Wire3DCGB_Face* f;
        f = &model->faces[(__safe_index w3dcgb_u8)i];
        if (w3dcgb_face_visible[(__safe_index w3dcgb_u8)i] &&
            w3dcgb_screen_visible[(__safe_index w3dcgb_u8)f->a] &&
            w3dcgb_screen_visible[(__safe_index w3dcgb_u8)f->b] &&
            w3dcgb_screen_visible[(__safe_index w3dcgb_u8)f->c])
        {
            w3dcgb_clear_triangle(
                w3dcgb_screen_x[(__safe_index w3dcgb_u8)f->a],
                w3dcgb_screen_y[(__safe_index w3dcgb_u8)f->a],
                w3dcgb_screen_x[(__safe_index w3dcgb_u8)f->b],
                w3dcgb_screen_y[(__safe_index w3dcgb_u8)f->b],
                w3dcgb_screen_x[(__safe_index w3dcgb_u8)f->c],
                w3dcgb_screen_y[(__safe_index w3dcgb_u8)f->c]);
        }
        i = (w3dcgb_u8)(i + 1);
    }
}
Wire3DCGB_ErasePackedSilhouette2D

Efface une silhouette compactée dans les deux plans de couleur de la zone de préparation normale.

Syntaxe

c
void Wire3DCGB_ErasePackedSilhouette2D(const w3dcgb_u8* profile, w3dcgb_u8 count, w3dcgb_i8 y0, w3dcgb_u8 x, w3dcgb_u8 y);

Paramètres

profile

Tableau de silhouette à un octet par ligne ; 0xFF saute une ligne.

count

Nombre d’entrées fournies ; consultez la limite de traitement propre à l’opération.

y0

Décalage signé du centre Y vers la première ligne de silhouette.

x

Coordonnée X du centre en pixels du viewport.

y

Coordonnée Y du centre en pixels du viewport.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Efface au plus 29 lignes de silhouette compactée dans les deux plans de bits préparés. Format, placement, marge de deux pixels et découpage sont ceux de MarkPackedSilhouette2D ; null est ignoré. L’écriture ASM des segments sélectionne la banque WRAM 2 puis restaure la sélection précédente, mais ne marque pas les tuiles modifiées. En mode partiel, l’appelant doit inclure les tuiles effacées dans la plage à transférer. Cette API vise la zone de préparation de 128×96.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Colored panels expose triangle, span, rectangle and packed-silhouette erasure.
#include "wire_cgb_example.h"
__prg_rom u8 silhouette[5]={0x73,0x74,0xFF,0x75,0x73};
void main() {
    u8 y;
    u8 bank;
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    for(y=8;y<=40;y++) Wire3DCGB_DrawLine2DColor(8,y,40,y,1);
    for(y=8;y<=40;y++) Wire3DCGB_DrawLine2DColor(48,y,80,y,2);
    for(y=64;y<=72;y++) Wire3DCGB_DrawLine2DColor(88,y,120,y,3);
    // The C triangle/rectangle clearers access the stage through the current
    // WRAM window. Select bank 2 around them and restore the caller's bank.
    bank=sample_svbk; sample_svbk=2;
    Wire3DCGB_EraseTriangle2D(12,12,36,12,12,36);
    Wire3DCGB_EraseSpan2D(36,40,24);
    Wire3DCGB_EraseRect2D(56,16,72,32);
    Wire3DCGB_ErasePackedSilhouette2D(silhouette,5,-2,104,68);
    sample_svbk=bank;
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Triangles, segments horizontaux, rectangles et silhouettes compactées creusent des trous noirs dans des panneaux remplis en rouge, bleu et vert.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_erase.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_erase.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:153

kitaqgb/lib/wire3d_cgb.c:2038

c
void Wire3DCGB_ErasePackedSilhouette2D(const w3dcgb_u8* profile, w3dcgb_u8 count,
                                      w3dcgb_i8 y0, w3dcgb_u8 x, w3dcgb_u8 y)
{
    w3dcgb_u8 i;
    w3dcgb_u8 packed;
    w3dcgb_u8 half_width;
    w3dcgb_i16 center;
    w3dcgb_i16 left;
    w3dcgb_i16 right;
    w3dcgb_i16 row;

    if (profile == 0) return;
    if (count > 29) count = 29;
    i = 0;
    while (i < count)
    {
        packed = profile[(__safe_index w3dcgb_u8)i];
        if (packed != 0xFF)
        {
            row = (w3dcgb_i16)((w3dcgb_i16)y + (w3dcgb_i16)y0 + (w3dcgb_i16)i);
            if ((row >= 0) && (row < WIRE3DCGB_SCREEN_H))
            {
                center = (w3dcgb_i16)((w3dcgb_i16)x + (w3dcgb_i16)(packed >> 4) - 7);
                half_width = (w3dcgb_u8)(packed & 15);
                left = (w3dcgb_i16)(center - (w3dcgb_i16)half_width - 2);
                right = (w3dcgb_i16)(center + (w3dcgb_i16)half_width + 2);
                if ((right >= 0) && (left < WIRE3DCGB_SCREEN_W))
                {
                    if (left < 0) left = 0;
                    if (right >= WIRE3DCGB_SCREEN_W) right = WIRE3DCGB_SCREEN_W - 1;
                    w3dcgb_mask_span_y = (w3dcgb_u8)row;
                    w3dcgb_mask_span_min_x = (w3dcgb_u8)left;
                    w3dcgb_mask_span_max_x = (w3dcgb_u8)right;
                    w3dcgb_stage_clear_span_asm();
                }
            }
        }
        i = (w3dcgb_u8)(i + 1);
    }
}
Wire3DCGB_EraseRect2D

Efface un rectangle dans la zone de préparation normale.

Syntaxe

c
void Wire3DCGB_EraseRect2D(w3dcgb_u8 x0, w3dcgb_u8 y0, w3dcgb_u8 x1, w3dcgb_u8 y1);

Paramètres

x0

Borne X inférieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

y0

Borne Y inférieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

x1

Borne X supérieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

y1

Borne Y supérieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Ordonne les bornes du rectangle et le découpe à 128×96. Les bandes gauches de pleine hauteur et de 16 ou 24 pixels de large utilisent l’effacement ASM avec préservation de banque et marquage des modifications. Les autres rectangles utilisent l’effacement ligne par ligne en C et nécessitent que l’appelant assure le bon mappage WRAM de la zone de préparation.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Colored panels expose triangle, span, rectangle and packed-silhouette erasure.
#include "wire_cgb_example.h"
__prg_rom u8 silhouette[5]={0x73,0x74,0xFF,0x75,0x73};
void main() {
    u8 y;
    u8 bank;
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    for(y=8;y<=40;y++) Wire3DCGB_DrawLine2DColor(8,y,40,y,1);
    for(y=8;y<=40;y++) Wire3DCGB_DrawLine2DColor(48,y,80,y,2);
    for(y=64;y<=72;y++) Wire3DCGB_DrawLine2DColor(88,y,120,y,3);
    // The C triangle/rectangle clearers access the stage through the current
    // WRAM window. Select bank 2 around them and restore the caller's bank.
    bank=sample_svbk; sample_svbk=2;
    Wire3DCGB_EraseTriangle2D(12,12,36,12,12,36);
    Wire3DCGB_EraseSpan2D(36,40,24);
    Wire3DCGB_EraseRect2D(56,16,72,32);
    Wire3DCGB_ErasePackedSilhouette2D(silhouette,5,-2,104,68);
    sample_svbk=bank;
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Triangles, segments horizontaux, rectangles et silhouettes compactées creusent des trous noirs dans des panneaux remplis en rouge, bleu et vert.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_erase.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_erase.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:145

kitaqgb/lib/wire3d_cgb.c:9146

c
void Wire3DCGB_EraseRect2D(w3dcgb_u8 x0, w3dcgb_u8 y0, w3dcgb_u8 x1, w3dcgb_u8 y1)
{
    w3dcgb_u8 t;
    w3dcgb_u8 y;

    if (x0 > x1)
    {
        t = x0;
        x0 = x1;
        x1 = t;
    }
    if (y0 > y1)
    {
        t = y0;
        y0 = y1;
        y1 = t;
    }
    if (x0 >= WIRE3DCGB_SCREEN_W) return;
    if (y0 >= WIRE3DCGB_SCREEN_H) return;
    if (x1 >= WIRE3DCGB_SCREEN_W) x1 = (w3dcgb_u8)(WIRE3DCGB_SCREEN_W - 1);
    if (y1 >= WIRE3DCGB_SCREEN_H) y1 = (w3dcgb_u8)(WIRE3DCGB_SCREEN_H - 1);

    if ((x0 == 0) &&
        (x1 == 15) &&
        (y0 == 0) &&
        (y1 == (w3dcgb_u8)(WIRE3DCGB_SCREEN_H - 1)))
    {
        w3dcgb_erase_left_guard16_asm();
        w3dcgb_mark_dirty_rect(0, 0, 15, (w3dcgb_u8)(WIRE3DCGB_SCREEN_H - 1));
        return;
    }
    if ((x0 == 0) &&
        (x1 == 23) &&
        (y0 == 0) &&
        (y1 == (w3dcgb_u8)(WIRE3DCGB_SCREEN_H - 1)))
    {
        w3dcgb_erase_left_guard24_asm();
        w3dcgb_mark_dirty_rect(0, 0, 23, (w3dcgb_u8)(WIRE3DCGB_SCREEN_H - 1));
        return;
    }

    y = y0;
    while (y <= y1)
    {
        w3dcgb_stage_clear_span(y, x0, x1);
        if (y == y1) break;
        y = (w3dcgb_u8)(y + 1);
    }
}
Wire3DCGB_EraseSpan2D

Efface un segment horizontal en sauvegardant puis restaurant la sélection de banque WRAM.

Syntaxe

c
void Wire3DCGB_EraseSpan2D(w3dcgb_u8 y, w3dcgb_u8 x0, w3dcgb_u8 x1);

Paramètres

y

Coordonnée Y en pixels de la ligne à effacer.

x0

Borne X inférieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

x1

Borne X supérieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Ordonne les bornes X, rejette une ligne ou une borne gauche hors écran, puis limite la borne droite à 127. Marque la plage comme modifiée et utilise l’effacement ASM de segments, qui sélectionne la banque WRAM 2 puis restaure la sélection précédente.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Colored panels expose triangle, span, rectangle and packed-silhouette erasure.
#include "wire_cgb_example.h"
__prg_rom u8 silhouette[5]={0x73,0x74,0xFF,0x75,0x73};
void main() {
    u8 y;
    u8 bank;
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    for(y=8;y<=40;y++) Wire3DCGB_DrawLine2DColor(8,y,40,y,1);
    for(y=8;y<=40;y++) Wire3DCGB_DrawLine2DColor(48,y,80,y,2);
    for(y=64;y<=72;y++) Wire3DCGB_DrawLine2DColor(88,y,120,y,3);
    // The C triangle/rectangle clearers access the stage through the current
    // WRAM window. Select bank 2 around them and restore the caller's bank.
    bank=sample_svbk; sample_svbk=2;
    Wire3DCGB_EraseTriangle2D(12,12,36,12,12,36);
    Wire3DCGB_EraseSpan2D(36,40,24);
    Wire3DCGB_EraseRect2D(56,16,72,32);
    Wire3DCGB_ErasePackedSilhouette2D(silhouette,5,-2,104,68);
    sample_svbk=bank;
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Triangles, segments horizontaux, rectangles et silhouettes compactées creusent des trous noirs dans des panneaux remplis en rouge, bleu et vert.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_erase.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_erase.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:134

kitaqgb/lib/wire3d_cgb.c:9123

c
void Wire3DCGB_EraseSpan2D(w3dcgb_u8 y, w3dcgb_u8 x0, w3dcgb_u8 x1)
{
    w3dcgb_u8 tx;

    if (x0 > x1)
    {
        tx = x0;
        x0 = x1;
        x1 = tx;
    }
    if ((y >= WIRE3DCGB_SCREEN_H) || (x0 >= WIRE3DCGB_SCREEN_W)) return;
    if (x1 >= WIRE3DCGB_SCREEN_W) x1 = WIRE3DCGB_SCREEN_W - 1;
    w3dcgb_mark_dirty_rect(x0, y, x1, y);
    w3dcgb_mask_span_y = y;
    w3dcgb_mask_span_min_x = x0;
    w3dcgb_mask_span_max_x = x1;
    w3dcgb_stage_clear_span_asm();
}
Wire3DCGB_EraseTriangle2D

Efface un triangle dans les deux plans de couleur de la zone de préparation normale.

Syntaxe

c
void Wire3DCGB_EraseTriangle2D(w3dcgb_u8 ax, w3dcgb_u8 ay, w3dcgb_u8 bx, w3dcgb_u8 by, w3dcgb_u8 cx, w3dcgb_u8 cy);

Paramètres

ax

Coordonnée X du sommet A en pixels du viewport.

ay

Coordonnée Y du sommet A en pixels du viewport.

bx

Coordonnée X du sommet B en pixels du viewport.

by

Coordonnée Y du sommet B en pixels du viewport.

cx

Coordonnée X du sommet C en pixels du viewport.

cy

Coordonnée Y du sommet C en pixels du viewport.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Efface un triangle avec l’effacement normal en C de la zone de préparation. Ses segments découpés marquent les tuiles touchées comme modifiées ; l’appelant ou l’allocation doit assurer le mappage WRAM de cette zone.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Colored panels expose triangle, span, rectangle and packed-silhouette erasure.
#include "wire_cgb_example.h"
__prg_rom u8 silhouette[5]={0x73,0x74,0xFF,0x75,0x73};
void main() {
    u8 y;
    u8 bank;
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    for(y=8;y<=40;y++) Wire3DCGB_DrawLine2DColor(8,y,40,y,1);
    for(y=8;y<=40;y++) Wire3DCGB_DrawLine2DColor(48,y,80,y,2);
    for(y=64;y<=72;y++) Wire3DCGB_DrawLine2DColor(88,y,120,y,3);
    // The C triangle/rectangle clearers access the stage through the current
    // WRAM window. Select bank 2 around them and restore the caller's bank.
    bank=sample_svbk; sample_svbk=2;
    Wire3DCGB_EraseTriangle2D(12,12,36,12,12,36);
    Wire3DCGB_EraseSpan2D(36,40,24);
    Wire3DCGB_EraseRect2D(56,16,72,32);
    Wire3DCGB_ErasePackedSilhouette2D(silhouette,5,-2,104,68);
    sample_svbk=bank;
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Triangles, segments horizontaux, rectangles et silhouettes compactées creusent des trous noirs dans des panneaux remplis en rouge, bleu et vert.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_erase.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_erase.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:133

kitaqgb/lib/wire3d_cgb.c:9113

c
void Wire3DCGB_EraseTriangle2D(w3dcgb_u8 ax, w3dcgb_u8 ay, w3dcgb_u8 bx, w3dcgb_u8 by, w3dcgb_u8 cx, w3dcgb_u8 cy)
{
    w3dcgb_clear_triangle(ax, ay, bx, by, cx, cy);
}
Wire3DCGB_FastMapBegin

Efface les numéros de tuiles et attributs du viewport FastMap de 16×12.

Syntaxe

c
void Wire3DCGB_FastMapBegin();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Marque FastMap comme préparé et efface les numéros de tuiles et attributs de son viewport de 16×12. Les colonnes 16..31 de la copie de travail sont conservées, même si le transfert copie 32 colonnes par ligne. Nécessite le runtime complet et un mappage WRAM FastMap stable ; n’initialise pas le matériel et ne transfère pas la carte.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// FastMap uses precomputed outline tiles rather than a pixel stage upload.
#include "wire_cgb_example.h"
void main() {
    u8 bank;
    wire_results_clear(); Wire3DCGB_InitFastMapLite(); wire_colors();
    bank=sample_svbk;sample_svbk=2;
    Wire3DCGB_FastMapBegin();
    Wire3DCGB_FastMapCell(1,1,1,15); // This first red square must disappear.
    Wire3DCGB_FastMapFlush();
    Wire3DCGB_FastMapBeginTilesOnly();
    Wire3DCGB_FastMapCell(13,1,1,1);
    Wire3DCGB_FastMapCell(13,1,1,4); // Same-color top and left sides combine.
    Wire3DCGB_FastMapRect(4,2,9,7,2,15);
    Wire3DCGB_FastMapCell(2,9,3,15);
    Wire3DCGB_FastMapFlushTilesOnly();
    sample_svbk=bank;result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Un coin rouge, un grand rectangle bleu et un cadre vert d’une tuile illustrent les cases de contour. La case rouge initiale en haut à gauche disparaît, tandis que la mise à jour des seules tuiles conserve les attributs.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_fastmap.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_fastmap.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:160

kitaqgb/lib/wire3d_cgb.c:10137

c
void Wire3DCGB_FastMapBegin()
{
    w3dcgb_fast_map_ready = 1;
    w3dcgb_fast_map_clear_rect(0, 0, 16, 12);
}
Wire3DCGB_FastMapBeginTilesOnly

Efface uniquement les numéros de tuiles du viewport FastMap de 16×12.

Syntaxe

c
void Wire3DCGB_FastMapBeginTilesOnly();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Marque FastMap comme préparé et efface seulement les numéros de tuiles de son viewport de 16×12. Conserve les attributs et les colonnes 16..31. Nécessite le runtime complet et le mappage WRAM prévu ; initialisation matérielle et transfert sont séparés.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// FastMap uses precomputed outline tiles rather than a pixel stage upload.
#include "wire_cgb_example.h"
void main() {
    u8 bank;
    wire_results_clear(); Wire3DCGB_InitFastMapLite(); wire_colors();
    bank=sample_svbk;sample_svbk=2;
    Wire3DCGB_FastMapBegin();
    Wire3DCGB_FastMapCell(1,1,1,15); // This first red square must disappear.
    Wire3DCGB_FastMapFlush();
    Wire3DCGB_FastMapBeginTilesOnly();
    Wire3DCGB_FastMapCell(13,1,1,1);
    Wire3DCGB_FastMapCell(13,1,1,4); // Same-color top and left sides combine.
    Wire3DCGB_FastMapRect(4,2,9,7,2,15);
    Wire3DCGB_FastMapCell(2,9,3,15);
    Wire3DCGB_FastMapFlushTilesOnly();
    sample_svbk=bank;result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Un coin rouge, un grand rectangle bleu et un cadre vert d’une tuile illustrent les cases de contour. La case rouge initiale en haut à gauche disparaît, tandis que la mise à jour des seules tuiles conserve les attributs.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_fastmap.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_fastmap.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:161

kitaqgb/lib/wire3d_cgb.c:10146

c
void Wire3DCGB_FastMapBeginTilesOnly()
{
    w3dcgb_fast_map_ready = 1;
    w3dcgb_fm_x0 = 0;
    w3dcgb_fm_y0 = 0;
    w3dcgb_fm_count_x = 16;
    w3dcgb_fm_count_y = 12;
    w3dcgb_fast_map_clear_rect_asm();
}
Wire3DCGB_FastMapCell

Ajoute à une case de carte les côtés de contour choisis parmi haut, bas, gauche et droite.

Syntaxe

c
void Wire3DCGB_FastMapCell(w3dcgb_u8 tx, w3dcgb_u8 ty, w3dcgb_u8 color, w3dcgb_u8 mask);

Paramètres

tx

Position X en coordonnées de tuiles.

ty

Position Y en coordonnées de tuiles.

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

mask

Masque des côtés de case : 1=haut, 2=bas, 4=gauche, 8=droite.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Ajoute des côtés de contour à une case : les bits 1/2/4/8 désignent haut/bas/gauche/droite. Les masques de même couleur se combinent ; une autre couleur remplace l’ancien masque. Un masque nul est ignoré, la couleur zéro signifie MAIN et les valeurs au-delà de 3 sont ramenées à 3. Vise la copie de travail de 16×12 avec un mappage WRAM stable ; runtime complet requis.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// FastMap uses precomputed outline tiles rather than a pixel stage upload.
#include "wire_cgb_example.h"
void main() {
    u8 bank;
    wire_results_clear(); Wire3DCGB_InitFastMapLite(); wire_colors();
    bank=sample_svbk;sample_svbk=2;
    Wire3DCGB_FastMapBegin();
    Wire3DCGB_FastMapCell(1,1,1,15); // This first red square must disappear.
    Wire3DCGB_FastMapFlush();
    Wire3DCGB_FastMapBeginTilesOnly();
    Wire3DCGB_FastMapCell(13,1,1,1);
    Wire3DCGB_FastMapCell(13,1,1,4); // Same-color top and left sides combine.
    Wire3DCGB_FastMapRect(4,2,9,7,2,15);
    Wire3DCGB_FastMapCell(2,9,3,15);
    Wire3DCGB_FastMapFlushTilesOnly();
    sample_svbk=bank;result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Un coin rouge, un grand rectangle bleu et un cadre vert d’une tuile illustrent les cases de contour. La case rouge initiale en haut à gauche disparaît, tandis que la mise à jour des seules tuiles conserve les attributs.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_fastmap.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_fastmap.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:162

kitaqgb/lib/wire3d_cgb.c:10160

c
void Wire3DCGB_FastMapCell(w3dcgb_u8 tx, w3dcgb_u8 ty, w3dcgb_u8 color, w3dcgb_u8 mask)
{
    w3dcgb_fast_map_or_cell((w3dcgb_i16)tx, (w3dcgb_i16)ty, color, mask);
}
Wire3DCGB_FastMapFlush

Transfère en VRAM les douze premières lignes complètes de numéros de tuiles et d’attributs de la copie de travail.

Syntaxe

c
void Wire3DCGB_FastMapFlush();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Si le LCD est allumé, attend un nouveau VBlank, puis transfère les douze premières lignes complètes de numéros de tuiles et d’attributs vers la carte 9800. LCD éteint, procède immédiatement. Nécessite le runtime complet, un mappage WRAM stable et une période sûre assez longue pour les deux transferts GDMA immédiats.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// FastMap uses precomputed outline tiles rather than a pixel stage upload.
#include "wire_cgb_example.h"
void main() {
    u8 bank;
    wire_results_clear(); Wire3DCGB_InitFastMapLite(); wire_colors();
    bank=sample_svbk;sample_svbk=2;
    Wire3DCGB_FastMapBegin();
    Wire3DCGB_FastMapCell(1,1,1,15); // This first red square must disappear.
    Wire3DCGB_FastMapFlush();
    Wire3DCGB_FastMapBeginTilesOnly();
    Wire3DCGB_FastMapCell(13,1,1,1);
    Wire3DCGB_FastMapCell(13,1,1,4); // Same-color top and left sides combine.
    Wire3DCGB_FastMapRect(4,2,9,7,2,15);
    Wire3DCGB_FastMapCell(2,9,3,15);
    Wire3DCGB_FastMapFlushTilesOnly();
    sample_svbk=bank;result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Un coin rouge, un grand rectangle bleu et un cadre vert d’une tuile illustrent les cases de contour. La case rouge initiale en haut à gauche disparaît, tandis que la mise à jour des seules tuiles conserve les attributs.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_fastmap.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_fastmap.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:164

kitaqgb/lib/wire3d_cgb.c:10208

c
void Wire3DCGB_FastMapFlush()
{
    w3dcgb_wait_vblank_start();
    w3dcgb_fast_map_flush_gdma_asm();
}
Wire3DCGB_FastMapFlushTilesOnly

Transfère uniquement les numéros de tuiles des douze premières lignes complètes de la carte de travail.

Syntaxe

c
void Wire3DCGB_FastMapFlushTilesOnly();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Si le LCD est allumé, attend un nouveau VBlank et transfère uniquement les numéros de tuiles des douze premières lignes complètes vers la carte 9800. Les attributs restent intacts. Nécessite le runtime complet, un mappage WRAM stable et un intervalle sûr pour le GDMA.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// FastMap uses precomputed outline tiles rather than a pixel stage upload.
#include "wire_cgb_example.h"
void main() {
    u8 bank;
    wire_results_clear(); Wire3DCGB_InitFastMapLite(); wire_colors();
    bank=sample_svbk;sample_svbk=2;
    Wire3DCGB_FastMapBegin();
    Wire3DCGB_FastMapCell(1,1,1,15); // This first red square must disappear.
    Wire3DCGB_FastMapFlush();
    Wire3DCGB_FastMapBeginTilesOnly();
    Wire3DCGB_FastMapCell(13,1,1,1);
    Wire3DCGB_FastMapCell(13,1,1,4); // Same-color top and left sides combine.
    Wire3DCGB_FastMapRect(4,2,9,7,2,15);
    Wire3DCGB_FastMapCell(2,9,3,15);
    Wire3DCGB_FastMapFlushTilesOnly();
    sample_svbk=bank;result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Un coin rouge, un grand rectangle bleu et un cadre vert d’une tuile illustrent les cases de contour. La case rouge initiale en haut à gauche disparaît, tandis que la mise à jour des seules tuiles conserve les attributs.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_fastmap.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_fastmap.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:165

kitaqgb/lib/wire3d_cgb.c:10217

c
void Wire3DCGB_FastMapFlushTilesOnly()
{
    w3dcgb_wait_vblank_start();
    w3dcgb_fast_map_flush_tiles_gdma_asm();
}
Wire3DCGB_FastMapRect

Place les côtés de contour choisis autour d’un rectangle en coordonnées de tuiles.

Syntaxe

c
void Wire3DCGB_FastMapRect(w3dcgb_u8 tx0, w3dcgb_u8 ty0, w3dcgb_u8 tx1, w3dcgb_u8 ty1, w3dcgb_u8 color, w3dcgb_u8 sides);

Paramètres

tx0

Position X en coordonnées de tuiles.

ty0

Position Y en coordonnées de tuiles.

tx1

Position X en coordonnées de tuiles.

ty1

Position Y en coordonnées de tuiles.

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

sides

Masque des côtés du rectangle : 1=haut, 2=bas, 4=gauche, 8=droite.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Ordonne les coordonnées de tuiles sur octets et les découpe à 16×12, puis remplace les cases de bord choisies. Les bits 1/2/4/8 désignent haut/bas/gauche/droite. La couleur zéro signifie MAIN ; les valeurs au-delà de 3 sont ramenées à 3. Attributs et cases intérieures restent intacts. Utilisez au moins deux lignes et deux colonnes pour des coins distincts ; les coins confondus sont écrasés successivement. Nécessite le runtime complet et un mappage WRAM stable.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// FastMap uses precomputed outline tiles rather than a pixel stage upload.
#include "wire_cgb_example.h"
void main() {
    u8 bank;
    wire_results_clear(); Wire3DCGB_InitFastMapLite(); wire_colors();
    bank=sample_svbk;sample_svbk=2;
    Wire3DCGB_FastMapBegin();
    Wire3DCGB_FastMapCell(1,1,1,15); // This first red square must disappear.
    Wire3DCGB_FastMapFlush();
    Wire3DCGB_FastMapBeginTilesOnly();
    Wire3DCGB_FastMapCell(13,1,1,1);
    Wire3DCGB_FastMapCell(13,1,1,4); // Same-color top and left sides combine.
    Wire3DCGB_FastMapRect(4,2,9,7,2,15);
    Wire3DCGB_FastMapCell(2,9,3,15);
    Wire3DCGB_FastMapFlushTilesOnly();
    sample_svbk=bank;result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Un coin rouge, un grand rectangle bleu et un cadre vert d’une tuile illustrent les cases de contour. La case rouge initiale en haut à gauche disparaît, tandis que la mise à jour des seules tuiles conserve les attributs.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_fastmap.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_fastmap.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:163

kitaqgb/lib/wire3d_cgb.c:10170

c
void Wire3DCGB_FastMapRect(w3dcgb_u8 tx0, w3dcgb_u8 ty0, w3dcgb_u8 tx1, w3dcgb_u8 ty1, w3dcgb_u8 color, w3dcgb_u8 sides)
{
    w3dcgb_u8 t;

    if (tx0 > tx1)
    {
        t = tx0;
        tx0 = tx1;
        tx1 = t;
    }
    if (ty0 > ty1)
    {
        t = ty0;
        ty0 = ty1;
        ty1 = t;
    }
    if (tx0 >= 16) return;
    if (ty0 >= 12) return;
    if (tx1 >= 16) tx1 = 15;
    if (ty1 >= 12) ty1 = 11;
    if (color == 0) color = WIRE3DCGB_COLOR_MAIN;
    if (color > 3) color = 3;

    w3dcgb_fm_x0 = tx0;
    w3dcgb_fm_y0 = ty0;
    w3dcgb_fm_x1 = tx1;
    w3dcgb_fm_y1 = ty1;
    w3dcgb_fm_count_x = (w3dcgb_u8)(tx1 - tx0 + 1);
    w3dcgb_fm_count_y = (w3dcgb_u8)(ty1 - ty0 + 1);
    w3dcgb_fm_tile_base = (w3dcgb_u8)(W3DCGB_FAST_TILE_BASE + ((color - 1) << 4));
    w3dcgb_fm_sides = (w3dcgb_u8)(sides & 15);
    w3dcgb_fast_map_rect_asm();
}
Wire3DCGB_GetFullScreenOverflow

Signale une coordonnée invalide ou l’épuisement de l’allocation de tuiles en plein écran.

Syntaxe

c
w3dcgb_u8 Wire3DCGB_GetFullScreenOverflow();

Valeur renvoyée

Zéro sans erreur, un après épuisement de l’allocation ou coordonnée invalide.

Conditions et limites

Renvoie l’indicateur d’erreur de l’image plein écran : le chemin de lignes rapides le définit en cas d’épuisement des tuiles ou de coordonnée invalide. Une fois défini, les tracés de pixels rapides suivants sont supprimés jusqu’à sa réinitialisation par BeginFrame. Ce n’est pas un indicateur général d’état matériel ; la lecture nécessite le runtime complet.

L’allocation plein écran a lieu avant que l’occlusion ou le débordement ne supprime les écritures de pixels. Des tuiles allouées peuvent rester noires, et dessiner après une erreur peut encore augmenter leur nombre.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// One point per tile exposes the 127-tile limit without relying on text alone.
#include "wire_cgb_example.h"
void main() {
    u8 i;
    wire_results_clear();
    Wire3DCGB_InitFullScreen(); wire_colors();
    Wire3DCGB_BeginFrame(); Wire3DCGB_SetLineColor(3);
    for(i=0;i<128;i++) Wire3DCGB_DrawPoint2D((i%20)*8+4,(i/20)*8+4);
    result[0]=Wire3DCGB_GetFullScreenTileCount();
    result[1]=Wire3DCGB_GetFullScreenOverflow();
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

127 points rouges occupent des tuiles distinctes. Une tentative de 128e allocation laisse le compteur à 127 et met overflow à un.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_capacity.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_capacity.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:194

kitaqgb/lib/wire3d_cgb.c:9965

c
w3dcgb_u8 Wire3DCGB_GetFullScreenOverflow()
{
    return w3dcgb_full_overflow;
}
Wire3DCGB_GetFullScreenTileCount

Renvoie le nombre de tuiles plein écran allouées dans l’image courante.

Syntaxe

c
w3dcgb_u8 Wire3DCGB_GetFullScreenTileCount();

Valeur renvoyée

Nombre de tuiles allouées, de 0 à 127.

Conditions et limites

Renvoie le nombre courant d’allocations plein écran, jusqu’à 127. Ce n’est ni un nombre d’octets ni le nombre de pixels visibles ou non nuls. Runtime complet uniquement.

L’allocation plein écran a lieu avant que l’occlusion ou le débordement ne supprime les écritures de pixels. Des tuiles allouées peuvent rester noires, et dessiner après une erreur peut encore augmenter leur nombre.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// One point per tile exposes the 127-tile limit without relying on text alone.
#include "wire_cgb_example.h"
void main() {
    u8 i;
    wire_results_clear();
    Wire3DCGB_InitFullScreen(); wire_colors();
    Wire3DCGB_BeginFrame(); Wire3DCGB_SetLineColor(3);
    for(i=0;i<128;i++) Wire3DCGB_DrawPoint2D((i%20)*8+4,(i/20)*8+4);
    result[0]=Wire3DCGB_GetFullScreenTileCount();
    result[1]=Wire3DCGB_GetFullScreenOverflow();
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

127 points rouges occupent des tuiles distinctes. Une tentative de 128e allocation laisse le compteur à 127 et met overflow à un.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_capacity.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_capacity.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:193

kitaqgb/lib/wire3d_cgb.c:9956

c
w3dcgb_u8 Wire3DCGB_GetFullScreenTileCount()
{
    return w3dcgb_full_tile_count;
}
Wire3DCGB_GetLineColor

Lit l’indice de couleur de ligne actuellement stocké.

Syntaxe

c
w3dcgb_u8 Wire3DCGB_GetLineColor();

Valeur renvoyée

Valeur de couleur de ligne actuellement stockée.

Conditions et limites

Renvoie la couleur de ligne courante sur deux bits sans modifier l’état de dessin.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:120

kitaqgb/lib/wire3d_cgb.c:1147

c
w3dcgb_u8 Wire3DCGB_GetLineColor()
{
    return w3dcgb_line_color;
}
Wire3DCGB_Init

Initialise le moteur de rendu par pixels CGB de 128×96.

Syntaxe

c
void Wire3DCGB_Init();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Initialise le moteur CGB de 128×96 : active la double vitesse, éteint le LCD au VBlank, efface les deux banques de tuiles, charge les tuiles du HUD et les tuiles générées, puis installe une zone de 16×12 en ordre par colonnes. L’état initial utilise la banque de tuiles vide 1, un défilement nul, les palettes BG par défaut, la couleur 2 et une caméra à zéro. Réinitialise les files et efface la zone de préparation de la banque 2. Appelez BeginFrame avant de dessiner pour initialiser l’occlusion. L’initialisation remplace globalement l’état du LCD, des tuiles et de la carte.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Au démarrage sparse CGB, la première utilisation de chaque banque cible (les deux premières images) actualise tout le viewport et efface les tuiles d’initialisation. Cette charge est incluse dans les mesures. DrawLine2D ne déclare pas de zone sparse : utilisez DrawLineClipped2D ou MarkDirtyRect2D explicitement.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:113

kitaqgb/lib/wire3d_cgb.c:7994

c
void Wire3DCGB_Init()
{
    w3dcgb_u8 row;
    w3dcgb_u8 col;
    w3dcgb_u8 tid;
    w3dcgb_u8 tile_index;
    w3dcgb_u16 off;

    w3dcgb_full_mode = 0;
    w3dcgb_atomic_maps = 0;
    Wire3DCGB_EnableDoubleSpeed();
    w3dcgb_wait_vblank_start();
    w3dcgb_reg_lcdc = 0;

    w3dcgb_clear_vram_asm();
    w3dcgb_load_hud_tiles();
#ifndef WIRE3DCGB_MINIMAL_RUNTIME
    w3dcgb_load_fast_map_tiles();
    w3dcgb_load_fast_stamp_tiles();
#endif
    w3dcgb_fill_bg_map_asm();
    w3dcgb_fill_attr_map_asm();

    row = 0;
    while (row < W3DCGB_TILE_H)
    {
        off = (w3dcgb_u16)((w3dcgb_u16)row << 5);
        tile_index = row;
        col = 0;
        while (col < W3DCGB_TILE_W)
        {
            if (tile_index < 112) tid = (w3dcgb_u8)(0x90 + tile_index);
            else tid = (w3dcgb_u8)(tile_index - 112);
            w3dcgb_bg_map_9800[(w3dcgb_u16)(off + (w3dcgb_u16)col)] = tid;
            tile_index = (w3dcgb_u8)(tile_index + W3DCGB_TILE_H);
            col = (w3dcgb_u8)(col + 1);
        }
        row = (w3dcgb_u8)(row + 1);
    }

    w3dcgb_select_blank_render_bank_asm();

    w3dcgb_reg_scx = 0;
    w3dcgb_reg_scy = 0;
    w3dcgb_reg_bgp = 0xB4;
    Wire3DCGB_SetPaletteRGB15(
        WIRE3DCGB_RGB15(0, 0, 2),
        WIRE3DCGB_RGB15(10, 20, 31),
        WIRE3DCGB_RGB15(31, 31, 31),
        WIRE3DCGB_RGB15(31, 14, 4));
    w3dcgb_line_color = WIRE3DCGB_COLOR_DEFAULT;
    w3dcgb_reg_lcdc = 0x81;
    w3dcgb_bgq_count = 0;
    w3dcgb_dirty_count = 0;
    w3dcgb_prev_dirty_count = 0;
    w3dcgb_dirty_min_tile = 0xFF;
    w3dcgb_dirty_max_tile = 0;
    // Both back banks may contain generated fast-map/stamp tiles. Refresh
    // the whole pixel viewport on their first sparse use, including empty rows.
    w3dcgb_prev_dirty_min_tile = 0;
    w3dcgb_prev_dirty_max_tile = (w3dcgb_u8)(WIRE3DCGB_TILE_COUNT - 1);
    w3dcgb_older_dirty_min_tile = 0;
    w3dcgb_older_dirty_max_tile = (w3dcgb_u8)(WIRE3DCGB_TILE_COUNT - 1);
    w3dcgb_display_tile_bank = 1;
    w3dcgb_pending_tile_bank = 1;

    Wire3DCGB_SetCamera((w3dcgb_i16)0, (w3dcgb_i16)0, (w3dcgb_i16)0, 0, 0, 0);
    w3dcgb_clear_stage_asm();
}
Wire3DCGB_InitFastMapLite

Initialise le rendu FastMap avec des tuiles de contour précalculées.

Syntaxe

c
void Wire3DCGB_InitFastMapLite();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Initialise un moteur de carte de tuiles CGB avec HUD et 48 tuiles de contour précalculées. Efface la VRAM des tuiles et les cartes, réinitialise défilement, palettes et caméra, puis choisit le mode normal. La disposition de carte du viewport par pixels et les motifs de cube générés sont omis ; utilisez les API FastMap dans ce mode. Efface la zone de préparation en banque 2 et marque la préparation de FastMap comme en attente. Une compilation avec le runtime complet est requise.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// FastMap uses precomputed outline tiles rather than a pixel stage upload.
#include "wire_cgb_example.h"
void main() {
    u8 bank;
    wire_results_clear(); Wire3DCGB_InitFastMapLite(); wire_colors();
    bank=sample_svbk;sample_svbk=2;
    Wire3DCGB_FastMapBegin();
    Wire3DCGB_FastMapCell(1,1,1,15); // This first red square must disappear.
    Wire3DCGB_FastMapFlush();
    Wire3DCGB_FastMapBeginTilesOnly();
    Wire3DCGB_FastMapCell(13,1,1,1);
    Wire3DCGB_FastMapCell(13,1,1,4); // Same-color top and left sides combine.
    Wire3DCGB_FastMapRect(4,2,9,7,2,15);
    Wire3DCGB_FastMapCell(2,9,3,15);
    Wire3DCGB_FastMapFlushTilesOnly();
    sample_svbk=bank;result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Un coin rouge, un grand rectangle bleu et un cadre vert d’une tuile illustrent les cases de contour. La case rouge initiale en haut à gauche disparaît, tandis que la mise à jour des seules tuiles conserve les attributs.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_fastmap.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_fastmap.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:115

kitaqgb/lib/wire3d_cgb.c:8108

c
void Wire3DCGB_InitFastMapLite()
{
    w3dcgb_atomic_maps = 0;
    w3dcgb_full_mode = 0;
    Wire3DCGB_EnableDoubleSpeed();
    w3dcgb_wait_vblank_start();
    w3dcgb_reg_lcdc = 0;

    w3dcgb_clear_vram_asm();
    w3dcgb_load_hud_tiles();
    w3dcgb_load_fast_map_tiles_lite_asm();
    w3dcgb_fill_bg_map_asm();
    w3dcgb_fill_attr_map_asm();

    w3dcgb_reg_scx = 0;
    w3dcgb_reg_scy = 0;
    w3dcgb_reg_bgp = 0xB4;
    Wire3DCGB_SetPaletteRGB15(
        WIRE3DCGB_RGB15(0, 0, 2),
        WIRE3DCGB_RGB15(10, 20, 31),
        WIRE3DCGB_RGB15(31, 31, 31),
        WIRE3DCGB_RGB15(31, 14, 4));
    w3dcgb_line_color = WIRE3DCGB_COLOR_DEFAULT;
    w3dcgb_reg_lcdc = 0x81;
    w3dcgb_bgq_count = 0;
    w3dcgb_dirty_count = 0;
    w3dcgb_prev_dirty_count = 0;
    w3dcgb_dirty_min_tile = 0xFF;
    w3dcgb_dirty_max_tile = 0;
    w3dcgb_prev_dirty_min_tile = 0xFF;
    w3dcgb_prev_dirty_max_tile = 0;
    w3dcgb_fast_map_ready = 0;
    w3dcgb_display_tile_bank = 0;
    w3dcgb_pending_tile_bank = 0;

    Wire3DCGB_SetCamera((w3dcgb_i16)0, (w3dcgb_i16)0, (w3dcgb_i16)0, 0, 0, 0);
    w3dcgb_clear_stage_asm();
}
Wire3DCGB_InitFullScreen

Initialise un moteur de 160×144 qui alloue les tuiles au fur et à mesure du tracé des pixels.

Syntaxe

c
void Wire3DCGB_InitFullScreen();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Initialise l’allocateur de tuiles CGB de 160×144. Efface les deux banques et la carte 9800, règle défilement, palettes, couleur et caméra, réinitialise les compteurs de tuiles et l’état des tables et segments, puis active l’adressage BG non signé. Les tuiles du HUD ne sont pas chargées. Réservez ses zones fixes en WRAM pour les tables, les données et les listes d’adresses ; gardez la même banque WRAM mappée pendant tout le rendu plein écran.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// A large frame demonstrates the 160x144 renderer and its allocated-tile count.
#include "wire_cgb_example.h"
void main() {
    wire_results_clear();
    Wire3DCGB_InitFullScreen(); wire_colors();
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,151,8);
    Wire3DCGB_DrawLine2D(8,8,8,135);
    Wire3DCGB_DrawLine2DColor(8,135,151,135,2);
    Wire3DCGB_DrawLine2DColor(151,8,151,135,3);
    result[0]=Wire3DCGB_GetFullScreenTileCount();
    result[1]=Wire3DCGB_GetFullScreenOverflow();
    Wire3DCGB_EndFrameFast();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Un grand cadre s’étend de (8,8) à (151,135) : haut et gauche rouges, bas bleu, droite verte. Il utilise 64 tuiles, avec overflow à zéro.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_full.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_full.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:114

kitaqgb/lib/wire3d_cgb.c:8070

c
void Wire3DCGB_InitFullScreen()
{
    w3dcgb_atomic_maps = 0;
    Wire3DCGB_EnableDoubleSpeed();
    w3dcgb_wait_vblank_start();
    w3dcgb_reg_lcdc = 0;

    w3dcgb_clear_vram_asm();
    w3dcgb_full_clear_map_asm();
    w3dcgb_reg_scx = 0;
    w3dcgb_reg_scy = 0;
    w3dcgb_reg_bgp = 0xB4;
    Wire3DCGB_SetPaletteRGB15(
        WIRE3DCGB_RGB15(0, 0, 2),
        WIRE3DCGB_RGB15(10, 20, 31),
        WIRE3DCGB_RGB15(31, 31, 31),
        WIRE3DCGB_RGB15(31, 14, 4));
    w3dcgb_line_color = WIRE3DCGB_COLOR_DEFAULT;
    w3dcgb_bgq_count = 0;
    w3dcgb_dirty_count = 0;
    w3dcgb_prev_dirty_count = 0;
    w3dcgb_display_tile_bank = 0;
    w3dcgb_pending_tile_bank = 0;
    w3dcgb_full_tile_count = 0;
    w3dcgb_full_prev_tile_count = 0;
    w3dcgb_full_overflow = 0;
    w3dcgb_full_mode = 1;

    Wire3DCGB_SetCamera((w3dcgb_i16)0, (w3dcgb_i16)0, (w3dcgb_i16)0, 0, 0, 0);
    w3dcgb_full_begin_asm();
    w3dcgb_reg_lcdc = 0x91;
}
Wire3DCGB_InvalidateFrameHistory

Étend la plage de transfert courante et les deux précédentes aux 192 tuiles du mode normal.

Syntaxe

c
void Wire3DCGB_InvalidateFrameHistory();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Étend la plage partielle courante et les deux précédentes aux 192 tuiles du mode normal. Les pixels ne sont pas effacés ; les transferts suivants ne peuvent plus se fier aux anciennes plages.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Au démarrage sparse CGB, la première utilisation de chaque banque cible (les deux premières images) actualise tout le viewport et efface les tuiles d’initialisation. Cette charge est incluse dans les mesures. DrawLine2D ne déclare pas de zone sparse : utilisez DrawLineClipped2D ou MarkDirtyRect2D explicitement.

Exemple d’utilisation

c
#pragma bank 0
// Reuse both VRAM banks and remove old geometry while presenting sparse frames.
#include "wire_cgb_example.h"
void main() {
    wire_results_clear(); Wire3DCGB_Init();
    Wire3DCGB_ClearFrameTiles();
    Wire3DCGB_EnableAtomicMaps(); wire_colors();
    // First frame: red on the left. Fast begin invalidates both bank histories.
    Wire3DCGB_BeginFrameFast(); wire_frame(8,8,32,32,1);
    Wire3DCGB_EndFrameFast();
    // Second frame: blue in the middle, with the old red frame removed.
    Wire3DCGB_BeginFrameSparse(); wire_frame(40,40,64,64,2);
    Wire3DCGB_EndFrameSparse();
    // Third frame: explicitly clearing a stage discards its first green point.
    Wire3DCGB_BeginFrameSparse();
    Wire3DCGB_SetLineColor(3); Wire3DCGB_DrawPoint2D(4,4);
    Wire3DCGB_ClearSparseStageFast();
    // The final image contains only this green frame on the right.
    wire_frame(80,8,112,32,3);
    Wire3DCGB_MarkDirtyRect2D(80,8,112,32);
    Wire3DCGB_InvalidateFrameHistory();
    Wire3DCGB_EndFrameSparseNow();
    result[0]=Wire3DCGB_GetLineColor();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Les cadres rouge et bleu dessinés précédemment disparaissent ; seul reste le cadre vert final de (80,8) à (112,32), ce qui illustre le transfert partiel et la gestion de l’historique.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_sparse.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_sparse.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:142

kitaqgb/lib/wire3d_cgb.c:9712

c
void Wire3DCGB_InvalidateFrameHistory()
{
    w3dcgb_dirty_min_tile = 0;
    w3dcgb_dirty_max_tile = (w3dcgb_u8)(WIRE3DCGB_TILE_COUNT - 1);
    w3dcgb_prev_dirty_min_tile = 0;
    w3dcgb_prev_dirty_max_tile = (w3dcgb_u8)(WIRE3DCGB_TILE_COUNT - 1);
    w3dcgb_older_dirty_min_tile = 0;
    w3dcgb_older_dirty_max_tile = (w3dcgb_u8)(WIRE3DCGB_TILE_COUNT - 1);
}
Wire3DCGB_MarkDirtyRect2D

Ajoute un rectangle de pixels à la plage à transférer ultérieurement.

Syntaxe

c
void Wire3DCGB_MarkDirtyRect2D(w3dcgb_u8 min_x, w3dcgb_u8 min_y, w3dcgb_u8 max_x, w3dcgb_u8 max_y);

Paramètres

min_x

Borne X inférieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

min_y

Borne Y inférieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

max_x

Borne X supérieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

max_y

Borne X supérieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Marque un rectangle de pixels, bornes incluses, pour un transfert ultérieur sans le dessiner. Fournissez les bornes dans l’ordre ; les valeurs dépassant 127/95 sont ramenées au bord. Le suivi porte sur les tuiles de 128×96, pas sur l’allocateur plein écran.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Reuse both VRAM banks and remove old geometry while presenting sparse frames.
#include "wire_cgb_example.h"
void main() {
    wire_results_clear(); Wire3DCGB_Init();
    Wire3DCGB_ClearFrameTiles();
    Wire3DCGB_EnableAtomicMaps(); wire_colors();
    // First frame: red on the left. Fast begin invalidates both bank histories.
    Wire3DCGB_BeginFrameFast(); wire_frame(8,8,32,32,1);
    Wire3DCGB_EndFrameFast();
    // Second frame: blue in the middle, with the old red frame removed.
    Wire3DCGB_BeginFrameSparse(); wire_frame(40,40,64,64,2);
    Wire3DCGB_EndFrameSparse();
    // Third frame: explicitly clearing a stage discards its first green point.
    Wire3DCGB_BeginFrameSparse();
    Wire3DCGB_SetLineColor(3); Wire3DCGB_DrawPoint2D(4,4);
    Wire3DCGB_ClearSparseStageFast();
    // The final image contains only this green frame on the right.
    wire_frame(80,8,112,32,3);
    Wire3DCGB_MarkDirtyRect2D(80,8,112,32);
    Wire3DCGB_InvalidateFrameHistory();
    Wire3DCGB_EndFrameSparseNow();
    result[0]=Wire3DCGB_GetLineColor();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Les cadres rouge et bleu dessinés précédemment disparaissent ; seul reste le cadre vert final de (80,8) à (112,32), ce qui illustre le transfert partiel et la gestion de l’historique.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_sparse.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_sparse.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:126

kitaqgb/lib/wire3d_cgb.c:1288

c
void Wire3DCGB_MarkDirtyRect2D(w3dcgb_u8 min_x, w3dcgb_u8 min_y, w3dcgb_u8 max_x, w3dcgb_u8 max_y)
{
    w3dcgb_mark_dirty_rect(min_x, min_y, max_x, max_y);
}
Wire3DCGB_MarkPackedSilhouette2D

Marque une silhouette compactée ligne par ligne dans le bitmap d’occlusion de 128×96.

Syntaxe

c
void Wire3DCGB_MarkPackedSilhouette2D(const w3dcgb_u8* profile, w3dcgb_u8 count, w3dcgb_i8 y0, w3dcgb_u8 x, w3dcgb_u8 y);

Paramètres

profile

Tableau de silhouette à un octet par ligne ; 0xFF saute une ligne.

count

Nombre d’entrées fournies ; consultez la limite de traitement propre à l’opération.

y0

Décalage signé du centre Y vers la première ligne de silhouette.

x

Coordonnée X du centre en pixels du viewport.

y

Coordonnée Y du centre en pixels du viewport.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Marque au plus 29 lignes de silhouette dans le masque bitmap de 128×96. Chaque octet compacté utilise son demi-octet haut pour le décalage du centre (nibble−7) et le bas pour la demi-largeur ; 0xFF saute une ligne. Place les lignes à y+y0+i, élargit les segments de deux pixels et les découpe au viewport. profile doit contenir count octets lisibles ; null est ignoré. Ne met pas à jour les segments plein écran et n’active pas l’occlusion.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Red/blue scanlines stop inside masks; green outlines identify the triangle.
#include "wire_cgb_example.h"
__prg_rom u8 silhouette[5]={0x73,0x74,0xFF,0x75,0x73};
void main() {
    u8 y;
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    // Clearing this first test mask must leave the upper-left scanline intact.
    Wire3DCGB_MarkTriangle2D(8,8,16,8,8,16);
    Wire3DCGB_ClearOcclusionMask();
    Wire3DCGB_MarkTriangle2D(32,16,64,16,32,48);
    Wire3DCGB_MarkPackedSilhouette2D(silhouette,5,-2,104,32);
    Wire3DCGB_SetOcclusionActive(1);
    for(y=8;y<=56;y=y+4) Wire3DCGB_DrawLine2DColor(8,y,88,y,1);
    for(y=28;y<=36;y++) Wire3DCGB_DrawLine2DColor(92,y,120,y,2);
    Wire3DCGB_SetOcclusionActive(0);
    Wire3DCGB_DrawLine2DColor(32,16,64,16,3);
    Wire3DCGB_DrawLine2DColor(64,16,32,48,3);
    Wire3DCGB_DrawLine2DColor(32,48,32,16,3);
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Un triangle masque le milieu des lignes de balayage rouges ; une silhouette compactée masque les lignes bleues. Les contours verts situent la région occultante.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_mask.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_mask.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:151

kitaqgb/lib/wire3d_cgb.c:1991

c
void Wire3DCGB_MarkPackedSilhouette2D(const w3dcgb_u8* profile, w3dcgb_u8 count,
                                     w3dcgb_i8 y0, w3dcgb_u8 x, w3dcgb_u8 y)
{
    w3dcgb_u8 i;
    w3dcgb_u8 packed;
    w3dcgb_u8 half_width;
    w3dcgb_i16 center;
    w3dcgb_i16 left;
    w3dcgb_i16 right;
    w3dcgb_i16 row;

    if (profile == 0) return;
    if (count > 29) count = 29;
    i = 0;
    while (i < count)
    {
        packed = profile[(__safe_index w3dcgb_u8)i];
        if (packed != 0xFF)
        {
            row = (w3dcgb_i16)((w3dcgb_i16)y + (w3dcgb_i16)y0 + (w3dcgb_i16)i);
            if ((row >= 0) && (row < WIRE3DCGB_SCREEN_H))
            {
                center = (w3dcgb_i16)((w3dcgb_i16)x + (w3dcgb_i16)(packed >> 4) - 7);
                half_width = (w3dcgb_u8)(packed & 15);
                /* Two-pixel guard covers rasterized endpoints at 22.5-degree views. */
                left = (w3dcgb_i16)(center - (w3dcgb_i16)half_width - 2);
                right = (w3dcgb_i16)(center + (w3dcgb_i16)half_width + 2);
                if ((right >= 0) && (left < WIRE3DCGB_SCREEN_W))
                {
                    if (left < 0) left = 0;
                    if (right >= WIRE3DCGB_SCREEN_W) right = WIRE3DCGB_SCREEN_W - 1;
                    w3dcgb_mask_span_y = (w3dcgb_u8)row;
                    w3dcgb_mask_span_min_x = (w3dcgb_u8)left;
                    w3dcgb_mask_span_max_x = (w3dcgb_u8)right;
                    w3dcgb_mask_set_span_asm();
                }
            }
        }
        i = (w3dcgb_u8)(i + 1);
    }
}
Wire3DCGB_MarkTriangle2D

Enregistre un triangle comme zone pouvant masquer les lignes tracées ensuite.

Syntaxe

c
void Wire3DCGB_MarkTriangle2D(w3dcgb_u8 ax, w3dcgb_u8 ay, w3dcgb_u8 bx, w3dcgb_u8 by, w3dcgb_u8 cx, w3dcgb_u8 cy);

Paramètres

ax

Coordonnée X du sommet A en pixels du viewport.

ay

Coordonnée Y du sommet A en pixels du viewport.

bx

Coordonnée X du sommet B en pixels du viewport.

by

Coordonnée Y du sommet B en pixels du viewport.

cx

Coordonnée X du sommet C en pixels du viewport.

cy

Coordonnée Y du sommet C en pixels du viewport.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Marque un triangle en coordonnées écran sans dessiner de pixels ni activer l’occlusion. Les sommets doivent se trouver dans le viewport choisi. L’ASM utilisé ajoute une marge d’un pixel en X, limitée à 0..127 en mode 128×96 ou 0..159 en mode 160×144. Cette fonction ne découpe pas des triangles arbitrairement hors limites.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Red/blue scanlines stop inside masks; green outlines identify the triangle.
#include "wire_cgb_example.h"
__prg_rom u8 silhouette[5]={0x73,0x74,0xFF,0x75,0x73};
void main() {
    u8 y;
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    // Clearing this first test mask must leave the upper-left scanline intact.
    Wire3DCGB_MarkTriangle2D(8,8,16,8,8,16);
    Wire3DCGB_ClearOcclusionMask();
    Wire3DCGB_MarkTriangle2D(32,16,64,16,32,48);
    Wire3DCGB_MarkPackedSilhouette2D(silhouette,5,-2,104,32);
    Wire3DCGB_SetOcclusionActive(1);
    for(y=8;y<=56;y=y+4) Wire3DCGB_DrawLine2DColor(8,y,88,y,1);
    for(y=28;y<=36;y++) Wire3DCGB_DrawLine2DColor(92,y,120,y,2);
    Wire3DCGB_SetOcclusionActive(0);
    Wire3DCGB_DrawLine2DColor(32,16,64,16,3);
    Wire3DCGB_DrawLine2DColor(64,16,32,48,3);
    Wire3DCGB_DrawLine2DColor(32,48,32,16,3);
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Un triangle masque le milieu des lignes de balayage rouges ; une silhouette compactée masque les lignes bleues. Les contours verts situent la région occultante.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_mask.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_mask.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:150

kitaqgb/lib/wire3d_cgb.c:1980

c
void Wire3DCGB_MarkTriangle2D(w3dcgb_u8 ax, w3dcgb_u8 ay, w3dcgb_u8 bx, w3dcgb_u8 by, w3dcgb_u8 cx, w3dcgb_u8 cy)
{
    w3dcgb_mark_triangle(ax, ay, bx, by, cx, cy);
}
Wire3DCGB_ProjectAxis48

Approxime un décalage projeté avec une focale de 48.

Syntaxe

c
w3dcgb_i16 Wire3DCGB_ProjectAxis48(w3dcgb_i16 value, w3dcgb_i16 z);

Paramètres

value

Composante signée sur 16 bits à projeter.

z

Profondeur utilisée pour choisir la taille ou calculer la projection.

Valeur renvoyée

Décalage projeté approximatif, signé sur 16 bits.

Conditions et limites

Approxime value*48/z sans caméra ni décalage du centre d’écran. Un Z négatif ou très petit devient 4. Au-delà de 255, décale ensemble profondeur et magnitude vers la droite jusqu’à ce que la profondeur tienne dans un octet, puis plafonne la magnitude à 160. Renvoie un décalage signé ; cet auxiliaire ne rejette pas les profondeurs proches ou lointaines.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Preprojected edge arrays, a clipped square, a tiny marker and a projectile.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Edge edges[4]={{0,1},{1,2},{2,3},{3,0}};
__prg_rom s8 vx8[4]={-8,8,8,-8};
__prg_rom s8 vy8[4]={-8,-8,8,8};
__prg_rom s16 vx16[4]={-12,12,12,-12};
__prg_rom s16 vy16[4]={-8,-8,8,8};
__prg_rom u8 mask[1]={5};
Wire3DCGB_Model shape;
void main() {
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    shape.vertices=0;shape.edges=edges;shape.faces=0;shape.edge_faces=0;
    shape.vertex_count=4;shape.edge_count=4;shape.face_count=0;shape.flags=0;
    Wire3DCGB_SetLineColor(2);
    Wire3DCGB_DrawMaskedModel2D(&shape,vx8,vy8,mask,24,24,1);
    Wire3DCGB_DrawEdgeList2D(edges,4,vx8,vy8,64,24,2);
    Wire3DCGB_DrawEdgeListClipped2D(edges,4,vx16,vy16,4,4,64,3);
    Wire3DCGB_DrawTinyModel2D(104,24,16,3);
    result[0]=Wire3DCGB_ProjectAxis48(48,96);
    result[1]=Wire3DCGB_ProjectAxis48(-48,96);
    Wire3DCGB_DrawFastProjectile(96,64,64,0,1);
    result[2]=Wire3DCGB_GetLineColor();
    Wire3DCGB_EndFrame();result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Deux arêtes horizontales rouges, un carré bleu, un cadre vert découpé, un repère vert de six pixels et un projectile rouge permettent de comparer les formats de listes.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_lists.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_lists.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:141

kitaqgb/lib/wire3d_cgb.c:9702

c
w3dcgb_i16 Wire3DCGB_ProjectAxis48(w3dcgb_i16 value, w3dcgb_i16 z)
{
    w3dcgb_projection_value = value;
    w3dcgb_projection_z = z;
    w3dcgb_project_axis48_asm();
    return w3dcgb_projection_result;
}
Wire3DCGB_ProjectPoint

Projette un point du monde par la caméra vers le viewport de 128×96.

Syntaxe

c
w3dcgb_u8 Wire3DCGB_ProjectPoint(w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_u8* sx, w3dcgb_u8* sy);

Paramètres

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

sx

Pointeur u8 valide et accessible en écriture recevant la coordonnée X projetée.

sy

Pointeur u8 valide et accessible en écriture recevant la coordonnée Y projetée.

Valeur renvoyée

Renvoie 1 si la projection réussit, 0 si la profondeur est rejetée.

Conditions et limites

Projette un point du monde par la caméra courante vers le viewport de 128×96. Renvoie zéro en cas de rejet de profondeur sans modifier les sorties ; sinon, écrit des coordonnées sur octets bornées au viewport. Des pointeurs valides et accessibles en écriture sont requis. Ce n’est pas le projecteur plein écran de 160×144. Absent des builds MINIMAL_RUNTIME.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Four cubes compare unity/half scale and persistent/temporary line colors.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Vec3 vertices[8]={
    {-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},
    {-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}
};
__prg_rom Wire3DCGB_Edge edges[12]={
    {0,1},{1,2},{2,3},{3,0},{4,5},{5,6},
    {6,7},{7,4},{0,4},{1,5},{2,6},{3,7}
};
Wire3DCGB_Model cube;
u8 sx;
u8 sy;
void main() {
    wire_results_clear();
    cube.vertices=vertices; cube.edges=edges;
    cube.faces=0; cube.edge_faces=0;
    cube.vertex_count=8; cube.edge_count=12; cube.face_count=0; cube.flags=0;
    Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DCGB_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    Wire3DCGB_DrawModelColor(&cube,-32,-32,96,0,0,0,2);
    Wire3DCGB_DrawModelScaledColor(&cube,32,-32,96,0,0,0,128,3);
    result[0]=Wire3DCGB_GetLineColor();
    Wire3DCGB_DrawLine3D(0,56,96,0,-56,96);
    Wire3DCGB_DrawLine3DColor(-80,0,96,80,0,96,3);
    result[1]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[2]=sx; result[3]=sy;
    // Camera setters affect future projection, leaving the staged cubes intact.
    Wire3DCGB_SetCamera(0,0,0,0,4,0);
    result[4]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[5]=Wire3DCGB_ProjectPointNoRotation(0,0,96,&sx,&sy);
    result[6]=sx;
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Compare les modèles à l’échelle unitaire et redimensionnés en rouge, bleu et vert, ainsi que des lignes 3D qui se croisent. Les valeurs en RAM vérifient aussi la projection de caméra et sa variante sans rotation.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_models.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:169

kitaqgb/lib/wire3d_cgb.c:589

c
w3dcgb_u8 Wire3DCGB_ProjectPoint(w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_u8* sx, w3dcgb_u8* sy)
{
    return w3dcgb_project_world(x, y, z, sx, sy);
}
Wire3DCGB_ProjectPointNoRotation

Projette un point après soustraction de la position de caméra, sans rotation de caméra.

Syntaxe

c
w3dcgb_u8 Wire3DCGB_ProjectPointNoRotation(w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_u8* sx, w3dcgb_u8* sy);

Paramètres

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

sx

Pointeur u8 valide et accessible en écriture recevant la coordonnée X projetée.

sy

Pointeur u8 valide et accessible en écriture recevant la coordonnée Y projetée.

Valeur renvoyée

Renvoie 1 si la projection réussit, 0 si la profondeur est rejetée.

Conditions et limites

Chemin rapide pour les jeux dont le tangage, le lacet et le roulis de caméra restent nuls. Soustrait la position de caméra et projette vers 128×96 en ignorant tous ses angles. À utiliser lorsque les trois angles sont nuls. Rejette une profondeur invalide sans modifier les valeurs pointées en sortie ; les coordonnées réussies sont bornées au viewport. Absent des builds MINIMAL_RUNTIME.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Four cubes compare unity/half scale and persistent/temporary line colors.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Vec3 vertices[8]={
    {-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},
    {-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}
};
__prg_rom Wire3DCGB_Edge edges[12]={
    {0,1},{1,2},{2,3},{3,0},{4,5},{5,6},
    {6,7},{7,4},{0,4},{1,5},{2,6},{3,7}
};
Wire3DCGB_Model cube;
u8 sx;
u8 sy;
void main() {
    wire_results_clear();
    cube.vertices=vertices; cube.edges=edges;
    cube.faces=0; cube.edge_faces=0;
    cube.vertex_count=8; cube.edge_count=12; cube.face_count=0; cube.flags=0;
    Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DCGB_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    Wire3DCGB_DrawModelColor(&cube,-32,-32,96,0,0,0,2);
    Wire3DCGB_DrawModelScaledColor(&cube,32,-32,96,0,0,0,128,3);
    result[0]=Wire3DCGB_GetLineColor();
    Wire3DCGB_DrawLine3D(0,56,96,0,-56,96);
    Wire3DCGB_DrawLine3DColor(-80,0,96,80,0,96,3);
    result[1]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[2]=sx; result[3]=sy;
    // Camera setters affect future projection, leaving the staged cubes intact.
    Wire3DCGB_SetCamera(0,0,0,0,4,0);
    result[4]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[5]=Wire3DCGB_ProjectPointNoRotation(0,0,96,&sx,&sy);
    result[6]=sx;
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Compare les modèles à l’échelle unitaire et redimensionnés en rouge, bleu et vert, ainsi que des lignes 3D qui se croisent. Les valeurs en RAM vérifient aussi la projection de caméra et sa variante sans rotation.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_models.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:171

Notes de déclaration (texte source)
Fast path for games whose camera pitch, yaw, and roll stay at zero.

kitaqgb/lib/wire3d_cgb.c:598

c
w3dcgb_u8 Wire3DCGB_ProjectPointNoRotation(w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z,
                                            w3dcgb_u8* sx, w3dcgb_u8* sy)
{
    return w3dcgb_project_camera_space((w3dcgb_i16)(x - w3dcgb_cam_x),
                                        (w3dcgb_i16)(y - w3dcgb_cam_y),
                                        (w3dcgb_i16)(z - w3dcgb_cam_z), sx, sy);
}
Wire3DCGB_PutBgTile

Met en file un changement de numéro de tuile du fond pour EndFrame.

Syntaxe

c
void Wire3DCGB_PutBgTile(w3dcgb_u8 x, w3dcgb_u8 y, w3dcgb_u8 tile);

Paramètres

x

Coordonnée X en tuiles dans la carte de fond de 32×32.

y

Coordonnée Y en tuiles dans la carte de fond de 32×32.

tile

Numéro de tuile sur huit bits pour la case du fond.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Met en file une écriture de numéro de tuile pour une carte BG de 32×32. Ignore les coordonnées invalides et les soumissions au-delà de 48 écritures en attente. EndFrame vide cette file privée ; le mode atomic-map réplique les écritures sur les deux cartes BG. Les attributs ne sont pas mis en file.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:188

kitaqgb/lib/wire3d_cgb.c:1067

c
void Wire3DCGB_PutBgTile(w3dcgb_u8 x, w3dcgb_u8 y, w3dcgb_u8 tile)
{
    if (x >= 32) return;
    if (y >= 32) return;
    if (w3dcgb_bgq_count >= W3DCGB_BG_QUEUE_LIMIT) return;
    w3dcgb_bgq_x[(__safe_index w3dcgb_u8)w3dcgb_bgq_count] = x;
    w3dcgb_bgq_y[(__safe_index w3dcgb_u8)w3dcgb_bgq_count] = y;
    w3dcgb_bgq_tile[(__safe_index w3dcgb_u8)w3dcgb_bgq_count] = tile;
    w3dcgb_bgq_count = (w3dcgb_u8)(w3dcgb_bgq_count + 1);
}
WIRE3DCGB_RGB15

Regroupe les canaux rouge, vert et bleu sur cinq bits en une couleur CGB de 15 bits.

Syntaxe

c
#define WIRE3DCGB_RGB15(r5, g5, b5) ((w3dcgb_u16)((w3dcgb_u16)((r5) & 31) | ((w3dcgb_u16)((g5) & 31) << 5) | ((w3dcgb_u16)((b5) & 31) << 10)))

Paramètres

r5

Canal rouge, 0..31.

g5

Canal vert, 0..31.

b5

Canal bleu, 0..31.

Valeur renvoyée

Valeur RGB15 regroupée dans un u16.

Conditions et limites

Regroupe les cinq bits faibles de chaque canal en RGB15 ; chaque argument est évalué une seule fois.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:50

Wire3DCGB_SetCamera

Mémorise la position et l’orientation de la caméra pour la projection, avec 16 pas angulaires par tour.

Syntaxe

c
void Wire3DCGB_SetCamera(w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 pitch, w3dcgb_i8 yaw, w3dcgb_i8 roll);

Paramètres

x

Composante X de la caméra en coordonnées du monde.

y

Composante Y de la caméra en coordonnées du monde.

z

Composante Z de la caméra en coordonnées du monde.

pitch

Rotation autour de X ; seize pas font un tour complet.

yaw

Rotation autour de Y ; seize pas font un tour complet.

roll

Rotation autour de Z ; seize pas font un tour complet.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Mémorise la position et les angles de la caméra sans changer les pixels existants. Les auxiliaires de rotation utilisent les quatre bits faibles des angles, soit 16 pas par tour. Les décalages d’écran sont des registres LCD distincts, que cet appel ne modifie pas.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Four cubes compare unity/half scale and persistent/temporary line colors.
#include "wire_cgb_example.h"
__prg_rom Wire3DCGB_Vec3 vertices[8]={
    {-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},
    {-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}
};
__prg_rom Wire3DCGB_Edge edges[12]={
    {0,1},{1,2},{2,3},{3,0},{4,5},{5,6},
    {6,7},{7,4},{0,4},{1,5},{2,6},{3,7}
};
Wire3DCGB_Model cube;
u8 sx;
u8 sy;
void main() {
    wire_results_clear();
    cube.vertices=vertices; cube.edges=edges;
    cube.faces=0; cube.edge_faces=0;
    cube.vertex_count=8; cube.edge_count=12; cube.face_count=0; cube.flags=0;
    Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DCGB_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    Wire3DCGB_DrawModelColor(&cube,-32,-32,96,0,0,0,2);
    Wire3DCGB_DrawModelScaledColor(&cube,32,-32,96,0,0,0,128,3);
    result[0]=Wire3DCGB_GetLineColor();
    Wire3DCGB_DrawLine3D(0,56,96,0,-56,96);
    Wire3DCGB_DrawLine3DColor(-80,0,96,80,0,96,3);
    result[1]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[2]=sx; result[3]=sy;
    // Camera setters affect future projection, leaving the staged cubes intact.
    Wire3DCGB_SetCamera(0,0,0,0,4,0);
    result[4]=Wire3DCGB_ProjectPoint(0,0,96,&sx,&sy);
    result[5]=Wire3DCGB_ProjectPointNoRotation(0,0,96,&sx,&sy);
    result[6]=sx;
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Compare les modèles à l’échelle unitaire et redimensionnés en rouge, bleu et vert, ainsi que des lignes 3D qui se croisent. Les valeurs en RAM vérifient aussi la projection de caméra et sa variante sans rotation.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_models.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:127

kitaqgb/lib/wire3d_cgb.c:8266

c
void Wire3DCGB_SetCamera(w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 pitch, w3dcgb_i8 yaw, w3dcgb_i8 roll)
{
    w3dcgb_cam_x = x;
    w3dcgb_cam_y = y;
    w3dcgb_cam_z = z;
    w3dcgb_cam_pitch = pitch;
    w3dcgb_cam_yaw = yaw;
    w3dcgb_cam_roll = roll;
}
Wire3DCGB_SetLineColor

Choisit l’indice de couleur pour les lignes suivantes.

Syntaxe

c
void Wire3DCGB_SetLineColor(w3dcgb_u8 color);

Paramètres

color

Indice de couleur de dessin ; les palettes d’exemple utilisent 1=rouge, 2=bleu et 3=vert.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Stocke color & 3. Utilisez les couleurs de ligne nommées 1..3 : les lignes normales combinent leurs plans de bits par OR, donc les couleurs se combinent aux intersections ; les lignes rapides plein écran remplacent la couleur du pixel. La couleur de ligne zéro est traitée comme 3 et n’efface pas. Le tracé de points en mode normal accepte séparément la couleur zéro pour effacer.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:119

kitaqgb/lib/wire3d_cgb.c:1140

c
void Wire3DCGB_SetLineColor(w3dcgb_u8 color)
{
    w3dcgb_line_color = (w3dcgb_u8)(color & 3);
}
Wire3DCGB_SetOcclusionActive

Active ou désactive le test d’occlusion pour les lignes suivantes.

Syntaxe

c
void Wire3DCGB_SetOcclusionActive(w3dcgb_u8 active);

Paramètres

active

Zéro désactive le test d’occlusion ; toute autre valeur l’active.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Normalise active à zéro ou un et le mémorise comme interrupteur d’occlusion. N’efface aucun masque et ne marque aucune géométrie.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Red/blue scanlines stop inside masks; green outlines identify the triangle.
#include "wire_cgb_example.h"
__prg_rom u8 silhouette[5]={0x73,0x74,0xFF,0x75,0x73};
void main() {
    u8 y;
    wire_results_clear(); Wire3DCGB_Init(); wire_colors(); Wire3DCGB_BeginFrame();
    // Clearing this first test mask must leave the upper-left scanline intact.
    Wire3DCGB_MarkTriangle2D(8,8,16,8,8,16);
    Wire3DCGB_ClearOcclusionMask();
    Wire3DCGB_MarkTriangle2D(32,16,64,16,32,48);
    Wire3DCGB_MarkPackedSilhouette2D(silhouette,5,-2,104,32);
    Wire3DCGB_SetOcclusionActive(1);
    for(y=8;y<=56;y=y+4) Wire3DCGB_DrawLine2DColor(8,y,88,y,1);
    for(y=28;y<=36;y++) Wire3DCGB_DrawLine2DColor(92,y,120,y,2);
    Wire3DCGB_SetOcclusionActive(0);
    Wire3DCGB_DrawLine2DColor(32,16,64,16,3);
    Wire3DCGB_DrawLine2DColor(64,16,32,48,3);
    Wire3DCGB_DrawLine2DColor(32,48,32,16,3);
    Wire3DCGB_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Un triangle masque le milieu des lignes de balayage rouges ; une silhouette compactée masque les lignes bleues. Les contours verts situent la région occultante.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_mask.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_mask.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:149

kitaqgb/lib/wire3d_cgb.c:1970

c
void Wire3DCGB_SetOcclusionActive(w3dcgb_u8 active)
{
    if (active == 0) w3dcgb_occlusion_active = 0;
    else w3dcgb_occlusion_active = 1;
}
Wire3DCGB_SetPaletteRGB15

Définit les quatre couleurs de dessin et les palettes du fond servant à colorer les motifs.

Syntaxe

c
void Wire3DCGB_SetPaletteRGB15(w3dcgb_u16 color0, w3dcgb_u16 color1, w3dcgb_u16 color2, w3dcgb_u16 color3);

Paramètres

color0

Couleur RGB15 de l’entrée 0 de la palette.

color1

Couleur RGB15 de l’entrée 1 de la palette.

color2

Couleur RGB15 de l’entrée 2 de la palette.

color3

Couleur RGB15 de l’entrée 3 de la palette.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Affecte les quatre couleurs RGB15 fournies à la palette BG 0. Les palettes 1..3 partagent color0 et répètent leur couleur non nulle respective dans les entrées 1..3, ce qui permet de recolorer les tuiles de motifs monochromes par leurs attributs. Appelez dans une période autorisant l’accès aux palettes, généralement pendant la configuration LCD éteint ou le VBlank.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:118

kitaqgb/lib/wire3d_cgb.c:1112

c
void Wire3DCGB_SetPaletteRGB15(w3dcgb_u16 color0, w3dcgb_u16 color1, w3dcgb_u16 color2, w3dcgb_u16 color3)
{
    w3dcgb_write_bg_color(0, color0);
    w3dcgb_write_bg_color(1, color1);
    w3dcgb_write_bg_color(2, color2);
    w3dcgb_write_bg_color(3, color3);

    w3dcgb_write_bg_color(4, color0);
    w3dcgb_write_bg_color(5, color1);
    w3dcgb_write_bg_color(6, color1);
    w3dcgb_write_bg_color(7, color1);

    w3dcgb_write_bg_color(8, color0);
    w3dcgb_write_bg_color(9, color2);
    w3dcgb_write_bg_color(10, color2);
    w3dcgb_write_bg_color(11, color2);

    w3dcgb_write_bg_color(12, color0);
    w3dcgb_write_bg_color(13, color3);
    w3dcgb_write_bg_color(14, color3);
    w3dcgb_write_bg_color(15, color3);
}
Wire3DCGB_SetScreenOffset

Règle directement les registres de défilement LCD SCX et SCY.

Syntaxe

c
void Wire3DCGB_SetScreenOffset(w3dcgb_u8 scx, w3dcgb_u8 scy);

Paramètres

scx

Décalage de défilement en pixels écrit dans SCX.

scy

Décalage de défilement en pixels écrit dans SCY.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

Écrit immédiatement SCX/SCY, sans attendre le VBlank ni modifier les coordonnées projetées. L’appelant choisit quand un changement visible du défilement est acceptable.

CGB uniquement. La préparation normale réserve D300..DEFF dans la banque WRAM 2. L’état partagé rend ces routines non réentrantes ; ne les rappelez pas récursivement depuis une interruption. Les exemples utilisent une pile fixe et le runtime complet.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// CGB raster paths: a red frame, blue diagonal, green marker and clipped line.
// Build this source together with lib/wire3d_cgb.c in an MBC5 256 KB CGB ROM.
#include "wire3d_cgb.h"
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4D) u8 sample_key1;
__location(0xC110) u16 result[8];
__prg_rom u8 lower_lines[8]={80,56,112,56,112,56,112,80};

void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DCGB_EnableDoubleSpeed();
    Wire3DCGB_Init(); // Already at double speed: its internal request is a no-op.
    result[2]=(u8)(sample_key1&128);
    // Palette writes are performed with the LCD off, after entering VBlank.
    while(sample_ly>=144) {} while(sample_ly<144) {}
    sample_lcdc=0;
    Wire3DCGB_SetPaletteRGB15(WIRE3DCGB_RGB15(0,0,0),WIRE3DCGB_RGB15(31,0,0),WIRE3DCGB_RGB15(0,0,31),WIRE3DCGB_RGB15(0,31,0));
    sample_lcdc=0x81;
    Wire3DCGB_SetScreenOffset(0,0);
    Wire3DCGB_SetCamera(0,0,0,0,0,0);
    Wire3DCGB_BeginFrame();
    Wire3DCGB_SetLineColor(1);
    Wire3DCGB_DrawLine2D(8,8,56,8);
    Wire3DCGB_DrawLine2D(56,8,56,40);
    Wire3DCGB_DrawLine2D(56,40,8,40);
    Wire3DCGB_DrawLine2D(8,40,8,8);
    Wire3DCGB_DrawLine2DColor(8,40,56,8,2);
    result[0]=Wire3DCGB_GetLineColor(); // Temporary blue restores red.
    Wire3DCGB_SetLineColor(3);
    Wire3DCGB_DrawPoint2D(64,48);
    Wire3DCGB_DrawLineClipped2D(-10,72,140,72,3);
    Wire3DCGB_DrawLineList2DColor(lower_lines,2,2);
    result[1]=Wire3DCGB_GetLineColor(); // The blue line list restores green.
    Wire3DCGB_PutBgTile(18,1,0x80); // Queue the supplied zero glyph outside the viewport.
    Wire3DCGB_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre les lignes, les points, l’effacement et la projection de base dans une seule image. Un cadre rouge contient une diagonale bleue, avec un point et une ligne horizontale verts, un L bleu et un zéro vert en haut à droite.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_cgb_raster.c .\kitaqgb\lib\wire3d_cgb.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_cgb_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_cgb.h:117

kitaqgb/lib/wire3d_cgb.c:1091

c
void Wire3DCGB_SetScreenOffset(w3dcgb_u8 scx, w3dcgb_u8 scy)
{
    w3dcgb_reg_scx = scx;
    w3dcgb_reg_scy = scy;
}

Mesure Wire3D, profils de 88 lignes et horloges indépendantes

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Un transfert complet de 88 lignes lit 1 408 octets sur DMG et 2 816 sur CGB. La réduction est de 26,67 % face aux 120 lignes DMG et de 8,33 % face à 96 lignes ; elle ne prédit pas le gain de fps. DMG conserve des colonnes espacées de 256 octets ; CGB compacte des colonnes de 11 tuiles. CGB réserve toujours 3 072 octets pour rester compatible avec le plein écran.

ProjectCameraPoint projette des coordonnées caméra sans soustraction ni rotation de caméra. Hors de Z=8..255, il renvoie 0 et conserve les sorties. X/Y sont limités à ±120 ; les produits de la table inverse de profondeur sont divisés par 32 avec arrondi signé vers le bas, puis bornés à l’écran. Ce n’est pas un découpage géométrique des lignes. Le ProjectPoint générique CGB conserve les limites de rotation ±220, même aux angles nuls.

EndFrameNow sur DMG supprime seulement l’attente initiale d’un nouveau VBlank ; il traite la file BG, les modes de transfert et l’historique dirty. EndFrameSparseNow sur CGB reste synchrone. Now attend encore les accès STAT, la fin du DMA et une présentation sûre. Les mises à jour DMG ne sont pas atomiques. L’effacement sparse CGB couvre la zone actuelle et celle présente dans la banque cible deux images auparavant. Les lignes CGB de bas niveau exigent un marquage dirty.

Au démarrage sparse CGB, la première utilisation de chaque banque cible (les deux premières images) actualise tout le viewport et efface les tuiles d’initialisation. Cette charge est incluse dans les mesures. DrawLine2D ne déclare pas de zone sparse : utilisez DrawLineClipped2D ou MarkDirtyRect2D explicitement.

Les exemples emploient une boîte mobile, une jauge et un BGM de quatre notes créés indépendamment. Le mouvement utilise les ticks écoulés d’audio_vblank ; un bref traitement VBlank sûr actualise la jauge. N’appelez jamais le moteur à état partagé depuis une ISR. wire3d_audio_vblank.c place la file de 80 octets en WRAM fixe et les fonctions de contrôle dans la banque ROM 5. Ne compilez pas aussi audio_vblank.c. Les exemples CGB utilisent WIRE3DCGB_STAGE_BANK2_ALLOCATION. Lisez la différence de ticks sur 8 bits avant 255 images.

L’outil compte les marqueurs après transfert et présentation terminés. Il mesure en dots PPU (4 194 304/s ; 70 224/image) l’effacement, la projection, la rastérisation, le transfert avec présentation et les attentes externes. Il donne moyenne, médiane, intervalle maximal et échéances dépassées. Le transfert avec présentation inclut les attentes internes STAT/DMA/VBlank. Ne comparez pas directement les cycles CPU CGB à double vitesse et DMG. Une même moyenne de fps ne prouve pas le respect de chaque échéance. Matériel réel non vérifié.

Sept configurations originales ont effectué 48 transferts chacune : 336 comparaisons stage/VRAM et 84 images vides pour vérifier l’effacement. Cinq profils ont réussi 25 700 cas limites de projection. Cinq builds Rust ont aussi terminé 48 images avec BGM non nul. Certains intervalles dépassent quatre images PPU : la moyenne des fps ne prouve pas l’absence de ralentissement. Vérification par émulateur, sans validation matérielle.

KOKURA a exécuté chaque exemple original DMG/CGB sur 400 images ; analyse SARAKURA et validation stricte réussies. Chacun conserve zéro erreur, un avertissement PC répété dans la boucle d’attente et trois observations, dont le risque de clic DAC/mixeur. Cela ne valide ni la fidélité sonore ni le matériel.

Les exemples, images et preuves publiés utilisent uniquement des formes, jauges et motifs sonores créés indépendamment. Aucun ROM commercial, code extrait, géométrie, écran, musique ou sauvegarde d’état d’un jeu commercial n’est inclus.

Résultats de vérification et exemples · C / BGM / HUD

ProfilfpsMédiane / maximum (images PPU)Dépassements / 47
clocked_dmg_88_sparse13.8524.449 / 4.73235
clocked_dmg_96_sparse13.1864.669 / 4.89139
clocked_dmg_120_sparse13.4344.453 / 7.17635
clocked_cgb_88_sparse15.0124.000 / 5.00028
clocked_cgb_96_sparse15.0924.000 / 5.00026
clocked_cgb_88_full12.5325.000 / 6.00041
clocked_cgb_96_full12.5885.000 / 5.02041
Original DMG box and bar gauge
DMG 128×88 · Les exemples, images et preuves publiés utilisent uniquement des formes, jauges et motifs sonores créés indépendamment. Aucun ROM commercial, code extrait, géométrie, écran, musique ou sauvegarde d’état d’un jeu commercial n’est inclus.
Original CGB box and bar gauge
CGB 128×88 · Les exemples, images et preuves publiés utilisent uniquement des formes, jauges et motifs sonores créés indépendamment. Aucun ROM commercial, code extrait, géométrie, écran, musique ou sauvegarde d’état d’un jeu commercial n’est inclus.
Wire3DDMG_ProjectCameraPoint

ProjectCameraPoint projette des coordonnées caméra sans soustraction ni rotation de caméra. Hors de Z=8..255, il renvoie 0 et conserve les sorties. X/Y sont limités à ±120 ; les produits de la table inverse de profondeur sont divisés par 32 avec arrondi signé vers le bas, puis bornés à l’écran. Ce n’est pas un découpage géométrique des lignes. Le ProjectPoint générique CGB conserve les limites de rotation ±220, même aux angles nuls.

Syntaxe

c
w3ddmg_u8 Wire3DDMG_ProjectCameraPoint(w3ddmg_i16 x,w3ddmg_i16 y,w3ddmg_i16 z,w3ddmg_u8* sx,w3ddmg_u8* sy);

Paramètres

x

X/Y/Z caméra signés sur 16 bits. sx et sy doivent être des pointeurs u8 valides et modifiables.

y

X/Y/Z caméra signés sur 16 bits. sx et sy doivent être des pointeurs u8 valides et modifiables.

z

X/Y/Z caméra signés sur 16 bits. sx et sy doivent être des pointeurs u8 valides et modifiables.

sx

X/Y/Z caméra signés sur 16 bits. sx et sy doivent être des pointeurs u8 valides et modifiables.

sy

X/Y/Z caméra signés sur 16 bits. sx et sy doivent être des pointeurs u8 valides et modifiables.

Valeur renvoyée

Renvoie 1 si la projection réussit, 0 si la profondeur est rejetée. Un rejet conserve sx et sy.

Conditions et limites

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Les exemples emploient une boîte mobile, une jauge et un BGM de quatre notes créés indépendamment. Le mouvement utilise les ticks écoulés d’audio_vblank ; un bref traitement VBlank sûr actualise la jauge. N’appelez jamais le moteur à état partagé depuis une ISR. wire3d_audio_vblank.c place la file de 80 octets en WRAM fixe et les fonctions de contrôle dans la banque ROM 5. Ne compilez pas aussi audio_vblank.c. Les exemples CGB utilisent WIRE3DCGB_STAGE_BANK2_ALLOCATION. Lisez la différence de ticks sur 8 bits avant 255 images.

L’outil compte les marqueurs après transfert et présentation terminés. Il mesure en dots PPU (4 194 304/s ; 70 224/image) l’effacement, la projection, la rastérisation, le transfert avec présentation et les attentes externes. Il donne moyenne, médiane, intervalle maximal et échéances dépassées. Le transfert avec présentation inclut les attentes internes STAT/DMA/VBlank. Ne comparez pas directement les cycles CPU CGB à double vitesse et DMG. Une même moyenne de fps ne prouve pas le respect de chaque échéance. Matériel réel non vérifié.

Exemple d’utilisation

c
#define WIRE3D_DMG_HEIGHT 88
#include "wire3d_dmg.h"
void project_one() {
    u8 sx; u8 sy;
    if (Wire3DDMG_ProjectCameraPoint(-24, 20, 96, &sx, &sy)) {
        // Use the projected coordinates in a main-thread drawing routine.
    }
}

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Sept configurations originales ont effectué 48 transferts chacune : 336 comparaisons stage/VRAM et 84 images vides pour vérifier l’effacement. Cinq profils ont réussi 25 700 cas limites de projection. Cinq builds Rust ont aussi terminé 48 images avec BGM non nul. Certains intervalles dépassent quatre images PPU : la moyenne des fps ne prouve pas l’absence de ralentissement. Vérification par émulateur, sans validation matérielle.

Programme d’exemple complet

renderer_dmg_88.c

hardware.c

audio_glue.c

README.md

Implémentation et source

kitaqgb/lib/wire3d_dmg.h:146

Notes de déclaration (texte source)
Validate depth and project coordinates already in camera space.

kitaqgb/lib/wire3d_dmg.c:720

c
w3ddmg_u8 Wire3DDMG_ProjectCameraPoint(w3ddmg_i16 x,w3ddmg_i16 y,w3ddmg_i16 z,w3ddmg_u8* sx,w3ddmg_u8* sy)
{
 return w3ddmg_project_camera_space(x,y,z,sx,sy);
}
Wire3DCGB_ProjectCameraPoint

ProjectCameraPoint projette des coordonnées caméra sans soustraction ni rotation de caméra. Hors de Z=8..255, il renvoie 0 et conserve les sorties. X/Y sont limités à ±120 ; les produits de la table inverse de profondeur sont divisés par 32 avec arrondi signé vers le bas, puis bornés à l’écran. Ce n’est pas un découpage géométrique des lignes. Le ProjectPoint générique CGB conserve les limites de rotation ±220, même aux angles nuls.

Syntaxe

c
w3dcgb_u8 Wire3DCGB_ProjectCameraPoint(w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_u8* sx, w3dcgb_u8* sy);

Paramètres

x

X/Y/Z caméra signés sur 16 bits. sx et sy doivent être des pointeurs u8 valides et modifiables.

y

X/Y/Z caméra signés sur 16 bits. sx et sy doivent être des pointeurs u8 valides et modifiables.

z

X/Y/Z caméra signés sur 16 bits. sx et sy doivent être des pointeurs u8 valides et modifiables.

sx

X/Y/Z caméra signés sur 16 bits. sx et sy doivent être des pointeurs u8 valides et modifiables.

sy

X/Y/Z caméra signés sur 16 bits. sx et sy doivent être des pointeurs u8 valides et modifiables.

Valeur renvoyée

Renvoie 1 si la projection réussit, 0 si la profondeur est rejetée. Un rejet conserve sx et sy.

Conditions et limites

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Les exemples emploient une boîte mobile, une jauge et un BGM de quatre notes créés indépendamment. Le mouvement utilise les ticks écoulés d’audio_vblank ; un bref traitement VBlank sûr actualise la jauge. N’appelez jamais le moteur à état partagé depuis une ISR. wire3d_audio_vblank.c place la file de 80 octets en WRAM fixe et les fonctions de contrôle dans la banque ROM 5. Ne compilez pas aussi audio_vblank.c. Les exemples CGB utilisent WIRE3DCGB_STAGE_BANK2_ALLOCATION. Lisez la différence de ticks sur 8 bits avant 255 images.

L’outil compte les marqueurs après transfert et présentation terminés. Il mesure en dots PPU (4 194 304/s ; 70 224/image) l’effacement, la projection, la rastérisation, le transfert avec présentation et les attentes externes. Il donne moyenne, médiane, intervalle maximal et échéances dépassées. Le transfert avec présentation inclut les attentes internes STAT/DMA/VBlank. Ne comparez pas directement les cycles CPU CGB à double vitesse et DMG. Une même moyenne de fps ne prouve pas le respect de chaque échéance. Matériel réel non vérifié.

Exemple d’utilisation

c
#define WIRE3DCGB_HEIGHT 88
#include "wire3d_cgb.h"
void project_one() {
    u8 sx; u8 sy;
    if (Wire3DCGB_ProjectCameraPoint(-24, 20, 96, &sx, &sy)) {
        // Use the projected coordinates in a main-thread drawing routine.
    }
}

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Sept configurations originales ont effectué 48 transferts chacune : 336 comparaisons stage/VRAM et 84 images vides pour vérifier l’effacement. Cinq profils ont réussi 25 700 cas limites de projection. Cinq builds Rust ont aussi terminé 48 images avec BGM non nul. Certains intervalles dépassent quatre images PPU : la moyenne des fps ne prouve pas l’absence de ralentissement. Vérification par émulateur, sans validation matérielle.

Programme d’exemple complet

renderer_cgb_88.c

hardware.c

audio_glue.c

README.md

Implémentation et source

kitaqgb/lib/wire3d_cgb.h:168

Notes de déclaration (texte source)
Project camera-space coordinates without subtracting/rotating the camera.
Depth 8..255; outputs unchanged on rejection. Shared scratch: no ISR calls.

kitaqgb/lib/wire3d_cgb.c:552

c
w3dcgb_u8 Wire3DCGB_ProjectCameraPoint(w3dcgb_i16 x,w3dcgb_i16 y,w3dcgb_i16 z,w3dcgb_u8* sx,w3dcgb_u8* sy)
{
    return w3dcgb_project_camera_space(x,y,z,sx,sy);
}
Wire3DDMG_EndFrameNow

EndFrameNow sur DMG supprime seulement l’attente initiale d’un nouveau VBlank ; il traite la file BG, les modes de transfert et l’historique dirty. EndFrameSparseNow sur CGB reste synchrone. Now attend encore les accès STAT, la fin du DMA et une présentation sûre. Les mises à jour DMG ne sont pas atomiques. L’effacement sparse CGB couvre la zone actuelle et celle présente dans la banque cible deux images auparavant. Les lignes CGB de bas niveau exigent un marquage dirty.

Syntaxe

c
void Wire3DDMG_EndFrameNow();

Valeur renvoyée

Aucune valeur de retour ; revient après transfert et synchronisation nécessaires.

Conditions et limites

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Les exemples emploient une boîte mobile, une jauge et un BGM de quatre notes créés indépendamment. Le mouvement utilise les ticks écoulés d’audio_vblank ; un bref traitement VBlank sûr actualise la jauge. N’appelez jamais le moteur à état partagé depuis une ISR. wire3d_audio_vblank.c place la file de 80 octets en WRAM fixe et les fonctions de contrôle dans la banque ROM 5. Ne compilez pas aussi audio_vblank.c. Les exemples CGB utilisent WIRE3DCGB_STAGE_BANK2_ALLOCATION. Lisez la différence de ticks sur 8 bits avant 255 images.

L’outil compte les marqueurs après transfert et présentation terminés. Il mesure en dots PPU (4 194 304/s ; 70 224/image) l’effacement, la projection, la rastérisation, le transfert avec présentation et les attentes externes. Il donne moyenne, médiane, intervalle maximal et échéances dépassées. Le transfert avec présentation inclut les attentes internes STAT/DMA/VBlank. Ne comparez pas directement les cycles CPU CGB à double vitesse et DMG. Une même moyenne de fps ne prouve pas le respect de chaque échéance. Matériel réel non vérifié.

Exemple d’utilisation

c
#define WIRE3D_DMG_HEIGHT 88
#include "wire3d_dmg.h"
void draw_one() {
    Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawLine2D(8,8,32,32);
    Wire3DDMG_PutBgTile(18,16,128);
    Wire3DDMG_EndFrameNow();
}

Cet extrait montre l’appel. Avant de l’intégrer à un programme complet, respectez les conditions d’initialisation et de dimensionnement des tampons indiquées.

Résultat attendu

Sept configurations originales ont effectué 48 transferts chacune : 336 comparaisons stage/VRAM et 84 images vides pour vérifier l’effacement. Cinq profils ont réussi 25 700 cas limites de projection. Cinq builds Rust ont aussi terminé 48 images avec BGM non nul. Certains intervalles dépassent quatre images PPU : la moyenne des fps ne prouve pas l’absence de ralentissement. Vérification par émulateur, sans validation matérielle.

Programme d’exemple complet

renderer_dmg_88.c

hardware.c

audio_glue.c

README.md

Implémentation et source

kitaqgb/lib/wire3d_dmg.h:289

Notes de déclaration (texte source)
Same queue/gate/history lifecycle, without the initial fresh-VBlank wait.
Synchronous STAT-safe upload; not an atomic swap. LCD must remain enabled.

kitaqgb/lib/wire3d_dmg.c:3826

c
void Wire3DDMG_EndFrameNow()
{
    w3ddmg_flush_bg_queue();



    if (w3ddmg_aux_transfer_enabled)
    {
        w3ddmg_transfer_stage_aux_asm();
    }
    if (w3ddmg_dirty_transfer_enabled)
    {
        w3ddmg_transfer_dirty_stage();
    }
    else
    {
        w3ddmg_transfer_stage_asm();
    }

}

wire3d_dmg.h — Rendu filaire pour DMG

Utilisation des chemins de rendu rapide

Pour les lignes dans la zone de rendu, l’adresse de dessin et le bit du pixel avancent progressivement ; le nombre de pixels restant et l’erreur restent dans les registres CPU. Cela évite de recalculer les coordonnées de tuile pour chaque pixel et ajoute des pixels de liaison pour raccorder les diagonales. Avec l’occlusion, cinq points de la ligne déterminent si elle doit être dessinée ; les lignes retenues empruntent le même chemin rapide. Les lignes du masque sont remplies octet par octet en préservant les bits partiels aux bords. Les rectangles englobant les faces et le rejet sur cinq points sont des approximations, pas une occlusion exacte des triangles ou lignes pixel par pixel. Les rotations de 0, 90, 180 et 270 degrés bornent les entrées, puis échangent les coordonnées et changent les signes. Les performances du jeu dépendent aussi du nombre de sommets, de la longueur des arêtes, de l’occlusion et des transferts VRAM. Mesurez séparément chaque opération et le temps nécessaire pour achever une image affichée.

Dessin de lignes 3D monochromes. Fournissez sommets, arêtes et faces du modèle, ainsi que position, rotation et échelle de l’objet. Suivez l’ordre initialisation, début d’image, dessin, transfert. La physique est séparée. Les angles ont seize pas par tour ; l’échelle de modèle 256 vaut l’unité.

Vec3 contient x/y/z, Edge les indices de sommets a/b, et Face les indices de triangle a/b/c. Les champs vertices, edges et faces de Model pointent vers ces tableaux ; chaque compteur en donne la longueur. edge_faces contient les indices des faces adjacentes f0/f1, avec FACE_NONE pour une face absente. MODEL_HIDDEN_LINES dans flags demande une sélection d’arêtes fondée sur les faces. L’aire projetée signée détermine l’orientation d’une face : l’ordre des sommets compte.

Object mémorise une référence au modèle, la position x/y/z, les angles rx/ry/rz, scale_q8 et visible. Les objets peuvent partager un modèle, mais le dessin ne copie pas les tables et ne change pas automatiquement leurs banques ROM. Gardez les données référencées lisibles pendant tout le dessin. L’Object CGB possède aussi un indice de couleur.

Le Model de hauteur 96 contient aussi edge_masks et edge_mask_count. Fournissez une table RAM de masques d’arêtes sur 16 bits sélectionnés selon le lacet de l’objet, ou mettez les deux champs à zéro si inutilisés.

Wire3DDMG_BeginFrame

Commence le dessin d’une image et désactive le test d’occlusion.

Syntaxe

c
void Wire3DDMG_BeginFrame();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_BeginFrame(); Efface les pixels préparés et le masque d’occlusion, puis désactive le filtrage d’occlusion. L’image VRAM affichée et la file de tuiles BG en attente restent inchangées. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_BeginFrame(); Désactive uniquement le filtrage d’occlusion. La zone de préparation est normalement effacée pendant le transfert ; Init fournit la première zone vierge. Ne supprime pas une image non soumise, n’efface pas le masque et ne réinitialise ni écritures BG en attente ni indicateurs de modification.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3DDMG_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3DDMG_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3DDMG_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3DDMG_SetCamera(0,0,0,0,0,0);
    Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawLine2D(8,8,56,8);
    Wire3DDMG_DrawLine2D(56,8,56,40);
    Wire3DDMG_DrawLine2D(56,40,8,40);
    Wire3DDMG_DrawLine2D(8,40,8,8);
    Wire3DDMG_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3DDMG_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3DDMG_PutBgTile(1,1,160);
    Wire3DDMG_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_raster.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:144

Notes de déclaration (texte source)
Disable occlusion filtering only. Stage clearing normally happens during
transfer, and Init supplies the first clean stage. This does not discard an
unsubmitted frame, clear the mask, or reset pending BG writes/dirty flags.

kitaqgb/lib/wire3d_dmg.c:3379

c
void Wire3DDMG_BeginFrame()
{




    /* The consuming stage transfer clears D000 as it uploads, so BeginFrame only
       resets draw state. Wire3DDMG_Init supplies the first clean buffer. */

    w3ddmg_occlusion_active = 0;
}
Wire3DDMG_DrawIndexedEdges

Dessine un modèle de lignes à échelle entière à partir de sommets et de paires d’indices d’arêtes sur deux octets.

Syntaxe

c
void Wire3DDMG_DrawIndexedEdges(const Wire3DDMG_Vec3* vertices, w3ddmg_u8 vertex_count, const w3ddmg_u8* edges, w3ddmg_u8 edge_count, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 scale);

Paramètres

vertices

Tableau de sommets 3D.

vertex_count

Nombre d’entrées du tableau de sommets.

edges

Indices des sommets de chaque arête, dans le format déclaré de structure ou de paire d’octets.

edge_count

Nombre d’arêtes.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

scale

Échelle entière ; zéro est traité comme un.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_DrawIndexedEdges(const Wire3DDMG_Vec3* vertices, w3ddmg_u8 vertex_count, const w3ddmg_u8* edges, w3ddmg_u8 edge_count, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 scale); Trace les arêtes indexées par paires d’octets après mise à l’échelle entière et translation ; l’échelle zéro signifie un, sans rotation d’objet ni filtrage de faces. Projette au plus 24 sommets. Fournissez au plus 128 paires d’arêtes, car les décalages sur octets bouclent après 255. Ignore les ID de sommets invalides, les extrémités rejetées en profondeur et les tableaux null. Produits et sommes de coordonnées doivent tenir dans s16.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Upload a main line and an auxiliary block separately; verify source consumption.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3DDMG_Vec3 vertices[2]={{-32,0,0},{32,0,0}};
__prg_rom u8 edge_pairs[2]={0,1};
u8* stage_byte;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawIndexedEdges(vertices,2,edge_pairs,1,-64,104,96,1);
    Wire3DDMG_TransferMainNow();
    // Direct auxiliary transfer writes a separate tile after the main upload.
    for(i=24;i<=31;i++) Wire3DDMG_DrawLine2D(40,i,47,i);
    stage_byte=(u8*)0xD518;result[1]=*stage_byte;
    Wire3DDMG_TransferAuxNow();result[2]=*stage_byte;

    // Do not upload the consumed stage again.
    result[7]=0xA55A; while(1) {}
}

Résultat attendu

Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_direct.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_direct.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:253

Notes de déclaration (texte source)
Draw byte-pair edge indices after integer scaling and translation; scale
zero means one, and there is no object rotation or face filtering. Project at
most 24 vertices. Supply at most 128 edge pairs because byte offsets wrap
after 255. Invalid vertex IDs/depth-rejected endpoints are skipped; null arrays
are ignored. Keep coordinate products/sums representable as s16.

kitaqgb/lib/wire3d_dmg.c:4568

c
void Wire3DDMG_DrawIndexedEdges(const Wire3DDMG_Vec3* vertices, w3ddmg_u8 vertex_count, const w3ddmg_u8* edges, w3ddmg_u8 edge_count, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 scale)
{
    w3ddmg_u8 i;
    w3ddmg_u8 count;

    if (vertices == 0) return;
    if (edges == 0) return;

    count = vertex_count;
    if (count > WIRE3D_DMG_MODEL_VERTEX_LIMIT) count = WIRE3D_DMG_MODEL_VERTEX_LIMIT;
    if (scale == 0) scale = 1;

    i = 0;
    while (i < count)
    {
        const Wire3DDMG_Vec3* v;
        w3ddmg_i16 vx;
        w3ddmg_i16 vy;
        w3ddmg_i16 vz;
        w3ddmg_u8 sx;
        w3ddmg_u8 sy;

        v = &vertices[(__safe_index w3ddmg_u8)i];
        vx = (w3ddmg_i16)(x + (w3ddmg_i16)(v->x * scale));
        vy = (w3ddmg_i16)(y + (w3ddmg_i16)(v->y * scale));
        vz = (w3ddmg_i16)(z + (w3ddmg_i16)(v->z * scale));

        if (w3ddmg_project_world(vx, vy, vz, &sx, &sy))
        {
            w3ddmg_screen_x[(__safe_index w3ddmg_u8)i] = sx;
            w3ddmg_screen_y[(__safe_index w3ddmg_u8)i] = sy;
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 1;
        }
        else
        {
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 0;
        }

        i = (w3ddmg_u8)(i + 1);
    }

    i = 0;
    while (i < edge_count)
    {
        w3ddmg_u8 a;
        w3ddmg_u8 b;

        a = edges[(__safe_index w3ddmg_u8)((w3ddmg_u8)(i << 1))];
        b = edges[(__safe_index w3ddmg_u8)((w3ddmg_u8)((i << 1) + 1))];
        if ((a < count) && (b < count) &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)a] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)b])
        {
            Wire3DDMG_DrawLine2D(
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)a],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)a],
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)b],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)b]);
        }

        i = (w3ddmg_u8)(i + 1);
    }
}
Wire3DDMG_DrawLine2D

Trace dans la zone de préparation une ligne en coordonnées écran à connexité 4, extrémités incluses.

Syntaxe

c
void Wire3DDMG_DrawLine2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by);

Paramètres

ax

Coordonnée X du sommet A en pixels du viewport.

ay

Coordonnée Y du sommet A en pixels du viewport.

bx

Coordonnée X du sommet B en pixels du viewport.

by

Coordonnée Y du sommet B en pixels du viewport.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_DrawLine2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by); Trace une ligne connexe dans la zone de préparation de 128×96, extrémités incluses. Pendant DrawScene, utilise le rejet d’occlusion grossier à cinq échantillons ; sinon, trace directement. Fournissez des coordonnées du viewport. Seul EndFrame met à jour la VRAM. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_DrawLine2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by); Si le transfert des zones modifiées est actif, marque le rectangle englobant en tuiles, puis trace une ligne connexe préparée. Le dessin de scène peut la rejeter avec cinq échantillons du masque. Fournissez des extrémités dans le viewport 128×120 ; les contrôles de pixels bas niveau ne découpent pas géométriquement le segment.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3DDMG_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3DDMG_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3DDMG_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3DDMG_SetCamera(0,0,0,0,0,0);
    Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawLine2D(8,8,56,8);
    Wire3DDMG_DrawLine2D(56,8,56,40);
    Wire3DDMG_DrawLine2D(56,40,8,40);
    Wire3DDMG_DrawLine2D(8,40,8,8);
    Wire3DDMG_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3DDMG_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3DDMG_PutBgTile(1,1,160);
    Wire3DDMG_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_raster.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:237

Notes de déclaration (texte source)
Mark the bounding tile rectangle when dirty transfer is enabled, then draw
a connected staged line. Scene drawing may reject it using five mask samples.
Supply 128x120 viewport endpoints; low-level pixel bounds checks do not clip
the segment geometrically.

kitaqgb/lib/wire3d_dmg.c:3423

c
void Wire3DDMG_DrawLine2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by)
{

    w3ddmg_mark_line_dirty(ax, ay, bx, by);


    if (w3ddmg_occlusion_active)
    {
        w3ddmg_line_stage_masked_c(ax, ay, bx, by);
        return;
    }

    w3ddmg_line_x0 = ax;
    w3ddmg_line_y0 = ay;
    w3ddmg_line_x1 = bx;
    w3ddmg_line_y1 = by;
    if (ax < 128 && bx < 128 && ay < WIRE3D_DMG_SCREEN_H && by < WIRE3D_DMG_SCREEN_H)
        w3ddmg_line_inside_asm();
    else
        w3ddmg_line_stage_asm();
}
Wire3DDMG_DrawLine3D

Projette deux extrémités du monde et trace une ligne entre elles.

Syntaxe

c
void Wire3DDMG_DrawLine3D(w3ddmg_i16 ax, w3ddmg_i16 ay, w3ddmg_i16 az, w3ddmg_i16 bx, w3ddmg_i16 by, w3ddmg_i16 bz);

Paramètres

ax

Composante X du point de départ en coordonnées du monde.

ay

Composante Y du point de départ en coordonnées du monde.

az

Composante Z du point de départ en coordonnées du monde.

bx

Composante X du point d’arrivée en coordonnées du monde.

by

Composante Y du point d’arrivée en coordonnées du monde.

bz

Composante Z du point d’arrivée en coordonnées du monde.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_DrawLine3D(w3ddmg_i16 ax, w3ddmg_i16 ay, w3ddmg_i16 az, w3ddmg_i16 bx, w3ddmg_i16 by, w3ddmg_i16 bz); Projette les deux extrémités du monde et dessine uniquement si les deux passent la plage de profondeur. Ne calcule pas l’intersection d’un segment traversant avec les plans proche ou lointain ; chaque extrémité projetée est bornée indépendamment aux bords de l’écran. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_DrawLine3D(w3ddmg_i16 ax, w3ddmg_i16 ay, w3ddmg_i16 az, w3ddmg_i16 bx, w3ddmg_i16 by, w3ddmg_i16 bz); Projette les deux extrémités du monde et dessine uniquement si les deux passent la plage de profondeur. Ne calcule pas l’intersection d’un segment traversant avec les plans proche ou lointain ; chaque extrémité projetée est bornée indépendamment aux bords de l’écran.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3DDMG_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3DDMG_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3DDMG_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3DDMG_SetCamera(0,0,0,0,0,0);
    Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawLine2D(8,8,56,8);
    Wire3DDMG_DrawLine2D(56,8,56,40);
    Wire3DDMG_DrawLine2D(56,40,8,40);
    Wire3DDMG_DrawLine2D(8,40,8,8);
    Wire3DDMG_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3DDMG_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3DDMG_PutBgTile(1,1,160);
    Wire3DDMG_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_raster.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:226

Notes de déclaration (texte source)
Project both world endpoints and draw only when both pass the depth range.
Do not intersect a crossing segment with near/far planes; projected endpoints
are independently clamped to the screen edges.

kitaqgb/lib/wire3d_dmg.c:3546

c
void Wire3DDMG_DrawLine3D(w3ddmg_i16 ax, w3ddmg_i16 ay, w3ddmg_i16 az, w3ddmg_i16 bx, w3ddmg_i16 by, w3ddmg_i16 bz)
{
    w3ddmg_u8 sx0;
    w3ddmg_u8 sy0;
    w3ddmg_u8 sx1;
    w3ddmg_u8 sy1;

    if (w3ddmg_project_world(ax, ay, az, &sx0, &sy0) == 0) return;
    if (w3ddmg_project_world(bx, by, bz, &sx1, &sy1) == 0) return;
    Wire3DDMG_DrawLine2D(sx0, sy0, sx1, sy1);
}
Wire3DDMG_DrawModel

Dessine un modèle de sommets et d’arêtes à la position et avec la rotation demandées, à l’échelle unitaire.

Syntaxe

c
void Wire3DDMG_DrawModel(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_DrawModel(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz); Dessine un modèle sans redimensionnement en appelant DrawModelScaled avec l’échelle 256. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_DrawModel(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz); Dessine un modèle sans redimensionnement en appelant DrawModelScaled avec l’échelle 256.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Compare direct model scaling with an object-array scene.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3DDMG_Vec3 vertices[8]={{-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},{-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}};
__prg_rom Wire3DDMG_Edge edges[12]={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
Wire3DDMG_Model cube;
Wire3DDMG_Object objects[2];
s16 px; s16 py; s16 pz;
void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;

    cube.vertices=vertices;cube.edges=edges;cube.faces=0;cube.edge_faces=0;
    cube.vertex_count=8;cube.edge_count=12;cube.face_count=0;cube.flags=0;

    Wire3DDMG_BeginFrame();
    // Upper pair: direct model calls at unity and half scale.
    Wire3DDMG_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DDMG_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    // Lower pair: the caller owns both object records and the model tables.
    for(i=0;i<2;i++) {
        objects[i].model=&cube;objects[i].x=-32+(s16)i*64;
        objects[i].y=-32;objects[i].z=96;
        objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256-(s16)i*128;objects[i].visible=1;
    }
    Wire3DDMG_DrawScene(objects,2);
    // Numeric checks cover the operation supplied by this viewport profile.
    px=16;py=0;pz=0;Wire3DDMG_RotatePoint(&px,&py,&pz,0,4,0);
    result[1]=px; result[2]=py; result[3]=pz;
    Wire3DDMG_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_models.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:164

Notes de déclaration (texte source)
Draw an unscaled model by delegating to DrawModelScaled with scale 256.

kitaqgb/lib/wire3d_dmg.c:3565

c
void Wire3DDMG_DrawModel(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz)

{
    Wire3DDMG_DrawModelScaled(model, x, y, z, rx, ry, rz, 256);
}

kitaqgb/lib/wire3d_dmg.c:3563

c
void Wire3DDMG_DrawModel(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz)



{
    Wire3DDMG_DrawModelScaled(model, x, y, z, rx, ry, rz, 256);
}
Wire3DDMG_DrawModelScaled

Redimensionne un modèle, le tourne dans l’ordre Y/X/Z, translate et projette ses sommets, puis trace ses arêtes.

Syntaxe

c
void Wire3DDMG_DrawModelScaled(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz, w3ddmg_i16 scale_q8);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

scale_q8

Échelle dont l’unité vaut 256 ; les valeurs nulles ou négatives signifient aussi l’unité.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_DrawModelScaled(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz, w3ddmg_i16 scale_q8); Redimensionne au plus 24 sommets, les tourne dans l’ordre Y/X/Z, les translate et les projette ; trace ensuite au plus 16 arêtes filtrées par masques de lacet et, éventuellement, par faces avant. Une échelle non positive devient l’unité (256). Les pointeurs de modèle, sommets ou arêtes nuls sont ignorés ; les tables référencées doivent rester lisibles. Produits d’échelle et translations doivent tenir sur 16 bits signés. Les arêtes traversant une limite de profondeur sont rejetées, pas découpées. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_DrawModelScaled(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz, w3ddmg_i16 scale_q8); Redimensionne au plus 24 sommets, les tourne Y/X/Z, les translate et les projette, puis parcourt les edge_count entrées, compteur sur un octet, avec filtrage facultatif par faces adjacentes. Le tampon de faces est limité à 16 ; les tables d’arêtes doivent contenir toutes les entrées déclarées. Une échelle non positive signifie 256. Les pointeurs de modèle, sommets ou arêtes nuls sont ignorés. Gardez produits et translations sur 16 bits signés ; les arêtes traversant une limite de profondeur sont rejetées.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Compare direct model scaling with an object-array scene.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3DDMG_Vec3 vertices[8]={{-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},{-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}};
__prg_rom Wire3DDMG_Edge edges[12]={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
Wire3DDMG_Model cube;
Wire3DDMG_Object objects[2];
s16 px; s16 py; s16 pz;
void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;

    cube.vertices=vertices;cube.edges=edges;cube.faces=0;cube.edge_faces=0;
    cube.vertex_count=8;cube.edge_count=12;cube.face_count=0;cube.flags=0;

    Wire3DDMG_BeginFrame();
    // Upper pair: direct model calls at unity and half scale.
    Wire3DDMG_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DDMG_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    // Lower pair: the caller owns both object records and the model tables.
    for(i=0;i<2;i++) {
        objects[i].model=&cube;objects[i].x=-32+(s16)i*64;
        objects[i].y=-32;objects[i].z=96;
        objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256-(s16)i*128;objects[i].visible=1;
    }
    Wire3DDMG_DrawScene(objects,2);
    // Numeric checks cover the operation supplied by this viewport profile.
    px=16;py=0;pz=0;Wire3DDMG_RotatePoint(&px,&py,&pz,0,4,0);
    result[1]=px; result[2]=py; result[3]=pz;
    Wire3DDMG_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_models.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:170

Notes de déclaration (texte source)
Scale up to 24 vertices, rotate Y/X/Z, translate and project, then traverse
all edge_count entries (a byte count) with optional adjacent-face filtering.
Face scratch is capped at 16; edge tables must contain all declared entries.
Nonpositive scale means 256. Null model/vertex/edge pointers are ignored.
Keep products/translations in signed 16-bit range; depth-crossing edges are dropped.

kitaqgb/lib/wire3d_dmg.c:3710

c
void Wire3DDMG_DrawModelScaled(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz, w3ddmg_i16 scale_q8)

{
    w3ddmg_u8 i;
    w3ddmg_u8 count;
    w3ddmg_u8 edge_count;
    w3ddmg_u8 face_count;

    if (model == 0) return;
    if (model->vertices == 0) return;
    if (model->edges == 0) return;
    if (scale_q8 <= 0) scale_q8 = 256;

    count = model->vertex_count;
    if (count > WIRE3D_DMG_MODEL_VERTEX_LIMIT) count = WIRE3D_DMG_MODEL_VERTEX_LIMIT;

    i = 0;
    while (i < count)
    {
        const Wire3DDMG_Vec3* v;
        w3ddmg_i16 vx;
        w3ddmg_i16 vy;
        w3ddmg_i16 vz;
        w3ddmg_u8 sx;
        w3ddmg_u8 sy;

        v = &model->vertices[(__safe_index w3ddmg_u8)i];
        vx = (w3ddmg_i16)((v->x * scale_q8) >> 8);
        vy = (w3ddmg_i16)((v->y * scale_q8) >> 8);
        vz = (w3ddmg_i16)((v->z * scale_q8) >> 8);






        w3ddmg_rotate_y(&vx, &vz, ry);
        w3ddmg_rotate_x(&vy, &vz, rx);
        w3ddmg_rotate_z(&vx, &vy, rz);


        vx = (w3ddmg_i16)(vx + x);
        vy = (w3ddmg_i16)(vy + y);
        vz = (w3ddmg_i16)(vz + z);

        if (w3ddmg_project_world(vx, vy, vz, &sx, &sy))
        {
            w3ddmg_screen_x[(__safe_index w3ddmg_u8)i] = sx;
            w3ddmg_screen_y[(__safe_index w3ddmg_u8)i] = sy;
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 1;
        }
        else
        {
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 0;
        }
        i = (w3ddmg_u8)(i + 1);
    }

    face_count = model->face_count;
    if (face_count > WIRE3D_DMG_MODEL_FACE_LIMIT) face_count = WIRE3D_DMG_MODEL_FACE_LIMIT;
    if ((model->flags & WIRE3D_DMG_MODEL_HIDDEN_LINES) && (model->faces != 0) && (model->edge_faces != 0))
    {
        w3ddmg_build_face_visibility(model, count, face_count);
    }

    edge_count = model->edge_count;




    i = 0;
    while (i < edge_count)
    {
        const Wire3DDMG_Edge* e;
        e = &model->edges[(__safe_index w3ddmg_u8)i];
        if ((e->a < count) && (e->b < count))
        {
            if (w3ddmg_screen_visible[(__safe_index w3ddmg_u8)e->a] &&
                w3ddmg_screen_visible[(__safe_index w3ddmg_u8)e->b] &&



                w3ddmg_is_edge_visible(model, i, face_count))

            {
                Wire3DDMG_DrawLine2D(
                    w3ddmg_screen_x[(__safe_index w3ddmg_u8)e->a],
                    w3ddmg_screen_y[(__safe_index w3ddmg_u8)e->a],
                    w3ddmg_screen_x[(__safe_index w3ddmg_u8)e->b],
                    w3ddmg_screen_y[(__safe_index w3ddmg_u8)e->b]);
            }
        }
        i = (w3ddmg_u8)(i + 1);
    }
}

kitaqgb/lib/wire3d_dmg.c:3703

c
void Wire3DDMG_DrawModelScaled(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz, w3ddmg_i16 scale_q8)








{
    w3ddmg_u8 i;
    w3ddmg_u8 count;
    w3ddmg_u8 edge_count;
    w3ddmg_u8 face_count;

    if (model == 0) return;
    if (model->vertices == 0) return;
    if (model->edges == 0) return;
    if (scale_q8 <= 0) scale_q8 = 256;

    count = model->vertex_count;
    if (count > WIRE3D_DMG_MODEL_VERTEX_LIMIT) count = WIRE3D_DMG_MODEL_VERTEX_LIMIT;

    i = 0;
    while (i < count)
    {
        const Wire3DDMG_Vec3* v;
        w3ddmg_i16 vx;
        w3ddmg_i16 vy;
        w3ddmg_i16 vz;
        w3ddmg_u8 sx;
        w3ddmg_u8 sy;

        v = &model->vertices[(__safe_index w3ddmg_u8)i];
        vx = (w3ddmg_i16)((v->x * scale_q8) >> 8);
        vy = (w3ddmg_i16)((v->y * scale_q8) >> 8);
        vz = (w3ddmg_i16)((v->z * scale_q8) >> 8);


        w3ddmg_rotate_y(&vx, &vz, (w3ddmg_i8)ry);
        w3ddmg_rotate_x(&vy, &vz, (w3ddmg_i8)rx);
        w3ddmg_rotate_z(&vx, &vy, (w3ddmg_i8)rz);






        vx = (w3ddmg_i16)(vx + x);
        vy = (w3ddmg_i16)(vy + y);
        vz = (w3ddmg_i16)(vz + z);

        if (w3ddmg_project_world(vx, vy, vz, &sx, &sy))
        {
            w3ddmg_screen_x[(__safe_index w3ddmg_u8)i] = sx;
            w3ddmg_screen_y[(__safe_index w3ddmg_u8)i] = sy;
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 1;
        }
        else
        {
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 0;
        }
        i = (w3ddmg_u8)(i + 1);
    }

    face_count = model->face_count;
    if (face_count > WIRE3D_DMG_MODEL_FACE_LIMIT) face_count = WIRE3D_DMG_MODEL_FACE_LIMIT;
    if ((model->flags & WIRE3D_DMG_MODEL_HIDDEN_LINES) && (model->faces != 0) && (model->edge_faces != 0))
    {
        w3ddmg_build_face_visibility(model, count, face_count);
    }

    edge_count = model->edge_count;

    if (edge_count > WIRE3D_DMG_MODEL_EDGE_LIMIT) edge_count = WIRE3D_DMG_MODEL_EDGE_LIMIT;
    w3ddmg_build_edge_flags(model, edge_count, face_count, rx, ry, rz);

    i = 0;
    while (i < edge_count)
    {
        const Wire3DDMG_Edge* e;
        e = &model->edges[(__safe_index w3ddmg_u8)i];
        if ((e->a < count) && (e->b < count))
        {
            if (w3ddmg_screen_visible[(__safe_index w3ddmg_u8)e->a] &&
                w3ddmg_screen_visible[(__safe_index w3ddmg_u8)e->b] &&

                w3ddmg_edge_flags[(__safe_index w3ddmg_u8)i])



            {
                Wire3DDMG_DrawLine2D(
                    w3ddmg_screen_x[(__safe_index w3ddmg_u8)e->a],
                    w3ddmg_screen_y[(__safe_index w3ddmg_u8)e->a],
                    w3ddmg_screen_x[(__safe_index w3ddmg_u8)e->b],
                    w3ddmg_screen_y[(__safe_index w3ddmg_u8)e->b]);
            }
        }
        i = (w3ddmg_u8)(i + 1);
    }
}
Wire3DDMG_DrawScene

Dessine au plus huit objets du plus proche au plus lointain, les faces proches masquant les arêtes suivantes.

Syntaxe

c
void Wire3DDMG_DrawScene(Wire3DDMG_Object* objects, w3ddmg_u8 count);

Paramètres

objects

Tableau d’objets contenant positions, rotations, échelles et indicateurs de visibilité.

count

Nombre d’entrées fournies ; consultez la limite de traitement propre à l’opération.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_DrawScene(Wire3DDMG_Object* objects, w3ddmg_u8 count); Traite au plus les huit premiers objets, triés du plus proche au plus lointain selon la profondeur de leur origine transformée. Dessine les modèles visibles et valides, puis marque les rectangles englobants de leurs faces avant pour rejeter les lignes suivantes dont tous les points échantillonnés sont masqués. C’est une approximation de l’occlusion entre objets, pas un tampon de profondeur. Efface son masque mais conserve les pixels déjà préparés. Ignore les tableaux null ; les objets et leurs données doivent rester lisibles. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_DrawScene(Wire3DDMG_Object* objects, w3ddmg_u8 count); Trie au plus huit origines d’objets selon leur profondeur caméra, du plus proche au plus lointain. Dessine les modèles visibles et valides et marque les rectangles englobants des faces avant pour les objets suivants. La première place triée évite les tests de masque ; la dernière n’ajoute pas d’occultant. C’est un rejet grossier de lignes, pas un tampon de profondeur. Ignore null et les entrées vides ; données de l’appelant et cache de projection courant doivent rester valides pendant le parcours.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Compare direct model scaling with an object-array scene.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3DDMG_Vec3 vertices[8]={{-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},{-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}};
__prg_rom Wire3DDMG_Edge edges[12]={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
Wire3DDMG_Model cube;
Wire3DDMG_Object objects[2];
s16 px; s16 py; s16 pz;
void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;

    cube.vertices=vertices;cube.edges=edges;cube.faces=0;cube.edge_faces=0;
    cube.vertex_count=8;cube.edge_count=12;cube.face_count=0;cube.flags=0;

    Wire3DDMG_BeginFrame();
    // Upper pair: direct model calls at unity and half scale.
    Wire3DDMG_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DDMG_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    // Lower pair: the caller owns both object records and the model tables.
    for(i=0;i<2;i++) {
        objects[i].model=&cube;objects[i].x=-32+(s16)i*64;
        objects[i].y=-32;objects[i].z=96;
        objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256-(s16)i*128;objects[i].visible=1;
    }
    Wire3DDMG_DrawScene(objects,2);
    // Numeric checks cover the operation supplied by this viewport profile.
    px=16;py=0;pz=0;Wire3DDMG_RotatePoint(&px,&py,&pz,0,4,0);
    result[1]=px; result[2]=py; result[3]=pz;
    Wire3DDMG_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_models.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:201

Notes de déclaration (texte source)
Sort at most eight object origins by camera depth, near to far. Draw visible
valid models and mark front-face bounding rectangles for later objects. The
first sorted slot bypasses mask tests and the last needs no new occluder.
This is coarse line rejection, not a depth buffer. Null/empty input is ignored;
caller data and the current projection cache must remain valid during traversal.

kitaqgb/lib/wire3d_dmg.c:3461

c
void Wire3DDMG_DrawScene(Wire3DDMG_Object* objects, w3ddmg_u8 count)
{
    w3ddmg_u8 scene_count;
    w3ddmg_u8 i;

    if (objects == 0) return;

    scene_count = count;
    if (scene_count > WIRE3D_DMG_SCENE_OBJECT_LIMIT) scene_count = WIRE3D_DMG_SCENE_OBJECT_LIMIT;

    if (scene_count == 0) return;


    i = 0;
    while (i < scene_count)
    {
        w3ddmg_scene_order[(__safe_index w3ddmg_u8)i] = i;
        w3ddmg_scene_depth[(__safe_index w3ddmg_u8)i] = w3ddmg_scene_object_depth(&objects[(__safe_index w3ddmg_u8)i]);
        i = (w3ddmg_u8)(i + 1);
    }

    i = 0;
    while (i < scene_count)
    {
        w3ddmg_u8 j;
        j = (w3ddmg_u8)(i + 1);
        while (j < scene_count)
        {
            w3ddmg_u8 oi;
            w3ddmg_u8 oj;
            oi = w3ddmg_scene_order[(__safe_index w3ddmg_u8)i];
            oj = w3ddmg_scene_order[(__safe_index w3ddmg_u8)j];





            if (w3ddmg_scene_depth[(__safe_index w3ddmg_u8)oj] < w3ddmg_scene_depth[(__safe_index w3ddmg_u8)oi])
            {
                w3ddmg_scene_order[(__safe_index w3ddmg_u8)i] = oj;
                w3ddmg_scene_order[(__safe_index w3ddmg_u8)j] = oi;
            }
            j = (w3ddmg_u8)(j + 1);
        }
        i = (w3ddmg_u8)(i + 1);
    }

    w3ddmg_clear_occlusion_mask();



    w3ddmg_occlusion_active = 0;


    i = 0;
    while (i < scene_count)
    {
        Wire3DDMG_Object* obj;
        obj = &objects[(__safe_index w3ddmg_u8)w3ddmg_scene_order[(__safe_index w3ddmg_u8)i]];
        if ((obj->visible != 0) && (obj->model != 0))
        {




            w3ddmg_occlusion_active = i == 0 ? 0 : 1;
            Wire3DDMG_DrawModelScaled(obj->model, obj->x, obj->y, obj->z, obj->rx, obj->ry, obj->rz, obj->scale_q8);
            if ((w3ddmg_u8)(i + 1) < scene_count)
            {
                w3ddmg_mark_model_occluder(obj->model);
            }

        }
        i = (w3ddmg_u8)(i + 1);
    }

    w3ddmg_occlusion_active = 0;
}
Wire3DDMG_EndFrame

Soumet à la VRAM les écritures du fond en attente et le dessin préparé.

Syntaxe

c
void Wire3DDMG_EndFrame();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_EndFrame(); Attend le prochain VBlank, applique les écritures BG en attente, puis copie la zone de préparation en VRAM en interrogeant les fenêtres d’accès. La copie consomme les pixels préparés. Le transfert peut dépasser le VBlank ; ce n’est pas un échange atomique d’image. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_EndFrame(); Attend le prochain VBlank et applique les écritures BG, puis consomme éventuellement les bandes auxiliaires avant de transférer les tuiles modifiées ou toute la zone principale. Le recouvrement des sources auxiliaire et principale rend cet ordre important. L’interrogation de STAT continue à travers les fenêtres d’accès ; la mise à jour peut dépasser un seul VBlank.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3DDMG_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3DDMG_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3DDMG_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3DDMG_SetCamera(0,0,0,0,0,0);
    Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawLine2D(8,8,56,8);
    Wire3DDMG_DrawLine2D(56,8,56,40);
    Wire3DDMG_DrawLine2D(56,40,8,40);
    Wire3DDMG_DrawLine2D(8,40,8,8);
    Wire3DDMG_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3DDMG_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3DDMG_PutBgTile(1,1,160);
    Wire3DDMG_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_raster.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:286

Notes de déclaration (texte source)
Wait for the next VBlank and flush BG writes, then optionally consume the
auxiliary strips before uploading either dirty tiles or the entire main stage.
Auxiliary/main source overlap makes that ordering significant. STAT polling
continues across access windows; the update need not fit one VBlank.

kitaqgb/lib/wire3d_dmg.c:3819

c
void Wire3DDMG_EndFrame()
{
    w3ddmg_wait_vblank_start();
    Wire3DDMG_EndFrameNow();
}
Wire3DDMG_EraseModelFaces

Projette les triangles avant du modèle et efface les pixels préparés à l’intérieur.

Syntaxe

c
void Wire3DDMG_EraseModelFaces(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz, w3ddmg_i16 scale_q8);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

scale_q8

Échelle dont l’unité vaut 256 ; les valeurs nulles ou négatives signifient aussi l’unité.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_EraseModelFaces(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz, w3ddmg_i16 scale_q8); Projette au plus 24 sommets et efface l’intérieur des triangles avant dans la zone de préparation, pour un modèle doté d’indicateurs de lignes cachées et de données de faces. Une échelle non positive signifie 256, soit l’unité. Examine au plus 16 faces ; celles traversant une limite de profondeur sont ignorées. Remplace aussi les caches de projection partagés, sans mettre à jour la VRAM. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_EraseModelFaces(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz, w3ddmg_i16 scale_q8); Projette au plus 24 sommets et efface l’intérieur des triangles avant dans la zone de préparation, pour un modèle doté d’indicateurs de lignes cachées et de données de faces. Une échelle non positive signifie 256, soit l’unité. Examine au plus 16 faces ; celles traversant une limite de profondeur sont ignorées. Remplace aussi les caches de projection partagés, sans mettre à jour la VRAM.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Erase a screen triangle and a projected model face from separate filled panels.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3DDMG_Vec3 vertices[4]={{-24,-24,0},{24,-24,0},{24,24,0},{-24,24,0}};
__prg_rom Wire3DDMG_Edge edges[4]={{0,1},{1,2},{2,3},{3,0}};
__prg_rom Wire3DDMG_Face faces[2]={{0,2,1},{0,3,2}};
Wire3DDMG_Model plane;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        plane.vertices=vertices;plane.edges=edges;plane.faces=faces;plane.edge_faces=0;
    plane.vertex_count=4;plane.edge_count=4;plane.face_count=2;plane.flags=1;
    Wire3DDMG_BeginFrame();
    // Separate panels show a direct screen triangle and a projected square face.
    for(i=8;i<=32;i++) Wire3DDMG_DrawLine2D(8,i,32,i);
    for(i=36;i<=84;i++) Wire3DDMG_DrawLine2D(40,i,88,i);
    Wire3DDMG_EraseTriangle2D(12,12,28,12,12,28);
    Wire3DDMG_EraseModelFaces(&plane,0,0,64,0,0,0,256);

    Wire3DDMG_EndFrame(); result[7]=0xA55A; while(1) {}
}

Résultat attendu

Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_faces.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_faces.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:179

Notes de déclaration (texte source)
Project up to 24 vertices and erase front-facing triangle interiors from
the stage for a model with hidden-line flags and face data. Nonpositive scale
means 256 (unity). Up to 16 faces are considered; depth-crossing faces are
skipped. This also replaces shared projection caches, but does not update VRAM.

kitaqgb/lib/wire3d_dmg.c:3581

c
void Wire3DDMG_EraseModelFaces(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz, w3ddmg_i16 scale_q8)

{
    w3ddmg_u8 i;
    w3ddmg_u8 count;
    w3ddmg_u8 face_count;

    if (model == 0) return;
    if (model->vertices == 0) return;
    if (model->faces == 0) return;
    if ((model->flags & WIRE3D_DMG_MODEL_HIDDEN_LINES) == 0) return;
    if (scale_q8 <= 0) scale_q8 = 256;

    count = model->vertex_count;
    if (count > WIRE3D_DMG_MODEL_VERTEX_LIMIT) count = WIRE3D_DMG_MODEL_VERTEX_LIMIT;

    i = 0;
    while (i < count)
    {
        const Wire3DDMG_Vec3* v;
        w3ddmg_i16 vx;
        w3ddmg_i16 vy;
        w3ddmg_i16 vz;
        w3ddmg_u8 sx;
        w3ddmg_u8 sy;

        v = &model->vertices[(__safe_index w3ddmg_u8)i];
        vx = (w3ddmg_i16)((v->x * scale_q8) >> 8);
        vy = (w3ddmg_i16)((v->y * scale_q8) >> 8);
        vz = (w3ddmg_i16)((v->z * scale_q8) >> 8);






        w3ddmg_rotate_y(&vx, &vz, ry);
        w3ddmg_rotate_x(&vy, &vz, rx);
        w3ddmg_rotate_z(&vx, &vy, rz);


        vx = (w3ddmg_i16)(vx + x);
        vy = (w3ddmg_i16)(vy + y);
        vz = (w3ddmg_i16)(vz + z);

        if (w3ddmg_project_world(vx, vy, vz, &sx, &sy))
        {
            w3ddmg_screen_x[(__safe_index w3ddmg_u8)i] = sx;
            w3ddmg_screen_y[(__safe_index w3ddmg_u8)i] = sy;
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 1;
        }
        else
        {
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 0;
        }
        i = (w3ddmg_u8)(i + 1);
    }

    face_count = model->face_count;
    if (face_count > WIRE3D_DMG_MODEL_FACE_LIMIT) face_count = WIRE3D_DMG_MODEL_FACE_LIMIT;
    w3ddmg_build_face_visibility(model, count, face_count);

    i = 0;
    while (i < face_count)
    {
        const Wire3DDMG_Face* f;
        f = &model->faces[(__safe_index w3ddmg_u8)i];
        if (w3ddmg_face_visible[(__safe_index w3ddmg_u8)i] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)f->a] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)f->b] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)f->c])
        {
            w3ddmg_clear_triangle(
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)f->a],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)f->a],
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)f->b],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)f->b],
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)f->c],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)f->c]);
        }
        i = (w3ddmg_u8)(i + 1);
    }
}

kitaqgb/lib/wire3d_dmg.c:3579

c
void Wire3DDMG_EraseModelFaces(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz, w3ddmg_i16 scale_q8)



{
    w3ddmg_u8 i;
    w3ddmg_u8 count;
    w3ddmg_u8 face_count;

    if (model == 0) return;
    if (model->vertices == 0) return;
    if (model->faces == 0) return;
    if ((model->flags & WIRE3D_DMG_MODEL_HIDDEN_LINES) == 0) return;
    if (scale_q8 <= 0) scale_q8 = 256;

    count = model->vertex_count;
    if (count > WIRE3D_DMG_MODEL_VERTEX_LIMIT) count = WIRE3D_DMG_MODEL_VERTEX_LIMIT;

    i = 0;
    while (i < count)
    {
        const Wire3DDMG_Vec3* v;
        w3ddmg_i16 vx;
        w3ddmg_i16 vy;
        w3ddmg_i16 vz;
        w3ddmg_u8 sx;
        w3ddmg_u8 sy;

        v = &model->vertices[(__safe_index w3ddmg_u8)i];
        vx = (w3ddmg_i16)((v->x * scale_q8) >> 8);
        vy = (w3ddmg_i16)((v->y * scale_q8) >> 8);
        vz = (w3ddmg_i16)((v->z * scale_q8) >> 8);


        w3ddmg_rotate_y(&vx, &vz, (w3ddmg_i8)ry);
        w3ddmg_rotate_x(&vy, &vz, (w3ddmg_i8)rx);
        w3ddmg_rotate_z(&vx, &vy, (w3ddmg_i8)rz);






        vx = (w3ddmg_i16)(vx + x);
        vy = (w3ddmg_i16)(vy + y);
        vz = (w3ddmg_i16)(vz + z);

        if (w3ddmg_project_world(vx, vy, vz, &sx, &sy))
        {
            w3ddmg_screen_x[(__safe_index w3ddmg_u8)i] = sx;
            w3ddmg_screen_y[(__safe_index w3ddmg_u8)i] = sy;
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 1;
        }
        else
        {
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)i] = 0;
        }
        i = (w3ddmg_u8)(i + 1);
    }

    face_count = model->face_count;
    if (face_count > WIRE3D_DMG_MODEL_FACE_LIMIT) face_count = WIRE3D_DMG_MODEL_FACE_LIMIT;
    w3ddmg_build_face_visibility(model, count, face_count);

    i = 0;
    while (i < face_count)
    {
        const Wire3DDMG_Face* f;
        f = &model->faces[(__safe_index w3ddmg_u8)i];
        if (w3ddmg_face_visible[(__safe_index w3ddmg_u8)i] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)f->a] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)f->b] &&
            w3ddmg_screen_visible[(__safe_index w3ddmg_u8)f->c])
        {
            w3ddmg_clear_triangle(
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)f->a],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)f->a],
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)f->b],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)f->b],
                w3ddmg_screen_x[(__safe_index w3ddmg_u8)f->c],
                w3ddmg_screen_y[(__safe_index w3ddmg_u8)f->c]);
        }
        i = (w3ddmg_u8)(i + 1);
    }
}
Wire3DDMG_EraseSpan2D

Efface un segment horizontal, bornes incluses, sur une ligne préparée.

Syntaxe

c
void Wire3DDMG_EraseSpan2D(w3ddmg_u8 y, w3ddmg_u8 x0, w3ddmg_u8 x1);

Paramètres

y

Coordonnée Y en pixels de la ligne à effacer.

x0

Borne X inférieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

x1

Borne X supérieure, en pixels du viewport ; l’ordre et le découpage suivent les notes de cette opération.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_EraseSpan2D(w3ddmg_u8 y, w3ddmg_u8 x0, w3ddmg_u8 x1); Ordonne les extrémités X et efface le segment préparé, bornes incluses. Les deux extrémités doivent être dans 0..127 ; un Y invalide est ignoré. La routine ne découpe pas X à votre place. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_EraseSpan2D(w3ddmg_u8 y, w3ddmg_u8 x0, w3ddmg_u8 x1); Ordonne les extrémités X et efface le segment préparé, bornes incluses. Les deux extrémités doivent être dans 0..127 ; un Y invalide est ignoré. La routine ne découpe pas X à votre place.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3DDMG_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3DDMG_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3DDMG_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3DDMG_SetCamera(0,0,0,0,0,0);
    Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawLine2D(8,8,56,8);
    Wire3DDMG_DrawLine2D(56,8,56,40);
    Wire3DDMG_DrawLine2D(56,40,8,40);
    Wire3DDMG_DrawLine2D(8,40,8,8);
    Wire3DDMG_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3DDMG_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3DDMG_PutBgTile(1,1,160);
    Wire3DDMG_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_raster.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:187

Notes de déclaration (texte source)
Order the X endpoints and erase the inclusive staged span. Both endpoints
must be in 0..127; invalid Y is ignored. The routine does not clip X for you.

kitaqgb/lib/wire3d_dmg.c:3681

c
void Wire3DDMG_EraseSpan2D(w3ddmg_u8 y, w3ddmg_u8 x0, w3ddmg_u8 x1)
{
    w3ddmg_u8 tx;

    if (x0 > x1)
    {
        tx = x0;
        x0 = x1;
        x1 = tx;
    }
    w3ddmg_stage_clear_span(y, x0, x1);
}
Wire3DDMG_EraseTriangle2D

Efface un triangle en coordonnées écran dans la zone de préparation, par segments horizontaux de lignes de balayage.

Syntaxe

c
void Wire3DDMG_EraseTriangle2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by, w3ddmg_u8 cx, w3ddmg_u8 cy);

Paramètres

ax

Coordonnée X du sommet A en pixels du viewport.

ay

Coordonnée Y du sommet A en pixels du viewport.

bx

Coordonnée X du sommet B en pixels du viewport.

by

Coordonnée Y du sommet B en pixels du viewport.

cx

Coordonnée X du sommet C en pixels du viewport.

cy

Coordonnée Y du sommet C en pixels du viewport.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_EraseTriangle2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by, w3ddmg_u8 cx, w3ddmg_u8 cy); Efface un triangle dans les pixels préparés à l’aide d’intersections entières avec les lignes de balayage. Fournissez des coordonnées du viewport. Les triangles dégénérés sont ignorés ; masque d’occlusion et VRAM restent inchangés. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_EraseTriangle2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by, w3ddmg_u8 cx, w3ddmg_u8 cy); Efface un triangle dans les pixels préparés à l’aide d’intersections entières avec les lignes de balayage. Fournissez des coordonnées du viewport. Les triangles dégénérés sont ignorés ; masque d’occlusion et VRAM restent inchangés.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Erase a screen triangle and a projected model face from separate filled panels.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3DDMG_Vec3 vertices[4]={{-24,-24,0},{24,-24,0},{24,24,0},{-24,24,0}};
__prg_rom Wire3DDMG_Edge edges[4]={{0,1},{1,2},{2,3},{3,0}};
__prg_rom Wire3DDMG_Face faces[2]={{0,2,1},{0,3,2}};
Wire3DDMG_Model plane;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        plane.vertices=vertices;plane.edges=edges;plane.faces=faces;plane.edge_faces=0;
    plane.vertex_count=4;plane.edge_count=4;plane.face_count=2;plane.flags=1;
    Wire3DDMG_BeginFrame();
    // Separate panels show a direct screen triangle and a projected square face.
    for(i=8;i<=32;i++) Wire3DDMG_DrawLine2D(8,i,32,i);
    for(i=36;i<=84;i++) Wire3DDMG_DrawLine2D(40,i,88,i);
    Wire3DDMG_EraseTriangle2D(12,12,28,12,12,28);
    Wire3DDMG_EraseModelFaces(&plane,0,0,64,0,0,0,256);

    Wire3DDMG_EndFrame(); result[7]=0xA55A; while(1) {}
}

Résultat attendu

Les faces projetées effacent une région remplie, rendant visibles les zones conservées et effacées.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_faces.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_faces.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:184

Notes de déclaration (texte source)
Erase a triangle from staged pixels using integer scanline intersections.
Supply viewport coordinates. Degenerate triangles are ignored; the occlusion
mask and VRAM are unchanged.

kitaqgb/lib/wire3d_dmg.c:3671

c
void Wire3DDMG_EraseTriangle2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by, w3ddmg_u8 cx, w3ddmg_u8 cy)
{
    w3ddmg_clear_triangle(ax, ay, bx, by, cx, cy);
}
Wire3DDMG_Init

Initialise le LCD, les tuiles et la carte du fond pour un viewport filaire monochrome.

Syntaxe

c
void Wire3DDMG_Init();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_Init(); Prend le contrôle du LCD : attend le VBlank, l’éteint, efface 6144 octets de tuiles et la carte BG, installe les tuiles HUD et le viewport 128×96 à numéros de tuiles signés, puis active le fond avec défilement nul et BGP=0xB4. Réinitialise caméra, file BG et zone de préparation. Réservez 0xD000..0xDFFF pour cette zone et conservez son mappage de banque WRAM. Appelez BeginFrame avant de dessiner pour initialiser aussi l’occlusion. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_Init(); Prend le contrôle du LCD, efface la VRAM des tuiles et la carte BG, puis installe un viewport de 16×15 à partir de la tuile (3,1). Règle le défilement à (8,0), BGP à 0xB4 et active le fond. Réinitialise caméra, files, modes de transfert, les deux tables de modifications et la zone de préparation. Réservez 0xD000..0xDFFF et gardez son mappage WRAM ; le stockage auxiliaire partage ces adresses. Appelez BeginFrame avant de dessiner pour établir l’état d’occlusion.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3DDMG_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3DDMG_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3DDMG_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3DDMG_SetCamera(0,0,0,0,0,0);
    Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawLine2D(8,8,56,8);
    Wire3DDMG_DrawLine2D(56,8,56,40);
    Wire3DDMG_DrawLine2D(56,40,8,40);
    Wire3DDMG_DrawLine2D(8,40,8,8);
    Wire3DDMG_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3DDMG_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3DDMG_PutBgTile(1,1,160);
    Wire3DDMG_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_raster.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:135

Notes de déclaration (texte source)
Take over LCD state, clear tile VRAM and the BG map, and install a 16x15
viewport beginning at map tile (3,1). Set scroll (8,0), BGP=0xB4 and BG display.
Reset camera, queues, transfer modes, both dirty tables and stage. Reserve
0xD000..0xDFFF and retain its WRAM mapping; auxiliary storage aliases it.
Call BeginFrame before drawing to establish occlusion state.

kitaqgb/lib/wire3d_dmg.c:3310

c
void Wire3DDMG_Init()
{
    w3ddmg_u8 row;
    w3ddmg_u8 col;
    w3ddmg_u8 tid;
    w3ddmg_u16 off;

    w3ddmg_wait_vblank_start();
    w3ddmg_reg_lcdc = 0;

    w3ddmg_clear_vram_asm();



    w3ddmg_fill_bg_map_asm();

    row = 0;
    tid = 0x90;
    while (row < WIRE3D_DMG_TILE_H)
    {



        off = (w3ddmg_u16)(0x23 + ((w3ddmg_u16)row << 5));

        col = 0;
        while (col < WIRE3D_DMG_TILE_W)
        {
            w3ddmg_bg_map_9800[(w3ddmg_u16)(off + (w3ddmg_u16)col)] = tid;
            tid = (w3ddmg_u8)(tid + WIRE3D_DMG_TILE_H);
            col = (w3ddmg_u8)(col + 1);
        }
        row = (w3ddmg_u8)(row + 1);
        tid = (w3ddmg_u8)(0x90 + row);
    }




    w3ddmg_reg_scx = 8;

    w3ddmg_reg_scy = 0;
    w3ddmg_reg_bgp = 0xB4;
    w3ddmg_reg_lcdc = 0x81;
    w3ddmg_bgq_count = 0;

    w3ddmg_aux_transfer_enabled = 0;
    w3ddmg_dirty_transfer_enabled = 0;


    Wire3DDMG_SetCamera((w3ddmg_i16)0, (w3ddmg_i16)0, (w3ddmg_i16)0, (w3ddmg_u8)0, (w3ddmg_u8)0, (w3ddmg_u8)0);
    w3ddmg_clear_stage_asm();

    w3ddmg_clear_stage_aux_asm();
    w3ddmg_clear_dirty_tables();

}
Wire3DDMG_ProjectPoint

Projette un point du monde par la caméra vers les coordonnées du viewport.

Syntaxe

c
w3ddmg_u8 Wire3DDMG_ProjectPoint(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8* sx, w3ddmg_u8* sy);

Paramètres

x

Composante X du point ou de l’origine de l’objet en coordonnées du monde.

y

Composante Y du point ou de l’origine de l’objet en coordonnées du monde.

z

Composante Z du point ou de l’origine de l’objet en coordonnées du monde.

sx

Pointeur u8 valide et accessible en écriture recevant la coordonnée X projetée.

sy

Pointeur u8 valide et accessible en écriture recevant la coordonnée Y projetée.

Valeur renvoyée

Renvoie 1 si la projection réussit, 0 si la profondeur est rejetée.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 w3ddmg_u8 Wire3DDMG_ProjectPoint(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8* sx, w3ddmg_u8* sy); Projette un point du monde avec la caméra courante. Une profondeur rejetée renvoie zéro sans changer les sorties ; le succès écrit des coordonnées bornées à 128×96. Les pointeurs de sortie doivent être valides. Borner à l’écran n’est pas un découpage géométrique. WIRE3D_DMG_HEIGHT = 120 w3ddmg_u8 Wire3DDMG_ProjectPoint(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8* sx, w3ddmg_u8* sy); Projette un point du monde avec la caméra courante. Une profondeur invalide renvoie zéro sans changer les sorties ; le succès écrit des coordonnées bornées à 128×120. Les deux pointeurs de sortie doivent être valides. Les différences de coordonnées doivent tenir dans s16.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3DDMG_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3DDMG_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3DDMG_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3DDMG_SetCamera(0,0,0,0,0,0);
    Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawLine2D(8,8,56,8);
    Wire3DDMG_DrawLine2D(56,8,56,40);
    Wire3DDMG_DrawLine2D(56,40,8,40);
    Wire3DDMG_DrawLine2D(8,40,8,8);
    Wire3DDMG_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3DDMG_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3DDMG_PutBgTile(1,1,160);
    Wire3DDMG_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_raster.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:216

Notes de déclaration (texte source)
Project a world point with the current camera. Return zero for invalid
depth without changing outputs; success writes clamped 128x120 coordinates.
Both output pointers must be valid. Coordinate differences must fit s16.

kitaqgb/lib/wire3d_dmg.c:688

c
w3ddmg_u8 Wire3DDMG_ProjectPoint(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8* sx, w3ddmg_u8* sy)
{
    return w3ddmg_project_world(x, y, z, sx, sy);
}
Wire3DDMG_PutBgTile

Met en file une écriture de numéro de tuile dans une case de la carte du fond.

Syntaxe

c
void Wire3DDMG_PutBgTile(w3ddmg_u8 x, w3ddmg_u8 y, w3ddmg_u8 tile);

Paramètres

x

Coordonnée X en tuiles dans la carte de fond de 32×32.

y

Coordonnée Y en tuiles dans la carte de fond de 32×32.

tile

Numéro de tuile sur huit bits pour la case du fond.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_PutBgTile(w3ddmg_u8 x, w3ddmg_u8 y, w3ddmg_u8 tile); Met en file une écriture de tuile dans la carte 32×32 en 0x9800 pour EndFrame. Les coordonnées invalides et les soumissions au-delà de 48 écritures en attente sont ignorées sans signalement. Cette file est distincte de celle de la bibliothèque vram générale. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_PutBgTile(w3ddmg_u8 x, w3ddmg_u8 y, w3ddmg_u8 tile); Met en file une écriture de tuile dans la carte 32×32 en 0x9800 pour EndFrame. Les coordonnées invalides et les soumissions au-delà de 48 écritures en attente sont ignorées sans signalement. Cette file est distincte de celle de la bibliothèque vram générale.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3DDMG_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3DDMG_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3DDMG_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3DDMG_SetCamera(0,0,0,0,0,0);
    Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawLine2D(8,8,56,8);
    Wire3DDMG_DrawLine2D(56,8,56,40);
    Wire3DDMG_DrawLine2D(56,40,8,40);
    Wire3DDMG_DrawLine2D(8,40,8,8);
    Wire3DDMG_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3DDMG_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3DDMG_PutBgTile(1,1,160);
    Wire3DDMG_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_raster.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:258

Notes de déclaration (texte source)
Queue a tile write to the 32x32 map at 0x9800 for EndFrame. Invalid map
coordinates and submissions beyond 48 pending writes are silently ignored.
This queue is separate from the general vram library queue.

kitaqgb/lib/wire3d_dmg.c:731

c
void Wire3DDMG_PutBgTile(w3ddmg_u8 x, w3ddmg_u8 y, w3ddmg_u8 tile)
{
    if (x >= 32) return;
    if (y >= 32) return;
    if (w3ddmg_bgq_count >= WIRE3D_DMG_BG_QUEUE_LIMIT) return;
    w3ddmg_bgq_x[(__safe_index w3ddmg_u8)w3ddmg_bgq_count] = x;
    w3ddmg_bgq_y[(__safe_index w3ddmg_u8)w3ddmg_bgq_count] = y;
    w3ddmg_bgq_tile[(__safe_index w3ddmg_u8)w3ddmg_bgq_count] = tile;
    w3ddmg_bgq_count = (w3ddmg_u8)(w3ddmg_bgq_count + 1);
}
Wire3DDMG_RotatePoint

Fait tourner un point sur place selon les angles fournis.

Syntaxe

c
void Wire3DDMG_RotatePoint(w3ddmg_i16* x, w3ddmg_i16* y, w3ddmg_i16* z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz);

Paramètres

x

Pointeur s16 distinct et accessible en écriture pour la composante X.

y

Pointeur s16 distinct et accessible en écriture pour la composante Y.

z

Pointeur s16 distinct et accessible en écriture pour la composante Z.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_RotatePoint(w3ddmg_i16* x, w3ddmg_i16* y, w3ddmg_i16* z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz); Tourne sur place dans l’ordre Y/X/Z, avec 16 pas par tour. Un pointeur de composante null rend tout l’appel sans effet ; utilisez des pointeurs distincts. Chaque rotation d’axe borne ses entrées à ±220.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Compare direct model scaling with an object-array scene.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3DDMG_Vec3 vertices[8]={{-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},{-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}};
__prg_rom Wire3DDMG_Edge edges[12]={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
Wire3DDMG_Model cube;
Wire3DDMG_Object objects[2];
s16 px; s16 py; s16 pz;
void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;

    cube.vertices=vertices;cube.edges=edges;cube.faces=0;cube.edge_faces=0;
    cube.vertex_count=8;cube.edge_count=12;cube.face_count=0;cube.flags=0;

    Wire3DDMG_BeginFrame();
    // Upper pair: direct model calls at unity and half scale.
    Wire3DDMG_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DDMG_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    // Lower pair: the caller owns both object records and the model tables.
    for(i=0;i<2;i++) {
        objects[i].model=&cube;objects[i].x=-32+(s16)i*64;
        objects[i].y=-32;objects[i].z=96;
        objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256-(s16)i*128;objects[i].visible=1;
    }
    Wire3DDMG_DrawScene(objects,2);
    // Numeric checks cover the operation supplied by this viewport profile.
    px=16;py=0;pz=0;Wire3DDMG_RotatePoint(&px,&py,&pz,0,4,0);
    result[1]=px; result[2]=py; result[3]=pz;
    Wire3DDMG_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_models.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:221

Notes de déclaration (texte source)
Rotate in place in Y/X/Z order using 16 steps per full turn. A null
component pointer makes the whole call a no-op; use distinct pointers.
Each axis rotation clamps its inputs to +/-220.

kitaqgb/lib/wire3d_dmg.c:3865

c
void Wire3DDMG_RotatePoint(w3ddmg_i16* x, w3ddmg_i16* y, w3ddmg_i16* z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz)
{
    if (x == 0) return;
    if (y == 0) return;
    if (z == 0) return;

    w3ddmg_rotate_y(x, z, ry);
    w3ddmg_rotate_x(y, z, rx);
    w3ddmg_rotate_z(x, y, rz);
}
Wire3DDMG_SelectEdgeMask

Choisit un masque précalculé de visibilité des arêtes selon le lacet de l’objet.

Syntaxe

c
w3ddmg_u16 Wire3DDMG_SelectEdgeMask(const Wire3DDMG_Model* model, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz);

Paramètres

model

Modèle contenant les tableaux de sommets, d’arêtes et de faces, ainsi que leurs nombres ; ses tables doivent rester lisibles pendant l’appel.

rx

Rotation autour de X ; seize pas font un tour complet.

ry

Rotation autour de Y ; seize pas font un tour complet.

rz

Rotation autour de Z ; seize pas font un tour complet.

Valeur renvoyée

Masque de visibilité des arêtes sur 16 bits, ou 0xFFFF si aucune table n’est fournie.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 w3ddmg_u16 Wire3DDMG_SelectEdgeMask(const Wire3DDMG_Model* model, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz); Choisit un masque précalculé d’après les quatre bits faibles du lacet de l’objet ; tangage, roulis et orientation de caméra sont ignorés. Utilisez 16, 8, 4 ou 2 secteurs ; les autres nombres positifs sélectionnent l’entrée zéro, sauf qu’un nombre >=16 utilise les 16 premières. Sans données, renvoie 0xFFFF. La table de masques doit rester lisible avec le mappage courant des pointeurs de données.

Cet exemple utilise le profil 128×96 ; son viewport commence à l’écran en (0,0). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Compare direct model scaling with an object-array scene.
// The selected 96-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 96
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3DDMG_Vec3 vertices[8]={{-16,-16,-16},{16,-16,-16},{16,16,-16},{-16,16,-16},{-16,-16,16},{16,-16,16},{16,16,16},{-16,16,16}};
__prg_rom Wire3DDMG_Edge edges[12]={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
Wire3DDMG_Model cube;
Wire3DDMG_Object objects[2];
u16 masks[2];
void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;

    cube.vertices=vertices;cube.edges=edges;cube.faces=0;cube.edge_faces=0;
    cube.vertex_count=8;cube.edge_count=12;cube.face_count=0;cube.flags=0;
    cube.edge_masks=0; cube.edge_mask_count=0;
    Wire3DDMG_BeginFrame();
    // Upper pair: direct model calls at unity and half scale.
    Wire3DDMG_DrawModel(&cube,-32,32,96,0,0,0);
    Wire3DDMG_DrawModelScaled(&cube,32,32,96,0,0,0,128);
    // Lower pair: the caller owns both object records and the model tables.
    for(i=0;i<2;i++) {
        objects[i].model=&cube;objects[i].x=-32+(s16)i*64;
        objects[i].y=-32;objects[i].z=96;
        objects[i].rx=0;objects[i].ry=0;objects[i].rz=0;
        objects[i].scale_q8=256-(s16)i*128;objects[i].visible=1;
    }
    Wire3DDMG_DrawScene(objects,2);
    // Numeric checks cover the operation supplied by this viewport profile.
    masks[0]=3;masks[1]=12;cube.edge_masks=masks; cube.edge_mask_count=2;
    result[1]=Wire3DDMG_SelectEdgeMask(&cube,0,0,0);
    result[2]=Wire3DDMG_SelectEdgeMask(&cube,0,8,0);
    Wire3DDMG_EndFrame(); result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Des modèles à l’échelle unitaire et à demi-échelle apparaissent au-dessus d’une scène issue d’un tableau d’objets aux mêmes échelles, illustrant projection et redimensionnement.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg96_models.c .\kitaqgb\lib\wire3d_dmg_96.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg96_models.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:207

Notes de déclaration (texte source)
Select a precomputed mask from the low four bits of object yaw; pitch,
roll and camera orientation are ignored. Use 16, 8, 4 or 2 bins; other positive
counts select entry zero (counts >=16 use the first 16). Missing data returns
0xFFFF. Keep the mask table readable through the current data-pointer mapping.

kitaqgb/lib/wire3d_dmg.c:1258

c
w3ddmg_u16 Wire3DDMG_SelectEdgeMask(const Wire3DDMG_Model* model, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz)
{
    w3ddmg_u8 count;
    w3ddmg_u8 bin;

    if (model == 0) return 0xFFFF;
    if (model->edge_masks == 0) return 0xFFFF;
    count = model->edge_mask_count;
    if (count == 0) return 0xFFFF;

    (void)rx;
    (void)rz;

    bin = (w3ddmg_u8)(((w3ddmg_u8)ry) & 15);
    if (count >= 16) return model->edge_masks[(__safe_index w3ddmg_u8)bin];
    if (count == 8) bin = (w3ddmg_u8)(bin >> 1);
    else if (count == 4) bin = (w3ddmg_u8)(bin >> 2);
    else if (count == 2) bin = (w3ddmg_u8)(bin >> 3);
    else bin = 0;

    if (bin >= count) bin = (w3ddmg_u8)(count - 1);
    return model->edge_masks[(__safe_index w3ddmg_u8)bin];
}
Wire3DDMG_SetAuxTransfer

Choisit si EndFrame transfère aussi les bandes auxiliaires.

Syntaxe

c
void Wire3DDMG_SetAuxTransfer(w3ddmg_u8 flag);

Paramètres

flag

Zéro désactive la fonction de transfert ; toute autre valeur l’active.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_SetAuxTransfer(w3ddmg_u8 flag); Mémorise l’autorisation de transfert auxiliaire d’EndFrame ; toute valeur non nulle l’active. Aucune donnée n’est copiée ou effacée ici. Les octets source auxiliaires partagent les adresses de la zone principale.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Use the auxiliary-transfer gate to consume an overlapping stage strip.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        Wire3DDMG_SetDirtyTransfer(1); Wire3DDMG_SetAuxTransfer(1);
    Wire3DDMG_BeginFrame();
    for(i=24;i<=31;i++) Wire3DDMG_DrawLine2D(40,i,47,i);
    // Auxiliary upload consumes this source before the dirty main tile is sent.

    Wire3DDMG_EndFrame(); result[7]=0xA55A; while(1) {}
}

Résultat attendu

Une partie de la zone principale est consommée par le transfert auxiliaire, ce qui produit un bloc noir de 8×8 à l’écran en (80,24).

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_aux_gate.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_aux_gate.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:268

Notes de déclaration (texte source)
Store the EndFrame auxiliary-transfer gate; any nonzero value enables it.
No data is copied or cleared here. Auxiliary source bytes alias the main stage.

kitaqgb/lib/wire3d_dmg.c:4639

c
void Wire3DDMG_SetAuxTransfer(w3ddmg_u8 flag)
{
    w3ddmg_aux_transfer_enabled = flag;
}
Wire3DDMG_SetCamera

Mémorise la position et l’orientation de la caméra pour les projections suivantes.

Syntaxe

c
void Wire3DDMG_SetCamera(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 pitch, w3ddmg_u8 yaw, w3ddmg_u8 roll);

Paramètres

x

Composante X de la caméra en coordonnées du monde.

y

Composante Y de la caméra en coordonnées du monde.

z

Composante Z de la caméra en coordonnées du monde.

pitch

Rotation autour de X ; seize pas font un tour complet.

yaw

Rotation autour de Y ; seize pas font un tour complet.

roll

Rotation autour de Z ; seize pas font un tour complet.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_SetCamera(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 pitch, w3ddmg_i8 yaw, w3ddmg_i8 roll); Mémorise la position et les angles de caméra pour les dessins suivants ; un tour compte 16 pas angulaires. Ne reprojette pas les dessins existants et ne valide pas les plages d’entrée. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_SetCamera(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 pitch, w3ddmg_u8 yaw, w3ddmg_u8 roll); Mémorise la position et les angles de caméra pour les dessins suivants ; un tour compte 16 pas angulaires. Ne reprojette pas les dessins existants et ne valide pas les plages d’entrée.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3DDMG_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3DDMG_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3DDMG_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3DDMG_SetCamera(0,0,0,0,0,0);
    Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawLine2D(8,8,56,8);
    Wire3DDMG_DrawLine2D(56,8,56,40);
    Wire3DDMG_DrawLine2D(56,40,8,40);
    Wire3DDMG_DrawLine2D(8,40,8,8);
    Wire3DDMG_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3DDMG_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3DDMG_PutBgTile(1,1,160);
    Wire3DDMG_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_raster.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:152

Notes de déclaration (texte source)
Store camera position and angles for later draws; a full turn is 16 angle
steps. No existing drawing is reprojected and no input range validation occurs.

kitaqgb/lib/wire3d_dmg.c:3399

c
void Wire3DDMG_SetCamera(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 pitch, w3ddmg_u8 yaw, w3ddmg_u8 roll)

{
    w3ddmg_cam_x = x;
    w3ddmg_cam_y = y;
    w3ddmg_cam_z = z;
    w3ddmg_cam_pitch = pitch;
    w3ddmg_cam_yaw = yaw;
    w3ddmg_cam_roll = roll;
}

kitaqgb/lib/wire3d_dmg.c:3397

c
void Wire3DDMG_SetCamera(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 pitch, w3ddmg_i8 yaw, w3ddmg_i8 roll)



{
    w3ddmg_cam_x = x;
    w3ddmg_cam_y = y;
    w3ddmg_cam_z = z;
    w3ddmg_cam_pitch = pitch;
    w3ddmg_cam_yaw = yaw;
    w3ddmg_cam_roll = roll;
}
Wire3DDMG_SetDirtyTransfer

Sélectionne le transfert des tuiles modifiées pour le viewport principal de 120 lignes.

Syntaxe

c
void Wire3DDMG_SetDirtyTransfer(w3ddmg_u8 flag);

Paramètres

flag

Zéro désactive la fonction de transfert ; toute autre valeur l’active.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_SetDirtyTransfer(w3ddmg_u8 flag); Mémorise l’autorisation de transfert des zones modifiées et efface les deux historiques de modifications ainsi que la zone principale, même si la valeur ne change pas. La VRAM est conservée ; l’activer sur une ancienne image peut laisser d’anciennes tuiles non marquées. Préparez donc un affichage de départ propre.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Remove the previous frame and upload only the tracked current/previous tiles.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        Wire3DDMG_SetDirtyTransfer(1); Wire3DDMG_SetAuxTransfer(0);
    Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawLine2D(8,8,24,8); Wire3DDMG_DrawLine2D(24,8,24,24);
    Wire3DDMG_DrawLine2D(24,24,8,24); Wire3DDMG_DrawLine2D(8,24,8,8);
    Wire3DDMG_EndFrame();
    Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawLine2D(80,80,104,80); Wire3DDMG_DrawLine2D(104,80,104,104);
    Wire3DDMG_DrawLine2D(104,104,80,104); Wire3DDMG_DrawLine2D(80,104,80,80);

    Wire3DDMG_EndFrame(); result[7]=0xA55A; while(1) {}
}

Résultat attendu

L’ancien cadre en haut à gauche disparaît ; seul reste le nouveau cadre aux coordonnées écran (96,88)..(120,112).

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_dirty.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_dirty.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:272

Notes de déclaration (texte source)
Store the dirty-transfer gate and clear both dirty histories and the main
stage, even if the value is unchanged. VRAM is retained; enabling this over an
old image can leave unmarked old tiles, so arrange a clean displayed baseline.

kitaqgb/lib/wire3d_dmg.c:4699

c
void Wire3DDMG_SetDirtyTransfer(w3ddmg_u8 flag)
{
    w3ddmg_dirty_transfer_enabled = flag;
    w3ddmg_clear_dirty_tables();
    w3ddmg_clear_stage_asm();
}
Wire3DDMG_SetPalette

Écrit la correspondance des quatre nuances dans le registre de palette du fond monochrome BGP.

Syntaxe

c
void Wire3DDMG_SetPalette(w3ddmg_u8 bgp);

Paramètres

bgp

Valeur du registre BGP contenant quatre affectations de nuance sur deux bits.

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 96 void Wire3DDMG_SetPalette(w3ddmg_u8 bgp); Écrit immédiatement l’encodage brut de la palette DMG BGP, sans synchronisation d’image. WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_SetPalette(w3ddmg_u8 bgp); Écrit immédiatement l’encodage brut de la palette DMG BGP, sans synchronisation d’image.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Draw a frame with a gap, a projected diagonal, and a copied corner tile.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
u8 projected_x;
u8 projected_y;
void main() {
    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
    Wire3DDMG_SetCamera(8,0,0,0,0,0);
    result[1]=Wire3DDMG_ProjectPoint(0,0,96,&projected_x,&projected_y);
    result[2]=projected_x; result[3]=projected_y;
    projected_x=91; projected_y=92;
    result[4]=Wire3DDMG_ProjectPoint(0,0,7,&projected_x,&projected_y);
    result[5]=projected_x; result[6]=projected_y;
    Wire3DDMG_SetCamera(0,0,0,0,0,0);
    Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawLine2D(8,8,56,8);
    Wire3DDMG_DrawLine2D(56,8,56,40);
    Wire3DDMG_DrawLine2D(56,40,8,40);
    Wire3DDMG_DrawLine2D(8,40,8,8);
    Wire3DDMG_EraseSpan2D(8,40,24); // Inclusive endpoints are ordered internally.
    Wire3DDMG_DrawLine3D(-24,-24,96,24,24,96);
    // Copy the viewport's top-left frame corner to a separate map cell.
    Wire3DDMG_PutBgTile(1,1,160);
    Wire3DDMG_EndFrame();
    result[7]=0xA55A;
    while(1) {}
}

Résultat attendu

Cet exemple montre lignes, points, effacement et projection dans une même image. Le milieu du bord supérieur du cadre en haut à gauche est effacé, et une diagonale est projetée près du centre. Une projection rejetée conserve les sorties 91 et 92.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_raster.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_raster.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:260

Notes de déclaration (texte source)
Write the raw DMG BGP palette encoding immediately; no frame synchronization occurs.

kitaqgb/lib/wire3d_dmg.c:746

c
void Wire3DDMG_SetPalette(w3ddmg_u8 bgp)
{
    w3ddmg_reg_bgp = bgp;
}
Wire3DDMG_TransferAuxNow

Transfère immédiatement six bandes auxiliaires et efface leurs octets source.

Syntaxe

c
void Wire3DDMG_TransferAuxNow();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_TransferAuxNow(); Transfère et consomme immédiatement les bandes source auxiliaires, indépendamment de leur autorisation. N’attend pas le début du VBlank et ne met à jour ni historique de modifications ni file BG. La source recouvre la zone principale ; coordonnez les deux transferts.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Upload a main line and an auxiliary block separately; verify source consumption.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3DDMG_Vec3 vertices[2]={{-32,0,0},{32,0,0}};
__prg_rom u8 edge_pairs[2]={0,1};
u8* stage_byte;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawIndexedEdges(vertices,2,edge_pairs,1,-64,104,96,1);
    Wire3DDMG_TransferMainNow();
    // Direct auxiliary transfer writes a separate tile after the main upload.
    for(i=24;i<=31;i++) Wire3DDMG_DrawLine2D(40,i,47,i);
    stage_byte=(u8*)0xD518;result[1]=*stage_byte;
    Wire3DDMG_TransferAuxNow();result[2]=*stage_byte;

    // Do not upload the consumed stage again.
    result[7]=0xA55A; while(1) {}
}

Résultat attendu

Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_direct.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_direct.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:280

Notes de déclaration (texte source)
Upload and consume auxiliary source strips immediately, independent of the
auxiliary gate. No VBlank-start wait or dirty-history/BG-queue update occurs.
The source overlaps the main stage and must be coordinated with its upload.

kitaqgb/lib/wire3d_dmg.c:4727

c
void Wire3DDMG_TransferAuxNow()
{
    w3ddmg_transfer_stage_aux_asm();
}
Wire3DDMG_TransferMainNow

Transfère immédiatement toute la zone principale et efface les pixels source consommés.

Syntaxe

c
void Wire3DDMG_TransferMainNow();

Valeur renvoyée

Aucune valeur de retour ; l’état modifié et les contraintes temporelles d’affichage sont décrits ci-dessus.

Conditions et limites

WIRE3D_DMG_HEIGHT = 120 void Wire3DDMG_TransferMainNow(); Transfère et consomme immédiatement toute la zone principale en interrogeant STAT, sans attendre le prochain VBlank. Ignore les autorisations de transfert et conserve les historiques de modifications et la file de tuiles BG ; l’appelant coordonne le cycle de l’image.

Cet exemple utilise le profil 128×120 ; son viewport commence à l’écran en (16,8). Réservez WRAM D000..DFFF et gardez son mappage de banque stable, sur CGB également. L’état partagé n’est pas réentrant.

WIRE3D_DMG_HEIGHT vaut 120 par défaut. Utilisez wire3d_dmg_96.c pour la hauteur 96. SelectEdgeMask est disponible à la hauteur 96 ; RotatePoint, DrawIndexedEdges, les contrôles d’autorisation de transfert et les transferts directs exigent la hauteur 120.

WIRE3D_DMG_HEIGHT accepte 88, 96 ou 120 ; WIRE3DCGB_HEIGHT accepte 88 ou 96. Les valeurs par défaut restent DMG 120 et CGB 96. Le profil de 88 lignes mesure 128×88, avec Y central=44. Utilisez le même réglage dans la bibliothèque et le programme ; compilez wire3d_dmg_88.c / wire3d_cgb_88.c à la place de l’entrée normale. DMG 88 garde la structure des modèles à 96 lignes et la limite de 16 arêtes. Le mode CGB 160×144 reste inchangé.

Exemple d’utilisation

c
#pragma bank 0
// Upload a main line and an auxiliary block separately; verify source consumption.
// The selected 120-line profile determines the stage layout and camera center.
#define WIRE3D_DMG_HEIGHT 120
#include "wire3d_dmg.h"
__location(0xC110) u16 result[8];
__location(0xFF47) u8 sample_bgp;
__location(0xFF40) u8 sample_lcdc;
__location(0xFF44) u8 sample_ly;
__location(0xFF4F) u8 sample_vbk;
__location(0xFF68) u8 sample_bgpi;
__location(0xFF69) u8 sample_bgpd;
__prg_rom Wire3DDMG_Vec3 vertices[2]={{-32,0,0},{32,0,0}};
__prg_rom u8 edge_pairs[2]={0,1};
u8* stage_byte;

void main() {

    u8 i;
    for(i=0;i<8;i++) result[i]=0;
    Wire3DDMG_Init();
    // A CGB-compatible ROM also needs CGB palette and tile-map attributes.
    if(__cgb_is_cgb()) {
        while(sample_ly>=144) {} while(sample_ly<144) {}
        sample_lcdc=0; sample_vbk=1;
        __vram_memset_unsafe(0x9800,0,1024); sample_vbk=0;
        sample_bgpi=0x80; sample_bgpd=255; sample_bgpd=127;
        for(i=0;i<6;i++) sample_bgpd=0;
        sample_lcdc=0x81;
    }
    Wire3DDMG_SetPalette(0xFC); // White background; every nonzero shade is black.
    result[0]=sample_bgp;
        Wire3DDMG_BeginFrame();
    Wire3DDMG_DrawIndexedEdges(vertices,2,edge_pairs,1,-64,104,96,1);
    Wire3DDMG_TransferMainNow();
    // Direct auxiliary transfer writes a separate tile after the main upload.
    for(i=24;i<=31;i++) Wire3DDMG_DrawLine2D(40,i,47,i);
    stage_byte=(u8*)0xD518;result[1]=*stage_byte;
    Wire3DDMG_TransferAuxNow();result[2]=*stage_byte;

    // Do not upload the consumed stage again.
    result[7]=0xA55A; while(1) {}
}

Résultat attendu

Une ligne horizontale projetée et un bloc auxiliaire de 8×8 illustrent les transferts directs ; un octet source passe de 255 à 0 lorsqu’il est consommé.

Programme d’exemple complet

Commande de compilation

powershell
New-Item -ItemType Directory -Force .\out | Out-Null
.\kitaqgb\kitaqgb.exe .\kitaq-docs\samples\api-examples\gb\wire_dmg120_direct.c .\kitaqgb\lib\wire3d_dmg.c -I .\kitaqgb\lib -I .\kitaq-docs\samples -o .\out\wire_dmg120_direct.gb --profile=dev --stack-bank=fixed --rst-disable --cgb=cgb --cart=mbc5 --romsize=256k --no-cache --no-disasm
Implémentation et source

kitaqgb/lib/wire3d_dmg.h:276

Notes de déclaration (texte source)
Upload and consume the full main stage immediately, polling STAT but not
waiting for the next VBlank. Ignore transfer gates and leave dirty histories
and BG tile queue unchanged; the caller coordinates the frame lifecycle.

kitaqgb/lib/wire3d_dmg.c:4714

c
void Wire3DDMG_TransferMainNow()
{
    w3ddmg_transfer_stage_asm();
}

Structures, constantes et en-têtes complets

Consultez ces en-têtes pour les macros qui ne sont pas des fonctions, les structures, les limites des tableaux, les énumérations et les alias. Ils reproduisent fidèlement les sources collectées, commentaires d'origine compris.

asset.h — Identifiants de ressources et descripteurs de données
c
#pragma once

#define ASSET_TYPE_RAW   ((u8)0)
#define ASSET_TYPE_TILES ((u8)1)
#define ASSET_TYPE_MAP   ((u8)2)
#define ASSET_TYPE_SONG  ((u8)3)

// Packed ROM descriptor: type tag, payload bank, bank-window address and byte length.
// The table itself may live in a different bank from the payload.
typedef __packed struct {
    u8 type;
    u8 bank;
    const u8* ptr;
    u16 len;
} AssetDesc;

void __farmemcpy(void* dst, u8 bank, const void* src, u16 len);
void __vram_copy(u16 dst, const void* src, u16 len);

// Retain the descriptor table address, bank and count; the table is not copied.
void asset_set_table(u8 bank, const AssetDesc* table, u8 count);
// Copy one descriptor from its ROM bank into caller storage. Return zero for a
// null destination or an out-of-range ID; table validity is the caller's responsibility.
u8 asset_get(u8 asset_id, AssetDesc* out_desc);
// Copy at most max_len bytes using the asset's bank. Success means the ID was
// valid, even when the payload was truncated to fit the supplied limit.
u8 asset_load_raw(u8 asset_id, void* dst, u16 max_len);
// Accept tile/raw descriptors and transfer their bytes to VRAM. This path passes
// the descriptor pointer directly; callers must arrange the correct visible ROM bank.
u8 asset_load_tiles(u8 asset_id, u16 vram_dst);
// Return the descriptor bank, or zero on lookup failure; zero can also be a valid bank.
u8 asset_get_bank(u8 asset_id);
// Return the stored address without switching banks. Use the descriptor bank
// with far-data helpers before dereferencing banked assets; failure returns null.
const u8* asset_get_ptr(u8 asset_id);
// Return the descriptor byte length, or zero if its ID cannot be resolved.
u16 asset_get_len(u8 asset_id);

kitaqgb/lib/asset.h

audio.h — Musique, effets sonores et commandes audio
c
#pragma once

// Shared Game Boy audio driver for KITAQGB projects.
//
// Integration notes:
// - Compile a hardware-register file before audio.c so NR10..NR52 and
//   WAVE0..WAVE15 are already declared.
// - Call Audio_Init() once during startup.
// - Call Audio_Update() once per frame, ideally from your VBlank-driven main loop.
// - audio.c is intended to stay in bank 0.
// - Music streams are banked explicitly with Audio_PlayMusic(bank, song).
// - Audio_PlaySFX(sfx, priority) captures the currently visible ROM bank.
// - Audio_PlaySFXBanked(bank, sfx, priority) safely classifies CH1/CH3 data
//   after switching to the requested bank, so banked SFX can be started from
//   any currently visible ROM bank.
// - GBDAW-Stream v1.2 extends the legacy command set with explicit per-channel
//   automation commands that map more directly from GUI and Python tooling.

// Physical APIs and music-stream commands share zero-based CH1..CH4 IDs.
#define AUDIO_CHANNEL_CH1 ((u8)0)
#define AUDIO_CHANNEL_CH2 ((u8)1)
#define AUDIO_CHANNEL_CH3 ((u8)2)
#define AUDIO_CHANNEL_CH4 ((u8)3)

// Music-stream IDs used by NOTE, SET_INST and STOP_CHANNEL.
#define AUDIO_STREAM_CHANNEL_CH1 AUDIO_CHANNEL_CH1
#define AUDIO_STREAM_CHANNEL_CH2 AUDIO_CHANNEL_CH2
#define AUDIO_STREAM_CHANNEL_CH3 AUDIO_CHANNEL_CH3
#define AUDIO_STREAM_CHANNEL_CH4 AUDIO_CHANNEL_CH4

#define AUDIO_PAN_CENTER ((u8)0)
#define AUDIO_PAN_LEFT ((u8)1)
#define AUDIO_PAN_RIGHT ((u8)2)
#define AUDIO_PAN_MUTE ((u8)3)
#define AUDIO_PAN_INHERIT ((u8)0xFF)

#define AUDIO_WAVE_TRIANGLE ((u8)0)
#define AUDIO_WAVE_SAW ((u8)1)
#define AUDIO_WAVE_VOWEL_A ((u8)2)
#define AUDIO_WAVE_VOWEL_I ((u8)3)
#define AUDIO_WAVE_VOWEL_U ((u8)4)
#define AUDIO_WAVE_VOWEL_E ((u8)5)
#define AUDIO_WAVE_VOWEL_O ((u8)6)
#define AUDIO_WAVE_CUSTOM ((u8)7)

#define AUDIO_CH3_LEVEL_MUTE ((u8)0x00)
#define AUDIO_CH3_LEVEL_100 ((u8)0x20)
#define AUDIO_CH3_LEVEL_50 ((u8)0x40)
#define AUDIO_CH3_LEVEL_25 ((u8)0x60)

#define AUDIO_VOLUME_MIN ((u8)0)
#define AUDIO_VOLUME_MAX ((u8)7)
#define AUDIO_NOTE_MAX ((u8)67)

#define AUDIO_CMD_WAIT ((u8)0x00)
#define AUDIO_CMD_NOTE ((u8)0x10)
#define AUDIO_CMD_SET_INST ((u8)0x11)
#define AUDIO_CMD_SET_PAN ((u8)0x12)
#define AUDIO_CMD_SET_SWEEP ((u8)0x13)
#define AUDIO_CMD_SET_WAVE ((u8)0x14)
#define AUDIO_CMD_SET_CH3_CUSTOM_WAVE ((u8)0x15)
#define AUDIO_CMD_SET_CH4_PARAM ((u8)0x16)
#define AUDIO_CMD_SET_MASTER_VOLUME ((u8)0x17)
#define AUDIO_CMD_SET_CH1_DUTY ((u8)0x18)
#define AUDIO_CMD_SET_CH2_DUTY ((u8)0x19)
#define AUDIO_CMD_SET_CH3_LEVEL ((u8)0x1A)
#define AUDIO_CMD_STOP_CHANNEL ((u8)0x20)
#define AUDIO_CMD_LOOP ((u8)0x30)
#define AUDIO_CMD_STOP ((u8)0x40)

#define AUDIO_SFX_CH3_MARKER ((u8)0xFF)

// Enable the APU and reset software streams, instruments, mix and fade state.
// Load the initial triangle wave, then leave every channel silent. Call at startup
// before concurrent interrupt-driven audio service can access these shared fields.
void Audio_Init();
// Advance the master fade first. Unless paused, service both effect streams
// then the optional legacy music decoder. Call once per frame for frame-based timing.
void Audio_Update();
// Retain the bank and song pointer, reset legacy instruments/cursors, and arm
// playback from the beginning. Supply a valid, persistent song; no bytes are copied
// and null is not checked. Existing effect streams remain active.
void __stackcall Audio_PlayMusic(u8 bank, u8 *song);
// Stop legacy music and clear its resume mask, then silence all physical channels.
// Effect pointers remain active and may produce sound on a later update.
void Audio_StopMusic();
// On pause entry, silence hardware while retaining cursors. On resume, retrigger
// eligible legacy CH1, CH2 and CH4 notes; CH3 is not retriggered here. Updates still
// advance master fades while paused, and effect playback resumes on a later update.
void __stackcall Audio_SetPaused(u8 on);
// Capture the currently mapped ROM bank and start an effect with inherited pan.
// Use the explicit-bank API when the pointer belongs to another bank.
void __stackcall Audio_PlaySFX(u8 *sfx, u8 priority);
// Start a banked effect with the channel's base pan, subject to priority arbitration.
void __stackcall Audio_PlaySFXBanked(u8 bank, u8 *sfx, u8 priority);
// Capture the currently mapped ROM bank and request an effect with a pan override.
// Use the explicit-bank API when the pointer belongs to another bank.
void __stackcall Audio_PlaySFXPanned(u8 *sfx, u8 priority, u8 pan);
// Retain a banked effect stream if its priority equals or exceeds the current
// owner's priority, or that slot is empty. A leading CH3 marker selects the wave
// slot and is skipped; other streams use the pulse slot. Paused requests are ignored.
// Keep stream storage valid until completion; acceptance does not trigger a note.
void __stackcall Audio_PlaySFXPannedBanked(u8 bank, u8 *sfx, u8 priority, u8 pan);
// Clear both effect streams and their pan overrides. When not paused, release
// borrowed channels through the configured legacy or VBlank recovery path.
void Audio_StopSfx();
// Stop a physical channel and clear its legacy resume bit. CH1 also clears the
// pulse effect stream; CH3 clears the wave effect stream. This is the legacy
// channel API and does not clear a VBlank driver's independently latched notes.
void __stackcall Audio_StopChannel(u8 ch);

// Set the music-processing gate. This does not silence notes already playing
// or stop the legacy stream cursor from consuming commands.
void __stackcall Audio_SetMusicEnabled(u8 on);
// Enable effect note writes, or disable them and release both effect streams.
// Disabling follows Audio_StopSfx recovery rules rather than silencing all channels.
void __stackcall Audio_SetSfxEnabled(u8 on);

// Clamp both output levels to 0..7, cancel any fade, and write NR50 immediately.
void __stackcall Audio_SetMasterVolume(u8 left, u8 right);
// Move left/right volume toward clamped targets at the requested Audio_Update
// call interval. An interval of zero applies the levels immediately.
void __stackcall Audio_FadeToMasterVolume(u8 left, u8 right, u8 step_frames);
// Cancel further volume steps, retaining the current cached levels and hardware output.
void Audio_CancelMasterVolumeFade();

// Update the base pan for a physical channel and reapply active effect overrides.
// Unknown channel IDs select CH4; unsupported pan values mute the selected channel.
void __stackcall Audio_SetPan(u8 ch, u8 pan);
// Two bits per channel (CH1 in bits 0-1): center, left, right, mute.
// Applies all four positions with one NR51 update for sequencer automation.
void __stackcall Audio_SetPanPacked(u8 packed);
// Install a named preset or the cached custom wave. Unknown IDs are ignored.
// This does not update Audio_Ch3Wave or trigger a new note.
void __stackcall Audio_LoadWave(u8 wave_id);
// Copy 16 packed sample bytes into the persistent custom cache and wave RAM.
// A null pointer is ignored; the source is needed only for this call.
void __stackcall Audio_LoadCustomWave(const u8 *wave16);

// Cache the low two duty bits for the next CH1 note; do not change the active register.
void __stackcall Audio_SetCh1Duty(u8 duty);
// Cache the low two duty bits for the next CH2 note; do not change the active register.
void __stackcall Audio_SetCh2Duty(u8 duty);
// Cache the raw NR32 level encoding for the next CH3 note without writing hardware.
void __stackcall Audio_SetCh3Level(u8 level);
// Cache the raw noise polynomial encoding for the next CH4 note without writing hardware.
void __stackcall Audio_SetCh4Param(u8 param);

// Trigger CH1 with the cached sweep and the supplied raw envelope. Clamp the
// note index; duty values 0, 1 and 3 select their encodings, and all others use 2.
void __stackcall Audio_Ch1NoteOn(u8 note, u8 vol_env, u8 duty2);
// Trigger CH2 with the supplied raw envelope and a clamped note index. Duty
// values 0, 1 and 3 select their encodings; all other values use duty 2.
void __stackcall Audio_Ch2NoteOn(u8 note, u8 vol_env, u8 duty2);
// Clamp the note index, program the raw NR32 output level, and trigger CH3.
// Wave RAM must already contain the desired waveform; this does not load one.
void __stackcall Audio_Ch3NoteOn(u8 note, u8 level);
// Cache the supplied noise parameter, program the raw envelope and polynomial
// registers, then trigger CH4 with the length-enable bit clear.
void __stackcall Audio_Ch4NoteOn(u8 param, u8 vol_env);

kitaqgb/lib/audio.h

audio_vblank.h — Lecture musicale par interruption VBlank
c
#pragma once

// Fixed-bank VBlank BGM driver.
//
// Stream format:
//   delay, ch1_note, ch2_note, ch3_note, ch4_noise_param
//   IMMEDIATE, ch1_note, ch2_note, ch3_note, ch4_noise_param
//   CONTROL, command, arg0, arg1, arg2
//
// Notes are 0..67. To stay inside the useful CGB register range, C6..G6
// (60..67) alias C5..G5 (48..55) in the fixed pitch table. REST leaves a
// channel unchanged, while STOP silences it. END stops either playback mode.
// LOOP jumps to MusicLoopPoint only in direct-pointer mode; a queue producer
// must expand loops itself. IMMEDIATE is recognized only in queue mode.
// Direct streams treat 0xFB as an ordinary delay, and queues treat 0xFE as one.

#define AUDIO_VBLANK_REST ((u8)0xFF)
#define AUDIO_VBLANK_END  ((u8)0xFF)
#define AUDIO_VBLANK_LOOP ((u8)0xFE)
#define AUDIO_VBLANK_STOP ((u8)0xFD)
#define AUDIO_VBLANK_CONTROL ((u8)0xFC)
#define AUDIO_VBLANK_IMMEDIATE ((u8)0xFB)
#define AUDIO_VBLANK_CONTROL_RESET ((u8)0x01)

#define AUDIO_VBLANK_W8 ((u8)15)
#define AUDIO_VBLANK_WQ ((u8)30)
#define AUDIO_VBLANK_WH ((u8)60)

#define AUDIO_VBLANK_QUEUE_RECORDS 16
#define AUDIO_VBLANK_QUEUE_BYTES 80

typedef void (*AudioVBlankFrameHook)();

extern __wram u8 AudioVBlank_MusicPlaying;
extern __wram u8 AudioVBlank_MusicEnabled;
extern __wram u8 AudioVBlank_MusicDelay;
extern __wram u8 *AudioVBlank_MusicStart;
extern __wram u8 *AudioVBlank_MusicPointer;
extern __wram u8 *AudioVBlank_MusicLoopPoint;
extern __wram u8 AudioVBlank_Step;
extern __wram u8 AudioVBlank_Ch2Note;
extern __wram u8 AudioVBlank_Ch1Note;
extern __wram u8 AudioVBlank_Ch3Note;
extern __wram u8 AudioVBlank_Ch2LatchedNote;
extern __wram u8 AudioVBlank_Ch1LatchedNote;
extern __wram u8 AudioVBlank_Ch3LatchedNote;
// Sound effects temporarily own CH1/CH2/CH3.  A pending value of 1 means a BGM
// note/stop event was suppressed and must be applied once the effect ends;
// value 2 means release the effect channel without retriggering an old note.
extern __wram u8 AudioVBlank_RestoreCh1Pending;
extern __wram u8 AudioVBlank_RestoreCh3Pending;
extern __wram u8 AudioVBlank_Ch4Param;
extern __wram u8 AudioVBlank_Ch1Envelope;
extern __wram u8 AudioVBlank_Ch2Envelope;
extern __wram u8 AudioVBlank_Ch4Envelope;
extern __wram u8 AudioVBlank_Ch1Duty;
extern __wram u8 AudioVBlank_Ch2Duty;
extern __wram u8 AudioVBlank_Ch1Sweep;
extern __wram u8 AudioVBlank_Ch3Level;
extern __wram u8 AudioVBlank_ControlCommand;
extern __wram u8 AudioVBlank_ControlArg0;
extern __wram u8 AudioVBlank_ControlArg1;
extern __wram u8 AudioVBlank_ControlArg2;
// QueueReset/QueueRefill/QueuePlay provide the foreground producer. The ISR owns
// ReadIndex and decreases Count; use the producer APIs instead of editing the
// indices/count while playback is running. Records contain exactly five bytes.
// MusicPlaying and all enable/pause gates still apply in queue mode.
extern __wram u8 AudioVBlank_QueueMode;
extern __wram u8 AudioVBlank_QueueReadIndex;
extern __wram u8 AudioVBlank_QueueWriteIndex;
extern __wram u8 AudioVBlank_QueueCount;
extern __wram u8 AudioVBlank_QueueUnderruns;
// Queue bytes reside in WRAM bank 1. A producer must select that bank while
// writing and restore the caller bank; publish the record only after all bytes
// are complete. The ISR selects bank 1 itself and restores SVBK before returning.
extern __wramx_bank(1) u8 AudioVBlank_QueueBuffer[AUDIO_VBLANK_QUEUE_BYTES];
// The ISR invokes this hook even when music processing is gated off. It runs
// with SVBK=1 using a direct-address call; keep hook code/data accessible in that
// context and synchronize pointer changes with interrupt execution.
extern __wram AudioVBlankFrameHook AudioVBlank_FrameHook;

// Reset software playback state, queue counters, instruments and the frame hook.
// Call before enabling this ISR; the routine does not mask interrupts or
// initialize the APU registers and cannot synchronize with an active handler.
void AudioVBlank_Init();
// Stop music and select an empty WRAM queue; preserve IE, IME and enable/pause gates.
void AudioVBlank_QueueReset();
// Copy complete records from the currently mapped source; return records accepted.
// Each call attempts at most 16 records and stops when full. Null/zero returns 0.
// Supports ROM and RAM sources, restores SVBK and IE, and never changes IME.
// Single foreground producer only: do not call from an ISR or frame hook.
// LOOP must be expanded by the producer. END occupies a full five-byte record.
u8 __stackcall AudioVBlank_QueueRefill(const u8 *records, u8 count);
// Start/resume queued playback; return 1 on success, 0 for an empty/nonqueue mode.
// Does not enable the interrupt, music gate or clear pause. Queue before starting.
u8 AudioVBlank_QueuePlay();
// Select a directly addressed song and reset its cursors, leaving the playing
// flag unchanged. Song storage must remain accessible to the fixed-bank ISR;
// coordinate this multi-field update with interrupt execution.
void __stackcall AudioVBlank_SetMusic(u8 *song);
// Restart the selected direct song at its beginning, leaving queue mode.
// A null song invokes Stop; this does not enable the music or IRQ gates.
void AudioVBlank_Play();
// Select and restart a directly addressed song. This is not the banked WRAM-queue path.
void __stackcall AudioVBlank_PlayMusic(u8 *song);
// Stop software playback and silence pulse/noise envelopes and the wave DAC.
// Song pointers and the IRQ enable remain unchanged; the routine writes the
// physical channels directly, so coordinate ownership with sound effects.
void AudioVBlank_Stop();
// Gate music processing and clear pending CH1/CH3 recovery on disable.
// No audio register is written here: disabling does not itself silence a note
// already playing or disable the VBlank interrupt.
void __stackcall AudioVBlank_SetEnabled(u8 on);
// Enable the VBlank source in IE and execute EI, enabling CPU interrupts globally.
// Install the correct interrupt vector and initialize driver state first.
void AudioVBlank_EnableIrq();
// Clear only the VBlank bit in IE. Other interrupt sources and current sound remain unchanged.
void AudioVBlank_DisableIrq();
// Recover the borrowed pulse channel (CH1 or CH2) from its latched music event.
// Pending value 2, disabled music, or a non-note latch silences it instead.
// The caller must first establish that the effect has released the channel.
void AudioVBlank_RestoreCh1();
// Recover a latched wave-channel music event after effect release, or disable
// the DAC for a release-only request, disabled music, or a non-note latch.
// The caller owns effect arbitration and clearing the pending flag.
void AudioVBlank_RestoreCh3();
// Request deferred pulse-channel release only when no recovery is pending.
// Preserve value 1, which records a music event suppressed while an effect owned it.
void AudioVBlank_RequestRestoreCh1();
// Request a deferred wave-channel release only if no recovery is pending.
// Preserve value 1, which records a new music event suppressed by the effect.
void AudioVBlank_RequestRestoreCh3();

kitaqgb/lib/audio_vblank.h

bank.h — Accès au code et aux données tenant compte des banques
c
#pragma once

// A bank byte accompanies the CPU-visible ROM address; the pointer alone is not a far address.
typedef __packed struct {
    u8 bank;
    const u8* ptr;
} BankPtr;

extern u8 kq_bank_current;

void __bankswitch(u8 bank);
u8 __farpeek8(u8 bank, const void* addr);
u16 __farpeek16(u8 bank, const void* addr);
void __farmemcpy(void* dst, u8 bank, const void* src, u16 len);
void __farcall_ptr(u8 bank, const void* func);

// Update both the library bank record and the compiler shadow used by far
// reads and calls. Invoke this permanent bank change from fixed-bank code.
void bank_switch(u8 bank);
// Return the last bank recorded by bank_switch; this does not read cartridge hardware.
u8 bank_get_current();
// Read one byte through the compiler intrinsic that accepts an explicit ROM bank.
u8 far_data_read8(u8 bank, const void* addr);
// Read a 16-bit value from the supplied bank and address through the far-read intrinsic.
u16 far_data_read16(u8 bank, const void* addr);
// Copy len bytes from banked ROM into caller-owned writable storage.
void far_data_read(u8 bank, const void* addr, void* dst, u16 len);
// Invoke a no-argument callback in its ROM bank, then restore the caller
// bank. The pointer must identify executable code; no arguments are forwarded.
void far_call(u8 bank, const void* func);
// Store a bank/address pair without accessing ROM; a null output pointer is ignored.
void farptr_make(BankPtr* out, u8 bank, const u8* ptr);
// Read one byte using both components of the bank-qualified pointer.
u8 farptr_read8(BankPtr ptr);
// Read a 16-bit value using both components of the bank-qualified pointer.
u16 farptr_read16(BankPtr ptr);
// Copy len bytes from a bank-qualified pointer; dst must have room for the full copy.
void farptr_read(BankPtr ptr, void* dst, u16 len);

kitaqgb/lib/bank.h

camera.h — Coordonnées du monde et zones visibles
c
#pragma once

#include "scroll.h"

// All position, target and bound fields use signed Q8.8 (-128 to just below 128 pixels).
// Pass initialized, non-null storage; world/screen conversion arguments use integer pixels.
typedef struct Camera8_8 {
    s16 fx;
    s16 fy;
    s16 target_fx;
    s16 target_fy;
    s16 min_fx;
    s16 min_fy;
    s16 max_fx;
    s16 max_fy;
    u8 use_target;
    u8 use_bounds;
} Camera8_8;

// Zero all position/target/bound fields and disable targeting and bounds.
void Camera_Init(Camera8_8* cam);
// Replace the current Q8.8 position and immediately apply enabled bounds.
void Camera_Set(Camera8_8* cam, s16 fx, s16 fy);
// Store a Q8.8 target and enable subsequent step-toward-target updates.
void Camera_SetTarget(Camera8_8* cam, s16 fx, s16 fy);
// Disable target following without moving the camera or erasing the stored target.
void Camera_ClearTarget(Camera8_8* cam);
// Install ordered Q8.8 bounds, enable them and clamp the current position immediately.
void Camera_SetBounds(Camera8_8* cam, s16 min_fx, s16 min_fy, s16 max_fx, s16 max_fy);
// Disable clamping while retaining the stored bounds and current position.
void Camera_ClearBounds(Camera8_8* cam);
// Add Q8.8 deltas and clamp afterward. Keep the intermediate sums within s16;
// clamping cannot repair arithmetic that already overflowed.
void Camera_Add(Camera8_8* cam, s16 dfx, s16 dfy);
// Move by the signed target delta shifted by 0..7 bits, then apply bounds.
// Quantization can make a small delta produce no movement; only exact equality
// clears targeting, and a target outside the bounds may remain active indefinitely.
void Camera_StepTowardTarget(Camera8_8* cam, u8 shift);
// Discard fractional bits and write the low eight integer bits to background scroll registers.
void Camera_ApplyBg(const Camera8_8* cam);
// Convert the Q8.8 position to byte scroll values and stage them for a later flush.
void Camera_ApplyBgBuffered(const Camera8_8* cam);
// Derive nonnegative camera extents from world minus screen size, then convert
// them to Q8.8 bounds. Extents must fit signed Q8.8; the u16 input type does
// not imply support for arbitrary large worlds.
void Camera_ClampToSize(Camera8_8* cam, u16 world_w_px, u16 world_h_px, u8 screen_w_px, u8 screen_h_px);
// Convert an integer-pixel world X by subtracting the camera's integer X component.
s16 Camera_WorldToScreenX(const Camera8_8* cam, s16 world_x);
// Convert an integer-pixel world Y by subtracting the camera's integer Y component.
s16 Camera_WorldToScreenY(const Camera8_8* cam, s16 world_y);
// Convert integer-pixel screen X back to world X using the camera's integer component.
s16 Camera_ScreenToWorldX(const Camera8_8* cam, s16 screen_x);
// Convert integer-pixel screen Y back to world Y using the camera's integer component.
s16 Camera_ScreenToWorldY(const Camera8_8* cam, s16 screen_y);

// Set the shared camera from integer pixels, converting to the representable Q8.8 range.
void camera_set(s16 x, s16 y);
// Position the shared camera so the world point appears at the requested screen
// anchor. This is an immediate move, not the smoothed target-following path.
void camera_follow_xy(s16 x, s16 y, u8 screen_cx, u8 screen_cy);
// Derive and apply world/screen bounds to the shared convenience camera.
void camera_clamp(u16 world_w_px, u16 world_h_px, u8 screen_w_px, u8 screen_h_px);
// Write the shared camera's current integer position to background scroll registers.
void camera_apply();
// Convert integer-pixel world X using the shared convenience camera.
s16 camera_world_to_screen_x(s16 world_x);
// Convert integer-pixel world Y using the shared convenience camera.
s16 camera_world_to_screen_y(s16 world_y);

kitaqgb/lib/camera.h

cgb_palette.h — Palettes BG et OBJ de la CGB
c
#pragma once

// High-level CGB palette helpers for KITAQGB.
// Palette writes no-op on DMG; RGB packing works on either hardware model.

// Safe here means CGB hardware gating. Palette data writes still require an accessible
// PPU phase (for example LCD off or a sufficiently short VBlank update).
u8 __cgb_is_cgb();
void __cgb_safe_set_bcps(u8 value);
void __cgb_safe_set_bcpd(u8 value);
void __cgb_safe_set_ocps(u8 value);
void __cgb_safe_set_ocpd(u8 value);

// Mask each component to five bits: red in 0..4, green in 5..9, blue in 10..14.
// These macros wrap oversized components rather than saturating them.
#define CGB_RGB15(r5, g5, b5) ((u16)((u16)((r5) & 31) | ((u16)((g5) & 31) << 5) | ((u16)((b5) & 31) << 10)))

// Pack the red, green and blue components using the public RGB15 macro.
u16 cgb_rgb15(u8 r5, u8 g5, u8 b5);

// Set one background color through the indexed palette wrapper.
void cgb_bg_color(u8 palette_index, u8 color_index, u16 rgb15);
// Set one object color through the indexed palette wrapper.
void cgb_obj_color(u8 palette_index, u8 color_index, u16 rgb15);
// Pack component values and write one background color.
void cgb_bg_rgb(u8 palette_index, u8 color_index, u8 r5, u8 g5, u8 b5);
// Pack component values and write one object color.
void cgb_obj_rgb(u8 palette_index, u8 color_index, u8 r5, u8 g5, u8 b5);

// Write background colors starting at the indexed slot. The range may cross
// palette boundaries and is clamped only at the end of all 32 slots.
void cgb_bg_colors(u8 palette_index, u8 start_color_index, const u16* colors, u8 color_count);
// Write object colors from the indexed slot, potentially crossing into later palettes.
void cgb_obj_colors(u8 palette_index, u8 start_color_index, const u16* colors, u8 color_count);

// Write four consecutive colors for one background palette.
void cgb_bg_palette(u8 palette_index, const u16* colors);
// Write four consecutive colors for one object palette.
void cgb_obj_palette(u8 palette_index, const u16* colors);

// Expose sequential background writes using an absolute color-slot index.
void cgb_bg_colors_raw(u8 start_color_slot, const u16* colors, u8 color_count);
// Expose sequential object writes using an absolute color-slot index.
void cgb_obj_colors_raw(u8 start_color_slot, const u16* colors, u8 color_count);

kitaqgb/lib/cgb_palette.h

cgb_tile.h — Numéros et attributs de tuiles CGB
c
#pragma once

// Declarations for compiler-intrinsic CGB tile helpers.
// Canonical intrinsic entry points use the "__" prefix.
// Attr writes no-op on DMG. Combined tile+attr writes still write the tile on DMG.

// These helpers emit compiler code; cgb_tile.c has no runtime bodies. Scalar coordinates address 32x32 maps.
// Safe write paths poll VRAM access; LCD-on paths can enable interrupts after writing.
// Use _unsafe/_fast only with caller-managed writable VRAM timing, especially inside an ISR.
// Tile writes use the selected VRAM bank; choose bank zero before combined tile/attribute operations.
#define KQ_CGB_ATTR_PAL_MASK 0x07
#define KQ_CGB_ATTR_BANK1 0x08
#define KQ_CGB_ATTR_XFLIP 0x20
#define KQ_CGB_ATTR_YFLIP 0x40
#define KQ_CGB_ATTR_PRIORITY 0x80

#define KQ_CGB_ATTR_NONE ((u8)0)
#define KQ_CGB_ATTR_PAL(n) ((u8)((n) & KQ_CGB_ATTR_PAL_MASK))
#define KQ_CGB_ATTR_BANK(bank) ((u8)((bank) ? KQ_CGB_ATTR_BANK1 : 0))
#define KQ_CGB_ATTR_XFLIP_IF(enabled) ((u8)((enabled) ? KQ_CGB_ATTR_XFLIP : 0))
#define KQ_CGB_ATTR_YFLIP_IF(enabled) ((u8)((enabled) ? KQ_CGB_ATTR_YFLIP : 0))
#define KQ_CGB_ATTR_PRIORITY_IF(enabled) ((u8)((enabled) ? KQ_CGB_ATTR_PRIORITY : 0))
#define KQ_CGB_ATTR(palette, bank, xflip, yflip, priority) ((u8)(((palette) & KQ_CGB_ATTR_PAL_MASK) | ((bank) ? KQ_CGB_ATTR_BANK1 : 0) | ((xflip) ? KQ_CGB_ATTR_XFLIP : 0) | ((yflip) ? KQ_CGB_ATTR_YFLIP : 0) | ((priority) ? KQ_CGB_ATTR_PRIORITY : 0)))

// Return the compiler/runtime CGB mode test as a byte Boolean.
u8 __cgb_is_cgb();
// Write the VRAM bank selection only on CGB. Safe here means hardware-mode guarded, not PPU-timed.
void __cgb_safe_set_vbk(u8 value);

// Write a tile number to map 9800, waiting for VRAM access when necessary.
void __settile(u8 x, u8 y, u8 tile);
// Write a tile number to map 9800 without waiting for writable VRAM.
void __settile_unsafe(u8 x, u8 y, u8 tile);
// Write at base+32*y+x with VRAM access checks; supply a valid tile-map base.
void __settileat(u16 base, u8 x, u8 y, u8 tile);
// Use an explicit map base without waiting for VRAM access.
void __settileat_unsafe(u16 base, u8 x, u8 y, u8 tile);
// Select the window map from LCDC bit 6, then write a tile with access checks.
void __settilewin(u8 x, u8 y, u8 tile);
// Select the LCDC window map and write without access waits.
void __settilewin_unsafe(u8 x, u8 y, u8 tile);
// Select the background map from LCDC bit 3, then write with access checks.
void __settilebg(u8 x, u8 y, u8 tile);
// Select the LCDC background map and write without access waits.
void __settilebg_unsafe(u8 x, u8 y, u8 tile);

// Copy count sequential bytes to dest using the current VRAM bank and access-checked transfer.
void __settile_bulk(u16 dest, const u8* src, u8 count);
// Copy count sequential bytes to dest without VRAM access waits; retain source-bank visibility.
void __settile_bulk_fast(u16 dest, const u8* src, u8 count);

// Write attributes in bank one at map 9800 on CGB, then leave VBK zero; skip on DMG. Use the access-checked write path.
void __settileattr(u8 x, u8 y, u8 attr);
// Write attributes in bank one at map 9800 on CGB, then leave VBK zero; skip on DMG. No VRAM access waits are inserted.
void __settileattr_unsafe(u8 x, u8 y, u8 attr);
// Write tile and CGB attributes at map 9800; DMG receives only the tile write. Use the access-checked write path.
void __settilecgb(u8 x, u8 y, u8 tile, u8 attr);
// Write tile and CGB attributes at map 9800; DMG receives only the tile write. No VRAM access waits are inserted.
void __settilecgb_unsafe(u8 x, u8 y, u8 tile, u8 attr);

// Write attributes in bank one at the explicit map base on CGB, then leave VBK zero; skip on DMG. Use the access-checked write path.
void __settileatattr(u16 base, u8 x, u8 y, u8 attr);
// Write attributes in bank one at the explicit map base on CGB, then leave VBK zero; skip on DMG. No VRAM access waits are inserted.
void __settileatattr_unsafe(u16 base, u8 x, u8 y, u8 attr);
// Write tile and CGB attributes at the explicit map base; DMG receives only the tile write. Use the access-checked write path.
void __settileatcgb(u16 base, u8 x, u8 y, u8 tile, u8 attr);
// Write tile and CGB attributes at the explicit map base; DMG receives only the tile write. No VRAM access waits are inserted.
void __settileatcgb_unsafe(u16 base, u8 x, u8 y, u8 tile, u8 attr);

// Write attributes in bank one at the LCDC window map on CGB, then leave VBK zero; skip on DMG. Use the access-checked write path.
void __settilewinattr(u8 x, u8 y, u8 attr);
// Write attributes in bank one at the LCDC window map on CGB, then leave VBK zero; skip on DMG. No VRAM access waits are inserted.
void __settilewinattr_unsafe(u8 x, u8 y, u8 attr);
// Write tile and CGB attributes at the LCDC window map; DMG receives only the tile write. Use the access-checked write path.
void __settilewincgb(u8 x, u8 y, u8 tile, u8 attr);
// Write tile and CGB attributes at the LCDC window map; DMG receives only the tile write. No VRAM access waits are inserted.
void __settilewincgb_unsafe(u8 x, u8 y, u8 tile, u8 attr);

// Write attributes in bank one at the LCDC background map on CGB, then leave VBK zero; skip on DMG. Use the access-checked write path.
void __settilebgattr(u8 x, u8 y, u8 attr);
// Write attributes in bank one at the LCDC background map on CGB, then leave VBK zero; skip on DMG. No VRAM access waits are inserted.
void __settilebgattr_unsafe(u8 x, u8 y, u8 attr);
// Write tile and CGB attributes at the LCDC background map; DMG receives only the tile write. Use the access-checked write path.
void __settilebgcgb(u8 x, u8 y, u8 tile, u8 attr);
// Write tile and CGB attributes at the LCDC background map; DMG receives only the tile write. No VRAM access waits are inserted.
void __settilebgcgb_unsafe(u8 x, u8 y, u8 tile, u8 attr);

// Copy count attributes to dest in bank one on CGB, then leave VBK zero; skip on DMG. Transfers use access checks.
void __settileattr_bulk(u16 dest, const u8* src, u8 count);
// Copy count attributes to dest in bank one on CGB, then leave VBK zero; skip on DMG. The caller supplies writable VRAM timing.
void __settileattr_bulk_fast(u16 dest, const u8* src, u8 count);
// Copy tile and attribute streams to dest; DMG receives only tiles. Keep both sources readable. Transfers use access checks.
void __settilecgb_bulk(u16 dest, const u8* tile_src, const u8* attr_src, u8 count);
// Copy tile and attribute streams to dest; DMG receives only tiles. Keep both sources readable. The caller supplies writable VRAM timing.
void __settilecgb_bulk_fast(u16 dest, const u8* tile_src, const u8* attr_src, u8 count);

kitaqgb/lib/cgb_tile.h

chain.h — Tampons circulaires pour l'historique des positions
c
#pragma once

typedef __packed struct {
    s16 x;
    s16 y;
} ChainPoint;

typedef __packed struct {
    ChainPoint* points;
    u8 capacity;
    u8 count;
    u8 head;
} Chain;

// Attach caller-owned ring storage and start with no recorded points.
// The storage must remain valid for the lifetime of the chain.
// Use a valid chain pointer and capacity entries of caller-owned storage.
// Capacity at most 128 keeps every head+age sum in the byte range used by the reader.
void chain_init(Chain* chain, ChainPoint* storage, u8 capacity);
// Forget the recorded points without clearing or freeing the backing storage.
void chain_clear(Chain* chain);
// Move the ring head backward and store the newest point. Once full, each push
// replaces the oldest point; zero capacity is a no-op.
void chain_push_head(Chain* chain, s16 x, s16 y);
// Read a point by age, with index zero denoting the newest point. Return zero
// for an invalid request and clear a non-null output first. Keep head + index
// within the 8-bit range: addition is narrowed before the capacity wrap.
u8 chain_get_segment(const Chain* chain, u8 index, ChainPoint* out);
// Return the number of stored points, or zero for a null chain.
u8 chain_get_count(const Chain* chain);

// Return target minus current along the shortest wrapped route.
// Supply size 1..256 and coordinates in 0..size-1; inputs are not normalized.
// Exactly half a field retains the direct displacement sign.
s16 chain_wrap_delta(u8 target, u8 current, u16 size);

// Articulated body: one current pose per joint, including the head at index 0.
// Caller-owned byte arrays keep the inner loop compact on both GB and FC.
// Heading sectors run clockwise: 0=right, 4=down, 8=left, 12=up.
// Coordinates are pixels; each wrapped dimension accepts 1..256 pixels.
typedef __packed struct {
    u8* x;
    u8* y;
    u8* heading;
    u8 capacity;
    u8 count;
    u16 width;
    u16 height;
} ChainBody;

// Attach three non-overlapping capacity-byte arrays. Return 1 on success.
// Invalid storage, zero capacity or dimensions outside 1..256 disable the body.
u8 chain_body_init(ChainBody* body, u8* x, u8* y, u8* heading, u8 capacity, u16 width, u16 height);
// Seed count joints in a straight pose behind the head; count includes the head.
// Return 0 without changing the pose if count is zero or exceeds capacity.
// Coordinates wrap to the playfield and headings are masked to 0..15.
u8 chain_body_reset(ChainBody* body, u8 count, u8 head_x, u8 head_y, u8 heading);
// Install the caller's head pose, then pull joints from front to rear.
// Each joint aims four pixels behind its updated predecessor and receives that
// predecessor's OLD heading. Each axis moves 1 pixel, or 2 when error exceeds 4.
// Call once per simulation tick; this does not advance head physics or render.
void chain_body_step(ChainBody* body, u8 head_x, u8 head_y, u8 heading);
// Append a copy of the current tail; later steps separate the new joint.
// Return 1 on growth, or 0 for an empty, disabled or full body.
u8 chain_body_grow(ChainBody* body);
// Remove all joints while retaining caller-owned storage and playfield settings.
void chain_body_clear(ChainBody* body);

kitaqgb/lib/chain.h

danmaku.h — Réserves de projectiles, éventails, impacts et frôlements
c
#pragma once

// Fixed-capacity, allocation-free bullet field for a 160 x 128 play area.
// Positions/velocities are signed Q12.4 / Q4.4; +Y points down.
// Tile ids 0..15 encode the four 4x4 quadrants of an 8x8 tile.
// Reserve those tiles in VRAM, with a 3x3 bullet centered at (2,2)
// in every set quadrant. Other tile ids in the map are decoration.
#define DANMAKU_MAX 96
#define DANMAKU_MAP_BYTES 576
typedef __packed struct {
    s16 x;
    s16 y;
    s8 vx;
    s8 vy;
    u8 active;
    u8 grazed;
} DanmakuBullet;

extern DanmakuBullet dm_bullets[DANMAKU_MAX];
extern __wram __aligned(16) u8 dm_map[DANMAKU_MAP_BYTES];
extern u8 dm_count;
extern u8 dm_peak;
// Per-step hit is a Boolean latch; graze counts newly grazed bullets this step. Spawn/rejection counters wrap at 65536.
extern u8 dm_hit;
extern u8 dm_graze;
extern u8 dm_player_x;
extern u8 dm_player_y;
extern u8 dm_invulnerable;
extern u16 dm_spawned;
extern u16 dm_rejected;

// Reset pool, peak and lifetime counters; player fields and map contents remain caller-owned state.
void danmaku_reset();
// Deactivate the pool while retaining peak/spawn/rejection counters and the RAM map.
void danmaku_clear();
// Use pixel origins inside 160x128 and signed sixteenth-pixel velocities; return one if a slot was allocated.
u8 danmaku_spawn(u8 x, u8 y, s8 vx, s8 vy);
// Attempt a fan using wrapping 32-step angles; count is capped at 96 and speed at 64.
void danmaku_fan(u8 x, u8 y, u8 direction, u8 step, u8 count, u8 speed);
// 32 directions, 0=right, 8=down, 16=left, 24=up. speed in 1/16 px.
// Clear the 32x18 RAM map before drawing the next frame; no transfer is performed.
void danmaku_clear_map();
// Caller fills decoration after clear_map, then calls step to overlay bullets.
// hit and graze are events for this step. Collision uses rendered centers.
void danmaku_step();
// Requires CGB and LCD off or the beginning of VBlank. VBK restored to 0.
// Transfers 18 rows (32-byte stride) to BG map 9800 with 36-block GDMA.
void danmaku_present_now();

kitaqgb/lib/danmaku.h

debug.h — Enregistrements en RAM et assertions
c
#pragma once

// Use a capacity from 1 through 255; the length counter is a byte.
// Compile every unit with the same override so the array declaration and storage agree.
#ifndef DEBUG_TRACE_MAX
#define DEBUG_TRACE_MAX 32
#endif

// Each packed entry retains a name pointer and two 16-bit values; name text is not copied.
typedef __packed struct {
    const u8* name;
    u16 value;
    u16 frame;
} DebugTraceEntry;

extern DebugTraceEntry kq_debug_trace_log[DEBUG_TRACE_MAX];
extern u8 kq_debug_trace_count;
extern u16 kq_debug_frame;
extern u16 kq_debug_last_assert;

// Reset log length, frame tag and last assertion code; existing entry bytes are not erased.
void debug_init();
// Set the frame tag copied into subsequently recorded entries.
void debug_set_frame(u16 frame);
// Append a named frame marker using 0xFFFF as its value.
void debug_mark_frame(const u8* label);
// Append an unsigned byte value, widened to the log's 16-bit value field.
void debug_trace_u8(const u8* name, u8 value);
// Append a 16-bit value with the current frame tag.
void debug_trace_u16(const u8* name, u16 value);
// Record the assertion code and attempt to append an ASSERT entry. This helper
// does not halt execution, and the code is retained even if the log is full.
void debug_assert_fail(u16 code);
// Return the number of valid entries in the fixed trace buffer.
u8 debug_get_trace_count();
// Expose the internal trace array for inspection; use the count to bound reads.
const DebugTraceEntry* debug_get_trace_log();
// Read the last recorded assertion code, or the zero value installed by initialization.
u16 debug_get_last_assert();

#define KITAQGB_TRACE_U8(name, value) debug_trace_u8((const u8*)(name), (u8)(value))
#define KITAQGB_TRACE_U16(name, value) debug_trace_u16((const u8*)(name), (u16)(value))
#define KITAQGB_TRACE(name, value) debug_trace_u16((const u8*)(name), (u16)(value))
#define KITAQGB_MARK_FRAME(label) debug_mark_frame((const u8*)(label))
#define KITAQGB_ASSERT(cond) do { if (!(cond)) debug_assert_fail((u16)1); } while (0)
#define KITAQGB_ASSERT_CODE(cond, code) do { if (!(cond)) debug_assert_fail((u16)(code)); } while (0)

kitaqgb/lib/debug.h

dmg3d.h — Rendu filaire monochrome de 128×120 pour DMG
c
// Compatibility names for the shared wire3d_dmg renderer.
// Select the same profile in every translation unit; compile one renderer entry.
#pragma once
#ifndef WIRE3D_DMG_HEIGHT
#define WIRE3D_DMG_HEIGHT 120
#endif
#if WIRE3D_DMG_HEIGHT != 120
#error Incompatible wire3d_dmg profile
#endif
#include "wire3d_dmg.h"

// The aliases below add no calls or storage. Their contracts are documented at the corresponding wire3d_dmg.h declarations.
#define DMG3D_ANGLE_STEPS WIRE3D_DMG_ANGLE_STEPS
#define DMG3D_AUX_COL_BYTES WIRE3D_DMG_AUX_COL_BYTES
#define DMG3D_AUX_ROWS WIRE3D_DMG_AUX_ROWS
#define DMG3D_BG_QUEUE_LIMIT WIRE3D_DMG_BG_QUEUE_LIMIT
#define DMG3D_BeginFrame Wire3DDMG_BeginFrame
#define DMG3D_CENTER_X WIRE3D_DMG_CENTER_X
#define DMG3D_CENTER_Y WIRE3D_DMG_CENTER_Y
#define DMG3D_DrawIndexedEdges Wire3DDMG_DrawIndexedEdges
#define DMG3D_DrawLine2D Wire3DDMG_DrawLine2D
#define DMG3D_DrawLine3D Wire3DDMG_DrawLine3D
#define DMG3D_DrawModel Wire3DDMG_DrawModel
#define DMG3D_DrawModelScaled Wire3DDMG_DrawModelScaled
#define DMG3D_DrawScene Wire3DDMG_DrawScene
#define DMG3D_Edge Wire3DDMG_Edge
#define DMG3D_EdgeFaces Wire3DDMG_EdgeFaces
#define DMG3D_EndFrame Wire3DDMG_EndFrame
#define DMG3D_EraseModelFaces Wire3DDMG_EraseModelFaces
#define DMG3D_EraseSpan2D Wire3DDMG_EraseSpan2D
#define DMG3D_EraseTriangle2D Wire3DDMG_EraseTriangle2D
#define DMG3D_FACE_NONE WIRE3D_DMG_FACE_NONE
#define DMG3D_FAR_Z WIRE3D_DMG_FAR_Z
#define DMG3D_Face Wire3DDMG_Face
#define DMG3D_Init Wire3DDMG_Init
#define DMG3D_MODEL_FACE_LIMIT WIRE3D_DMG_MODEL_FACE_LIMIT
#define DMG3D_MODEL_HIDDEN_LINES WIRE3D_DMG_MODEL_HIDDEN_LINES
#define DMG3D_MODEL_VERTEX_LIMIT WIRE3D_DMG_MODEL_VERTEX_LIMIT
#define DMG3D_Model Wire3DDMG_Model
#define DMG3D_NEAR_Z WIRE3D_DMG_NEAR_Z
#define DMG3D_Object Wire3DDMG_Object
#define DMG3D_PROJECT_LIMIT WIRE3D_DMG_PROJECT_LIMIT
#define DMG3D_ProjectPoint Wire3DDMG_ProjectPoint
#define DMG3D_PutBgTile Wire3DDMG_PutBgTile
#define DMG3D_ROW_BYTES WIRE3D_DMG_ROW_BYTES
#define DMG3D_RotatePoint Wire3DDMG_RotatePoint
#define DMG3D_SCENE_OBJECT_LIMIT WIRE3D_DMG_SCENE_OBJECT_LIMIT
#define DMG3D_SCREEN_H WIRE3D_DMG_SCREEN_H
#define DMG3D_SCREEN_W WIRE3D_DMG_SCREEN_W
#define DMG3D_SetAuxTransfer Wire3DDMG_SetAuxTransfer
#define DMG3D_SetCamera Wire3DDMG_SetCamera
#define DMG3D_SetDirtyTransfer Wire3DDMG_SetDirtyTransfer
#define DMG3D_SetPalette Wire3DDMG_SetPalette
#define DMG3D_TILE_H WIRE3D_DMG_TILE_H
#define DMG3D_TILE_W WIRE3D_DMG_TILE_W
#define DMG3D_TRANSFORM_LIMIT WIRE3D_DMG_TRANSFORM_LIMIT
#define DMG3D_TransferAuxNow Wire3DDMG_TransferAuxNow
#define DMG3D_TransferMainNow Wire3DDMG_TransferMainNow
#define DMG3D_Vec3 Wire3DDMG_Vec3
// The remaining aliases retain internal identifiers for source compatibility; they do not define an independent renderer.
#define DMG3D_abs_i16 w3ddmg_abs_i16
#define DMG3D_angle_index w3ddmg_angle_index
#define DMG3D_aux_transfer_enabled w3ddmg_aux_transfer_enabled
#define DMG3D_bg_map_9800 w3ddmg_bg_map_9800
#define DMG3D_bgq_addr_hi w3ddmg_bgq_addr_hi
#define DMG3D_bgq_addr_lo w3ddmg_bgq_addr_lo
#define DMG3D_bgq_count w3ddmg_bgq_count
#define DMG3D_bgq_tile w3ddmg_bgq_tile
#define DMG3D_bgq_value w3ddmg_bgq_value
#define DMG3D_bgq_x w3ddmg_bgq_x
#define DMG3D_bgq_y w3ddmg_bgq_y
#define DMG3D_bit_mask w3ddmg_bit_mask
#define DMG3D_build_face_visibility w3ddmg_build_face_visibility
#define DMG3D_cam_pitch w3ddmg_cam_pitch
#define DMG3D_cam_roll w3ddmg_cam_roll
#define DMG3D_cam_x w3ddmg_cam_x
#define DMG3D_cam_y w3ddmg_cam_y
#define DMG3D_cam_yaw w3ddmg_cam_yaw
#define DMG3D_cam_z w3ddmg_cam_z
#define DMG3D_clamp_i16 w3ddmg_clamp_i16
#define DMG3D_clamp_screen w3ddmg_clamp_screen
#define DMG3D_clear_dirty_tables w3ddmg_clear_dirty_tables
#define DMG3D_clear_occlusion_mask w3ddmg_clear_occlusion_mask
#define DMG3D_clear_occlusion_mask_asm w3ddmg_clear_occlusion_mask_asm
#define DMG3D_clear_stage_asm w3ddmg_clear_stage_asm
#define DMG3D_clear_stage_aux_asm w3ddmg_clear_stage_aux_asm
#define DMG3D_clear_triangle w3ddmg_clear_triangle
#define DMG3D_clear_vram_asm w3ddmg_clear_vram_asm
#define DMG3D_cos_q6 w3ddmg_cos_q6
#define DMG3D_dirty_dst_hi w3ddmg_dirty_dst_hi
#define DMG3D_dirty_dst_lo w3ddmg_dirty_dst_lo
#define DMG3D_dirty_src_hi w3ddmg_dirty_src_hi
#define DMG3D_dirty_src_lo w3ddmg_dirty_src_lo
#define DMG3D_dirty_tiles w3ddmg_dirty_tiles
#define DMG3D_dirty_transfer_enabled w3ddmg_dirty_transfer_enabled
#define DMG3D_edge_area w3ddmg_edge_area
#define DMG3D_face_visible w3ddmg_face_visible
#define DMG3D_fill_bg_map_asm w3ddmg_fill_bg_map_asm
#define DMG3D_flush_bg_queue w3ddmg_flush_bg_queue
#define DMG3D_i16 w3ddmg_i16
#define DMG3D_i8 w3ddmg_i8
#define DMG3D_inv_depth w3ddmg_inv_depth
#define DMG3D_is_edge_visible w3ddmg_is_edge_visible
#define DMG3D_line_dx w3ddmg_line_dx
#define DMG3D_line_dy w3ddmg_line_dy
#define DMG3D_line_err w3ddmg_line_err
#define DMG3D_line_stage_asm w3ddmg_line_stage_asm
#define DMG3D_line_stage_masked_c w3ddmg_line_stage_masked_c
#define DMG3D_line_sx w3ddmg_line_sx
#define DMG3D_line_sy w3ddmg_line_sy
#define DMG3D_line_x w3ddmg_line_x
#define DMG3D_line_x0 w3ddmg_line_x0
#define DMG3D_line_x1 w3ddmg_line_x1
#define DMG3D_line_y w3ddmg_line_y
#define DMG3D_line_y0 w3ddmg_line_y0
#define DMG3D_line_y1 w3ddmg_line_y1
#define DMG3D_mark_line_dirty w3ddmg_mark_line_dirty
#define DMG3D_mark_model_occluder w3ddmg_mark_model_occluder
#define DMG3D_mark_rect_dirty w3ddmg_mark_rect_dirty
#define DMG3D_mark_tile_dirty w3ddmg_mark_tile_dirty
#define DMG3D_mark_triangle w3ddmg_mark_triangle
#define DMG3D_mask_get w3ddmg_mask_get
#define DMG3D_mask_offset w3ddmg_mask_offset
#define DMG3D_mask_set w3ddmg_mask_set
#define DMG3D_mask_set_span w3ddmg_mask_set_span
#define DMG3D_neg_angle w3ddmg_neg_angle
#define DMG3D_occlusion_active w3ddmg_occlusion_active
#define DMG3D_occlusion_mask w3ddmg_occlusion_mask
#define DMG3D_plot_stage_asm w3ddmg_plot_stage_asm
#define DMG3D_plot_tx w3ddmg_plot_tx
#define DMG3D_plot_x w3ddmg_plot_x
#define DMG3D_plot_y w3ddmg_plot_y
#define DMG3D_prev_dirty_tiles w3ddmg_prev_dirty_tiles
#define DMG3D_project_camera_space w3ddmg_project_camera_space
#define DMG3D_project_world w3ddmg_project_world
#define DMG3D_put_bg_tile_safe_asm w3ddmg_put_bg_tile_safe_asm
#define DMG3D_reg_bgp w3ddmg_reg_bgp
#define DMG3D_reg_lcdc w3ddmg_reg_lcdc
#define DMG3D_reg_ly w3ddmg_reg_ly
#define DMG3D_reg_scx w3ddmg_reg_scx
#define DMG3D_reg_scy w3ddmg_reg_scy
#define DMG3D_rotate_x w3ddmg_rotate_x
#define DMG3D_rotate_y w3ddmg_rotate_y
#define DMG3D_rotate_z w3ddmg_rotate_z
#define DMG3D_scene_depth w3ddmg_scene_depth
#define DMG3D_scene_object_depth w3ddmg_scene_object_depth
#define DMG3D_scene_order w3ddmg_scene_order
#define DMG3D_screen_delta w3ddmg_screen_delta
#define DMG3D_screen_visible w3ddmg_screen_visible
#define DMG3D_screen_x w3ddmg_screen_x
#define DMG3D_screen_y w3ddmg_screen_y
#define DMG3D_sin_q6 w3ddmg_sin_q6
#define DMG3D_stage w3ddmg_stage
#define DMG3D_stage_clear_pixel w3ddmg_stage_clear_pixel
#define DMG3D_stage_clear_span w3ddmg_stage_clear_span
#define DMG3D_transfer_dirty_stage w3ddmg_transfer_dirty_stage
#define DMG3D_transfer_dirty_tile_asm w3ddmg_transfer_dirty_tile_asm
#define DMG3D_transfer_stage_asm w3ddmg_transfer_stage_asm
#define DMG3D_transfer_stage_aux_asm w3ddmg_transfer_stage_aux_asm
#define DMG3D_u16 w3ddmg_u16
#define DMG3D_u8 w3ddmg_u8
#define DMG3D_vram_tiles w3ddmg_vram_tiles
#define DMG3D_wait_vblank_start w3ddmg_wait_vblank_start
#define dmg3d w3ddmg
#define dmg3d_pair_aux_block w3ddmg_pair_aux_block
#define dmg3d_pair_aux_done w3ddmg_pair_aux_done
#define dmg3d_pair_aux_wait_0 w3ddmg_pair_aux_wait_0
#define dmg3d_pair_aux_wait_1 w3ddmg_pair_aux_wait_1
#define dmg3d_pair_aux_wait_10 w3ddmg_pair_aux_wait_10
#define dmg3d_pair_aux_wait_11 w3ddmg_pair_aux_wait_11
#define dmg3d_pair_aux_wait_12 w3ddmg_pair_aux_wait_12
#define dmg3d_pair_aux_wait_13 w3ddmg_pair_aux_wait_13
#define dmg3d_pair_aux_wait_14 w3ddmg_pair_aux_wait_14
#define dmg3d_pair_aux_wait_15 w3ddmg_pair_aux_wait_15
#define dmg3d_pair_aux_wait_16 w3ddmg_pair_aux_wait_16
#define dmg3d_pair_aux_wait_17 w3ddmg_pair_aux_wait_17
#define dmg3d_pair_aux_wait_18 w3ddmg_pair_aux_wait_18
#define dmg3d_pair_aux_wait_19 w3ddmg_pair_aux_wait_19
#define dmg3d_pair_aux_wait_2 w3ddmg_pair_aux_wait_2
#define dmg3d_pair_aux_wait_20 w3ddmg_pair_aux_wait_20
#define dmg3d_pair_aux_wait_21 w3ddmg_pair_aux_wait_21
#define dmg3d_pair_aux_wait_22 w3ddmg_pair_aux_wait_22
#define dmg3d_pair_aux_wait_23 w3ddmg_pair_aux_wait_23
#define dmg3d_pair_aux_wait_24 w3ddmg_pair_aux_wait_24
#define dmg3d_pair_aux_wait_25 w3ddmg_pair_aux_wait_25
#define dmg3d_pair_aux_wait_26 w3ddmg_pair_aux_wait_26
#define dmg3d_pair_aux_wait_27 w3ddmg_pair_aux_wait_27
#define dmg3d_pair_aux_wait_3 w3ddmg_pair_aux_wait_3
#define dmg3d_pair_aux_wait_4 w3ddmg_pair_aux_wait_4
#define dmg3d_pair_aux_wait_5 w3ddmg_pair_aux_wait_5
#define dmg3d_pair_aux_wait_6 w3ddmg_pair_aux_wait_6
#define dmg3d_pair_aux_wait_7 w3ddmg_pair_aux_wait_7
#define dmg3d_pair_aux_wait_8 w3ddmg_pair_aux_wait_8
#define dmg3d_pair_aux_wait_9 w3ddmg_pair_aux_wait_9
#define dmg3d_pair_main_block w3ddmg_pair_main_block
#define dmg3d_pair_main_wait_0 w3ddmg_pair_main_wait_0
#define dmg3d_pair_main_wait_1 w3ddmg_pair_main_wait_1
#define dmg3d_pair_main_wait_10 w3ddmg_pair_main_wait_10
#define dmg3d_pair_main_wait_11 w3ddmg_pair_main_wait_11
#define dmg3d_pair_main_wait_12 w3ddmg_pair_main_wait_12
#define dmg3d_pair_main_wait_13 w3ddmg_pair_main_wait_13
#define dmg3d_pair_main_wait_14 w3ddmg_pair_main_wait_14
#define dmg3d_pair_main_wait_2 w3ddmg_pair_main_wait_2
#define dmg3d_pair_main_wait_3 w3ddmg_pair_main_wait_3
#define dmg3d_pair_main_wait_4 w3ddmg_pair_main_wait_4
#define dmg3d_pair_main_wait_5 w3ddmg_pair_main_wait_5
#define dmg3d_pair_main_wait_6 w3ddmg_pair_main_wait_6
#define dmg3d_pair_main_wait_7 w3ddmg_pair_main_wait_7
#define dmg3d_pair_main_wait_8 w3ddmg_pair_main_wait_8
#define dmg3d_pair_main_wait_9 w3ddmg_pair_main_wait_9
#define dmg3dac_col w3ddmgac_col
#define dmg3dac_enter w3ddmgac_enter
#define dmg3dac_row w3ddmgac_row
#define dmg3dbg_enter w3ddmgbg_enter
#define dmg3dco_enter w3ddmgco_enter
#define dmg3dco_loop w3ddmgco_loop
#define dmg3dco_page w3ddmgco_page
#define dmg3dcs_enter w3ddmgcs_enter
#define dmg3dcs_inner w3ddmgcs_inner
#define dmg3dcs_outer w3ddmgcs_outer
#define dmg3dcv_enter w3ddmgcv_enter
#define dmg3dcv_loop w3ddmgcv_loop
#define dmg3dcv_page w3ddmgcv_page
#define dmg3ddt_enter w3ddmgdt_enter
#define dmg3ddt_loop w3ddmgdt_loop
#define dmg3dfb_enter w3ddmgfb_enter
#define dmg3dfb_loop w3ddmgfb_loop
#define dmg3dfb_page w3ddmgfb_page
#define dmg3dls_branch w3ddmgls_branch
#define dmg3dls_done w3ddmgls_done
#define dmg3dls_enter w3ddmgls_enter
#define dmg3dls_shallow w3ddmgls_shallow
#define dmg3dls_shallow_loop w3ddmgls_shallow_loop
#define dmg3dls_shallow_skip_bridge w3ddmgls_shallow_skip_bridge
#define dmg3dls_steep w3ddmgls_steep
#define dmg3dls_steep_loop w3ddmgls_steep_loop
#define dmg3dls_steep_skip_bridge w3ddmgls_steep_skip_bridge
#define dmg3dls_x_reverse w3ddmgls_x_reverse
#define dmg3dls_y_reverse w3ddmgls_y_reverse
#define dmg3dls_y_start w3ddmgls_y_start
#define dmg3dps_enter w3ddmgps_enter
#define dmg3dps_ret w3ddmgps_ret

kitaqgb/lib/dmg3d.h

entity.h — Réserves d'objets fondées sur des tableaux fixes
c
#pragma once

// Keep capacity in 1..255: IDs and scan counters are bytes and FF is reserved for failure.
// Use the same definition in every compilation unit.
#ifndef ENTITY_MAX
#define ENTITY_MAX ((u8)16)
#endif

// Position, velocity, state and timer units are game-defined; the pool does not advance them.
// The sprite field is only bookkeeping and does not allocate or release OAM entries.
typedef __packed struct {
    u8 active;
    u8 type;
    s16 x;
    s16 y;
    s16 vx;
    s16 vy;
    u8 state;
    u8 timer;
    u8 sprite;
} Entity;

// An entity callback receives a slot ID, not a persistent object handle.
typedef void (*EntityFn)(u8 id);

// Reset every slot before the game starts using the pool.
void entity_init();
// Returns a reusable slot ID, or 0xFF if no slot is free.
u8 entity_create(u8 type, s16 x, s16 y);
// Release a valid slot without clearing its payload. Reallocation resets the payload;
// a saved pointer or ID must not be treated as a persistent entity identity.
void entity_destroy(u8 id);
// Returns null for an invalid or inactive ID; the returned pointer aliases reusable pool storage.
Entity* entity_get(u8 id);
// Call fn for each slot that is active when the scan reaches it; null is a no-op.
// Callbacks may change the pool, so newly activated later slots can run in this pass.
void entity_update_all(EntityFn fn);
// Use the same active-slot traversal for drawing; the callback supplies all rendering.
void entity_draw_all(EntityFn fn);
// Count occupied slots without changing entity state.
u8 entity_count_active();
// Release every entity and restore deterministic defaults, including the no-sprite sentinel.
void entity_clear_all();

kitaqgb/lib/entity.h

fixed.h — Calcul en virgule fixe Q8.8 et rectangles
c
#pragma once

// Signed Q8.8 uses 256 units per pixel/value: the range is -128 to 127 + 255/256.
typedef s16 fix8;

#define FIX_ONE ((fix8)256)
#define FIX_HALF ((fix8)128)

typedef __packed struct {
    fix8 x;
    fix8 y;
} Vec2;

typedef __packed struct {
    s16 x;
    s16 y;
    s16 w;
    s16 h;
} KQRect;

// Convert an integer to signed 8.8 fixed point by moving it into the high byte.
// The caller must keep the result within the representable 16-bit range.
fix8 fix_from_int(s16 n);
// Discard the eight fractional bits using a signed right shift.
s16 fix_to_int(fix8 x);
// Approximate 8.8 multiplication by discarding four low bits from each operand
// before multiplying. This trades precision for a smaller intermediate product.
fix8 fix_mul(fix8 a, fix8 b);
// Scale the reduced-precision quotient back to 8.8 and return zero for b == 0.
// Callers must also ensure (b >> 4) is nonzero; the explicit check only tests b.
// The intermediate product must fit the compiler's integer arithmetic.
fix8 fix_div(fix8 a, fix8 b);
// Interpolate toward b using a quantized Q0.8 weight. Both shifts discard low
// bits, so small changes may vanish and a weight of 255 need not reach b.
fix8 fix_lerp(fix8 a, fix8 b, u8 t_q8);
// Return the magnitude in s16. The most-negative s16 has no positive s16
// representation and must be excluded by callers needing a nonnegative result.
s16 kq_abs_s16(s16 v);
// Select the smaller signed value.
s16 kq_min_s16(s16 a, s16 b);
// Select the larger signed value.
s16 kq_max_s16(s16 a, s16 b);
// Clamp to an inclusive interval; callers must provide lo <= hi.
s16 kq_clamp_s16(s16 v, s16 lo, s16 hi);
// Test overlap using exclusive right/bottom edges; touching edges do not collide.
// Require positive dimensions and edge sums that fit s16; zero-sized rectangles
// are not explicitly rejected and may be reported as overlapping.
u8 kq_rect_intersect(KQRect a, KQRect b);
// Test a half-open rectangle: left/top edges are included, right/bottom excluded.
// The coordinate-plus-size sums must remain representable as s16.
u8 kq_point_in_rect(s16 x, s16 y, KQRect r);

kitaqgb/lib/fixed.h

input.h — État des boutons, appuis, relâchements et répétition
c
#pragma once

#define BTN_RIGHT  ((u8)0x01)
#define BTN_LEFT   ((u8)0x02)
#define BTN_UP     ((u8)0x04)
#define BTN_DOWN   ((u8)0x08)
#define BTN_A      ((u8)0x10)
#define BTN_B      ((u8)0x20)
#define BTN_SELECT ((u8)0x40)
#define BTN_START  ((u8)0x80)

// A fresh press pulses immediately. The next pulse occurs DELAY + 1 updates later.
#ifndef INPUT_REPEAT_DELAY
#define INPUT_REPEAT_DELAY ((u8)18)
#endif

// Subsequent pulses are RATE + 1 updates apart; zero repeats on every held update.
#ifndef INPUT_REPEAT_RATE
#define INPUT_REPEAT_RATE ((u8)5)
#endif

extern u8 kq_input_prev_keys;
extern u8 kq_input_keys;
extern u8 kq_input_press_keys;
extern u8 kq_input_release_keys;
extern u8 kq_input_repeat_keys;

u16 __readpadex(u8 prev_keys);

// Clear sampled/edge state and initialize an independent repeat timer for each button.
void input_init();
// Sample input once per game tick and derive press, release and repeat masks.
// Repeat delays are measured in calls to this function, not elapsed wall-clock time.
void input_update();
// Return whether any masked button is currently held.
u8 input_down(u8 mask);
// Return whether any masked button became pressed in the latest sample.
u8 input_pressed(u8 mask);
// Return whether any masked button became released in the latest sample.
u8 input_released(u8 mask);
// Return whether any masked button produced a fresh press or scheduled repeat pulse.
u8 input_repeat(u8 mask);
// Return the complete held-button mask from the latest update.
u8 input_current();
// Return the held-button mask that preceded the latest update.
u8 input_previous();

#define btn_down input_down
#define btn_pressed input_pressed
#define btn_released input_released
#define btn_repeat input_repeat

kitaqgb/lib/input.h

link.h — Communication série et paquets logiques
c
#pragma once

// Shared Game Boy serial link library for KITAQGB projects.
//
// Integration notes:
// - Compile a hardware-register file before link.c / link_packet.c so SB, SC,
//   IF_REG, and IE_REG are already declared.
// - Call Link_InitMaster() on the clock-source side and Link_InitSlave() on the
//   other side.
// - Call Link_Poll() or Link_PollPacket() regularly from the main loop.
// - If you enable serial IRQ mode, call Link_OnSerialIRQ() from your own
//   serial interrupt handler at vector 0x0058.
// - The packet layer is intentionally small and one-deep. It works best as a
//   master-driven command/response layer. The low-level byte API remains the
//   escape hatch for custom protocols.

#define LINK_MODE_SLAVE   ((u8)0)
#define LINK_MODE_MASTER  ((u8)1)

#define LINK_CLOCK_NORMAL ((u8)0)
#define LINK_CLOCK_FAST   ((u8)1)

#define LINK_ERR_NONE        ((u8)0)
#define LINK_ERR_BUSY        ((u8)1)
#define LINK_ERR_TIMEOUT     ((u8)2)
#define LINK_ERR_OVERFLOW    ((u8)3)
#define LINK_ERR_PROTOCOL    ((u8)4)
#define LINK_ERR_DISCONNECT  ((u8)5)

#define LINK_PKT_MAX_PAYLOAD ((u8)24)
#define LINK_RX_QUEUE_SIZE   ((u8)8)
#define LINK_TX_QUEUE_SIZE   ((u8)8)

#define LINK4_MODE_NONE      ((u8)0)
#define LINK4_MODE_HOST      ((u8)1)
#define LINK4_MODE_PEER      ((u8)2)
#define LINK4_MAX_PLAYERS    ((u8)4)
#define LINK4_HOST_SLOT      ((u8)0)
#define LINK4_INVALID_SLOT   ((u8)0xFF)

// Reset byte queues, packet mailboxes, cooperative-peer state and errors, then
// disable serial transfers and serial IRQ delivery. Existing data is discarded.
void Link_InitCommon();
// Reset link state and select the internal-clock role for subsequent transfers.
void Link_InitMaster();
// Reset link state and select the external-clock role for subsequent transfers.
void Link_InitSlave();
// Enable or disable serial IRQ delivery and clear its pending flag. Enabling
// does not install the handler. Leaving its outer critical section enables CPU interrupts.
void __stackcall Link_SetUseInterrupt(u8 on);
// Select the fast-clock bit for future master transfers; this does not restart
// an active transfer or verify that the hardware supports CGB fast mode.
void __stackcall Link_SetFastClock(u8 on);

// Poll once before returning busy state, so this query may collect a completed byte.
u8 Link_IsBusy();
// Read the ordinary receive-ready flag without polling hardware.
u8 Link_HasByte();
// Return the latest latched error without clearing it.
u8 Link_LastError();
// Clear the error latch without resetting queues or an active transfer.
void Link_ClearError();

// Start one full-duplex byte exchange, or return BUSY without replacing an
// active transfer. Slave mode arms reception and waits for external clocks.
u8 __stackcall Link_BeginTransfer(u8 out);
// Collect a pending transfer only after hardware clears the SC start bit.
void Link_Poll();
// Stop the hardware transfer under interrupt protection. Queued receive bytes
// and packet-layer state remain available; this is not a full protocol reset.
void Link_Cancel();
// Acknowledge serial IRQ and finish a software-busy transfer. Call this from
// the actual serial interrupt handler, not an unrelated interrupt.
void Link_OnSerialIRQ();

// Pop the ordinary receive queue without waiting or polling hardware; null discards a byte.
u8 __stackcall Link_TryReadByte(u8 *out);
// Pop one byte, returning zero when empty. Use Link_TryReadByte when a received
// zero byte must be distinguished from an empty queue.
u8 Link_ReadByte();
// Require an output pointer, poll immediately, then wait at most timeout_frames
// VBlanks for a byte. Zero timeout still performs the initial poll and read.
u8 __stackcall Link_WaitByte(u16 timeout_frames, u8 *out);

// Validate payload size and idle packet state, copy payload bytes into owned
// storage and schedule transmission. Return success means queued, not acknowledged;
// keep polling to progress the exchange and inspect the error latch.
u8 __stackcall Link_SendPacket(const u8 *data, u8 len, u8 cmd);
// Drain received bytes, advance one outgoing exchange and update the retry
// timer. Timeout ticks count calls without progress, not hardware frames; call
// with a controlled cadence and avoid mixing raw reads with packet consumption.
void Link_PollPacket();
// Inspect the shared completed-packet flag without advancing the protocol.
u8 Link_HasPacket();
// Consume the shared packet mailbox and its matching peer flag. Any output
// may be null; a nonnull destination needs room for the received payload because
// there is no destination-capacity argument.
u8 __stackcall Link_ReadPacket(u8 *cmd, u8 *len, u8 *dst);

// Cooperative 4-player adapter helpers.
//
// This layer models the common host-selected adapter pattern:
// - Slot 0 is always the host.
// - The host selects one active peer slot at a time.
// - Packet mailboxes stay one-deep per peer.
// - The original Link_* API remains available for normal 2-player projects.
// Reset as master, validate slot count and select logical peer one. Invalid configuration still discards old link state.
u8 __stackcall Link4_InitHost(u8 slot_count);
// Reset as slave and validate the local nonzero slot and total slot count.
// An invalid configuration still discards the previous link state.
u8 __stackcall Link4_InitPeer(u8 local_slot, u8 slot_count);
// Return the configured cooperative role; this is not a hardware connection probe.
u8 Link4_GetMode();
// Return the configured zero-based local slot.
u8 Link4_GetLocalSlot();
// Return the configured number of logical slots, not a live connection count.
u8 Link4_GetSlotCount();
// Return the current logical destination, or the invalid-slot sentinel when unset.
u8 Link4_GetSelectedPeer();
// Return the peer attributed to the last completed byte transfer.
u8 Link4_GetLastRxPeer();
// Return the peer attributed when the last byte transfer was started.
u8 Link4_GetLastTxPeer();
// Poll completion, then change the logical destination only while byte and
// packet state are idle. A peer can select only the host. No adapter-routing
// command is sent here; the transport must provide the matching physical route.
u8 __stackcall Link4_SelectPeer(u8 peer_slot);
// Select the logical peer and start a byte exchange, returning the first error.
u8 __stackcall Link4_BeginTransferTo(u8 peer_slot, u8 out);
// Inspect a valid peer ring without polling the hardware.
u8 __stackcall Link4_HasByteFrom(u8 peer_slot);
// Pop one byte from the selected peer ring; null output discards it.
u8 __stackcall Link4_TryReadByteFrom(u8 peer_slot, u8 *out);
// Scan remote rings in increasing slot order and return the first available
// byte. Null output pointers are allowed; lower slots have polling priority.
u8 __stackcall Link4_TryReadByteAny(u8 *peer_slot, u8 *out);
// Select a logical peer, then copy and schedule a packet; return the first error.
u8 __stackcall Link4_SendPacketTo(u8 peer_slot, const u8 *data, u8 len, u8 cmd);
// Advance the shared packet engine; this does not poll every logical peer in turn.
void Link4_PollPacket();
// Inspect the one-packet mailbox for a valid remote slot without consuming it.
u8 __stackcall Link4_HasPacketFrom(u8 peer_slot);
// Consume a peer mailbox, copying to optional outputs. A nonnull destination
// needs room for the entire payload. Clear the shared mailbox only when it
// refers to this same peer.
u8 __stackcall Link4_ReadPacketFrom(u8 peer_slot, u8 *cmd, u8 *len, u8 *dst);

kitaqgb/lib/link.h

link_dmg07.h — Communication DMG-07 avec horloge externe
c
#pragma once

// Polling driver for the physical Nintendo DMG-07 Four Player Adapter.
//
// The adapter supplies every serial clock.  LinkDmg07_Poll() must therefore be
// called frequently enough to re-arm the serial port between adapter bytes;
// calling it only once per video frame is not sufficient.  Call
// LinkDmg07_TickFrame() exactly once per frame for timeout accounting.
//
// Transmission uses SIZE=1: every adapter packet contains four bytes, one for
// each physical player slot.  A console sends its local byte during byte 0 and
// sends zero during bytes 1..3, except while emitting an aligned FF restart
// packet.  The adapter broadcasts those four submitted bytes in the following
// packet.  The initial broadcast contains undefined adapter data and is
// discarded by this driver.

#define LINK_DMG07_PHASE_PING       ((u8)0)
#define LINK_DMG07_PHASE_REQUEST_AA ((u8)1)
#define LINK_DMG07_PHASE_WAIT_CC    ((u8)2)
#define LINK_DMG07_PHASE_TRANSFER   ((u8)3)

#define LINK_DMG07_MAX_PLAYERS  ((u8)4)
#define LINK_DMG07_PACKET_BYTES ((u8)4)
#define LINK_DMG07_SIZE         ((u8)1)
// Physical slots here are one-based; do not substitute the zero-based Link4 cooperative slot identifiers.
#define LINK_DMG07_NO_SLOT      ((u8)0)

// RATE $10 gives the shortest documented packet period for SIZE=1 while
// retaining the adapter's normal inter-byte pacing.  RATE $00 is not used.
#define LINK_DMG07_DEFAULT_RATE ((u8)0x10)

#ifndef LINK_DMG07_TIMEOUT_FRAMES
#define LINK_DMG07_TIMEOUT_FRAMES ((u8)12)
#endif

#define LINK_DMG07_ERR_NONE        ((u8)0)
#define LINK_DMG07_ERR_STATE       ((u8)1)
#define LINK_DMG07_ERR_NOT_PLAYER1 ((u8)2)
#define LINK_DMG07_ERR_NOT_READY   ((u8)3)
#define LINK_DMG07_ERR_TIMEOUT     ((u8)4)
#define LINK_DMG07_ERR_PROTOCOL    ((u8)5)
#define LINK_DMG07_ERR_OVERFLOW    ((u8)6)

#define LINK_DMG07_RESTART_NONE    ((u8)0)
#define LINK_DMG07_RESTART_PENDING ((u8)1)
#define LINK_DMG07_RESTART_SENDING ((u8)2)

// Initializes polling-only external-clock operation.  A zero RATE is replaced
// with LINK_DMG07_DEFAULT_RATE.  This driver disables only the serial IRQ bit.
void __stackcall LinkDmg07_Init(u8 rate);

// Services at most one completed serial byte and immediately re-arms SC=$80.
// Call continuously from the main loop, including between VBlanks.
void LinkDmg07_Poll();

// Advances saturating frame-based silence and handshake timeout counters.
void LinkDmg07_TickFrame();

// Return the discovery, start-handshake or transfer phase without polling.
u8 LinkDmg07_GetPhase();
// Return the one-based player slot, or LINK_DMG07_NO_SLOT before discovery.
u8 LinkDmg07_GetLocalSlot();

// Normalized mask: bit 0 is player 1, ..., bit 3 is player 4.
u8 LinkDmg07_GetConnectedMask();
// Return the last validated raw adapter status byte.
u8 LinkDmg07_GetLastStatus();
// Read the completed-discovery status flag without clearing it.
u8 LinkDmg07_HasPingStatus();
// Clear and report the completed-discovery flag; return zero if no new status exists.
u8 LinkDmg07_ConsumePingStatus();

// Only physical player 1 may request AA AA AA AA.  The bytes are aligned to
// the next FE/status/status/status ping packet.  All consoles enter transfer
// mode only after receiving four consecutive CC bytes.
u8 LinkDmg07_RequestTransmission();

// Any physical slot may schedule FF FF FF FF at the next four-byte packet
// boundary while remaining in TRANSFER phase.  The driver keeps sending aligned
// FF bytes until it sees the adapter's complete all-FF indicator packet, then
// returns to PING.  A transfer-phase silence timeout schedules the same recovery
// automatically and preserves the current byte position for clocks that resume.
u8 LinkDmg07_RequestRestart();
// Return whether aligned recovery is absent, pending or sending control traffic.
u8 LinkDmg07_GetRestartState();

// Sets the byte sampled when byte 0 of the next adapter packet is armed.
// Set it before the current packet completes (and before requesting start for
// the first submission).  During normal transfer, bytes 1..3 are sent as zero.
void __stackcall LinkDmg07_SetLocalByte(u8 value);

// The first incoming adapter data packet is discarded.  Thereafter ReadPacket
// copies four bytes in physical slot order (players 1..4).
u8 LinkDmg07_IsPipelinePrimed();
// Inspect the one-packet receive mailbox without consuming it.
u8 LinkDmg07_HasPacket();
// Consume the latest four-byte packet. A nonnull destination must hold four
// bytes; null discards the packet. Packet storage remains after the flag clears.
u8 __stackcall LinkDmg07_ReadPacket(u8 *dst);
// Read one cached player byte using a one-based slot. Invalid slots return
// zero; the function neither requires readiness nor consumes the packet.
u8 __stackcall LinkDmg07_GetPacketSlot(u8 player_slot);

// SentSequence increments when this console's packet byte is clocked out.
// PacketSequence labels the returned four-byte packet.  For a valid packet it
// is one less than SentSequence, making the DMG-07 one-packet delay explicit.
u8 LinkDmg07_GetSentSequence();
// Return the modulo-256 sequence associated with the most recently published packet.
u8 LinkDmg07_GetPacketSequence();

// SilenceFrames is reset by every completed serial byte.  TimeoutCount counts
// distinct serial-silence or AA/CC/restart handshake timeouts. DisconnectCount counts
// adapter-silence outages and ping-status membership drops.  All saturate.
u8 LinkDmg07_GetSilenceFrames();
// Return the saturating lifetime timeout count, preserved across protocol restarts.
u8 LinkDmg07_GetTimeoutCount();
// Return the saturating count of removed-player and previously-seen-adapter timeout events.
u8 LinkDmg07_GetDisconnectCount();
// Return the saturating protocol/overflow error count. Timeout and request
// validation paths use separate counters or latches and do not increment this value.
u8 LinkDmg07_GetErrorCount();
// Return the latest error latch without clearing counters or restarting the protocol.
u8 LinkDmg07_LastError();
// Clear only the latest error code, preserving counters and protocol state.
void LinkDmg07_ClearError();

kitaqgb/lib/link_dmg07.h

physics2d.h — Mouvement et collisions en 2D
c
#pragma once

// Position and velocity use caller-selected integer units with one integration
// step per call; no hidden pixel or time conversion occurs. Keep intermediate
// signed arithmetic in range. World/body storage is owned by the caller.
#include "fixed.h"

// Multiply a signed word by a signed byte; divide by 256, truncating toward zero.
s16 __smul16x8(s16 a, s8 b);

// Lightweight deterministic 2D physics for KITAQGB.
// Integer pixels per step are one possible unit convention; inv_mass is Q8.

typedef struct {
    s16 x;
    s16 y;
    s16 vx;
    s16 vy;
    s16 half_x;
    s16 half_y;
    s16 inv_mass_q8;      // 0 means static body.
    s16 restitution_q8;   // 0..255 (reserved for future tuning).
    u8 active;
} KQBody2D;

typedef struct {
    KQBody2D* bodies;
    u8 body_count;
    s16 gravity_x;
    s16 gravity_y;
    u8 solver_iterations;
    s16 max_speed;
} KQWorld2D;

// Retain the caller-owned body array without initializing its elements.
// Set gravity to (0,32), four contact iterations and a per-axis speed limit of 512.
// A null world is ignored; the array must outlive subsequent world operations.
void kq2d_world_init(KQWorld2D* world, KQBody2D* bodies, u8 body_count);
// Advance active dynamic bodies, then visit each active unordered pair for
// the configured contact passes (zero means one). Static bodies still participate
// as obstacles. The world borrows its array and shares non-reentrant ASM scratch.
// This is discrete integration; fast bodies can pass through thin obstacles.
void kq2d_step(KQWorld2D* world);
// For one active dynamic body, add gravity, clamp each velocity axis and then
// add velocity to position. Null inputs are ignored; no contacts are solved.
// Use a nonnegative speed limit and keep additions in signed 16-bit range.
void kq2d_integrate_body(KQWorld2D* world, KQBody2D* body);
// Test strict overlap of two centered boxes; touching edges return false.
// Both pointers must be valid. Active/mass flags are ignored, and coordinate
// differences and extent sums must fit the signed 16-bit calculations.
u8 kq2d_overlap_aabb(const KQBody2D* a, const KQBody2D* b);
// Initialize an active unit-inverse-mass body at the supplied center and half
// extents, with zero velocity and reserved restitution set to zero. Null is ignored.
void kq2d_body_init(KQBody2D* body, s16 x, s16 y, s16 half_x, s16 half_y);
// Replace the center without altering velocity, extents or activity. Null is ignored.
void kq2d_body_set_pos(KQBody2D* body, s16 x, s16 y);
// Replace velocity without clamping or checking activity/mass. Null is ignored.
void kq2d_body_set_velocity(KQBody2D* body, s16 vx, s16 vy);
// Add gravity and clamp each velocity axis separately for an active dynamic
// body. Null, inactive and static bodies are ignored. Supply a nonnegative limit
// and avoid overflow in the additions before clamping; position is unchanged.
void kq2d_body_apply_gravity(KQBody2D* body, s16 gravity_x, s16 gravity_y, s16 max_speed);
// Scale both velocities through the signed 8-bit coefficient intrinsic.
// Despite the unsigned parameter, values 128..255 become negative coefficients;
// this is not a full-range unsigned Q8 damping helper. Null is ignored.
void kq2d_body_apply_friction(KQBody2D* body, u8 friction_q8);
// Delegate strict rectangle overlap to the fixed-point utility; edge-only
// contact is false. Coordinate-plus-size sums must remain representable as s16.
u8 kq2d_rect_intersect(KQRect a, KQRect b);
// Delegate the half-open point test: include left/top and exclude right/bottom.
// Coordinate-plus-size sums must remain representable as s16.
u8 kq2d_point_in_rect(s16 x, s16 y, KQRect r);

// Opt-in surface solver. Velocities/threshold/kick share the caller's units.
// Normal must be unit length in Q8; coefficients are 0..255.
typedef struct {
    s16 nx_q8;
    s16 ny_q8;
    s16 vx;
    s16 vy;
    s16 bounce_threshold;
    s16 kick;
    u8 restitution_q8;
    u8 friction_q8;
} KQSurface2D;

// Truncates toward zero, including negative values; coefficient is -256..256.
s16 kq2d_scale_q8(s16 value, s16 coefficient);
// Conservative circular bound, with a shared Q8 scale for both components.
// Quantizes toward zero; very small limits relative to input may yield zero.
// Components and positive max_speed must be <= 16383 in magnitude.
void kq2d_body_limit_speed(KQBody2D* body, s16 max_speed);
// Kinematic surface response; returns incoming normal speed, or zero if separating.
// Caller resolves penetration separately. Relative components must fit +/-8191.
s16 kq2d_body_resolve_surface(KQBody2D* body, const KQSurface2D* surface);
// Linear crossing time in Q8 (0..256); positive separation is outside.
// Returns 0 for initial overlap, 256 for no crossing. Gaps must fit +/-8191.
u16 kq2d_surface_toi_q8(s16 start_gap, s16 end_gap);

kitaqgb/lib/physics2d.h

physics2d_circle.h — Physique des cercles
c
#pragma once

// Deterministic 2D circle physics for KITAQGB.
// Intended for top-down ball games such as billiards, air hockey, and marbles.

// Use consistent caller-selected units for centers, radii and per-step velocity.
// The implementation uses 16-bit arithmetic: reduced squared-distance sums and
// weight products must fit their types. Reduction to byte-sized components alone
// is insufficient to guarantee this. Body storage remains caller-owned.
typedef struct {
    s16 x;
    s16 y;
    s16 vx;
    s16 vy;
    s16 radius;
    s16 inv_mass_q8;      // 0 means static body.
    u8 restitution_q8;    // 0..255, higher means bouncier.
    u8 friction_q8;       // 0..255, higher removes more tangential motion.
    u8 active;
} KQCircleBody2D;

typedef struct {
    KQCircleBody2D* bodies;
    u8 body_count;
    s16 gravity_x;
    s16 gravity_y;
    u8 solver_iterations;
    s16 max_speed;
    u8 linear_damping_q8;   // 255 is almost no damping, lower values damp faster.
    u8 use_bounds;
    s16 min_x;
    s16 min_y;
    s16 max_x;
    s16 max_y;
    u8 wall_restitution_q8;
    u8 wall_friction_q8;
} KQCircleWorld2D;

// Retain a caller-owned array without initializing bodies. Set zero gravity,
// four contact passes, per-axis limit 768 and damping 252/256; bounds start disabled.
// A null world is ignored. Keep the array alive for subsequent steps.
void kq2dc_world_init(KQCircleWorld2D* world, KQCircleBody2D* bodies, u8 body_count);
// Store and enable bounds without validating their order or fitting bodies
// immediately. Supply extents large enough for body diameters. Null is ignored.
void kq2dc_set_bounds(KQCircleWorld2D* world, s16 min_x, s16 min_y, s16 max_x, s16 max_y);
// Integrate active dynamic bodies, apply bounds, solve contacts, then damp
// velocity and snap components in -1..1 to zero. Zero solver iterations means one.
// Pairs with both velocities zero are skipped, so resting overlaps can remain.
// Bounds can reposition static bodies; null world/array inputs are ignored.
void kq2dc_step(KQCircleWorld2D* world);
// Compare a reduced integer center distance with the reduced radius sum.
// Valid pointers and positive radii are required; activity and mass are ignored.
// This approximate test requires representable differences, radius sums and
// squared-distance sum. Touching at the computed distance returns false.
u8 kq2dc_overlap_circle(const KQCircleBody2D* a, const KQCircleBody2D* b);

kitaqgb/lib/physics2d_circle.h

physics3d.h — Physique des AABB en 3D
c
#pragma once

// Lightweight deterministic 3D physics for KITAQGB.
// AABB contacts, acceleration, mass-weighted bounce, and impact state flags.

// The game owns break decisions: the solver records impact speeds but never
// sets this flag or deactivates a body based on break_speed. Positions, extents,
// velocities and acceleration use consistent caller-selected per-step units.
#define KQ3D_BODY_BROKEN ((u8)0x01)

typedef struct {
    s16 x;
    s16 y;
    s16 z;
    s16 vx;
    s16 vy;
    s16 vz;
    s16 ax;
    s16 ay;
    s16 az;
    s16 half_x;
    s16 half_y;
    s16 half_z;
    s16 mass_q8;        // 256 means mass 1.0.
    s16 inv_mass_q8;    // 0 means static body.
    s16 restitution_q8; // 256 means perfectly elastic.
    s16 break_speed;    // Reserved for game-side impact thresholds.
    s16 last_impact_speed;
    u8 active;
    u8 flags;
} KQBody3D;

typedef struct {
    KQBody3D* bodies;
    u8 body_count;
    s16 gravity_x;
    s16 gravity_y;
    s16 gravity_z;
    u8 solver_iterations;
    s16 max_speed;
} KQWorld3D;

// Borrow the body array without initializing it. Set gravity (0,24,0), four
// contact passes and a per-axis speed limit of 512. Null world is ignored;
// the caller retains ownership and must keep the array alive.
void kq3d_world_init(KQWorld3D* world, KQBody3D* bodies, u8 body_count);
// Initialize an active centered box with zero velocity/acceleration,
// restitution 224, cleared impact/flags and mass set through the weight helper.
// The caller supplies valid half extents. Null body is ignored.
void kq3d_body_init(KQBody3D* body, s16 x, s16 y, s16 z, s16 half_x, s16 half_y, s16 half_z, s16 mass_q8);
// Store the requested mass; nonpositive mass makes the body static.
// For positive mass compute inverse weight as max(1,32767/max(mass,64)).
// The stored mass retains the original input; this is a relative solver weight,
// not an exact Q8 reciprocal. Null body is ignored.
void kq3d_body_set_mass(KQBody3D* body, s16 mass_q8);
// Integrate active dynamic bodies and reset their impact values, then solve
// each active unordered pair for the configured passes (zero means one).
// Static bodies retain previous impact maxima until the game clears them.
// Acceleration persists; flags and break thresholds remain game-owned.
// This discrete solver shares non-reentrant ASM scratch and can miss fast crossings.
void kq3d_step(KQWorld3D* world);
// Reset impact for one active dynamic body, add gravity and persistent body
// acceleration, clamp velocity per axis and advance position. Static/inactive
// bodies retain impact state. Null inputs are ignored; no contacts are solved.
// Use a nonnegative speed limit and avoid overflow before clamping.
void kq3d_integrate_body(KQWorld3D* world, KQBody3D* body);
// Test strict overlap on all three axes; face-only contact returns false.
// Valid pointers are required and flags are ignored. Center differences and
// extent sums must fit the signed 16-bit magnitude calculations.
u8 kq3d_overlap_aabb(const KQBody3D* a, const KQBody3D* b);

// Sum three signed products, shifting each by eight bits before addition.
// Coefficients are signed bytes scaled by 1/256; the 16-bit sum is not saturated.
s16 kq3d_dot_q8_8(s16 x, s16 y, s16 z, s8 ax, s8 ay, s8 az);

kitaqgb/lib/physics3d.h

raster.h — Tables de défilement par bandes et lignes
c
#pragma once

#include "scroll.h"

// Keep wrapper capacity consistent with the compiler split-table capacity; wrapper checks do not enlarge it.
#define KQ_RASTER_MAX_BANDS 8

#define KQ_RASTER_OK        0
#define KQ_RASTER_FULL      1
#define KQ_RASTER_BAD_LY    2
#define KQ_RASTER_UNSORTED  3
#define KQ_RASTER_BAD_RANGE 4

#define KQ_RASTER_BG        KQ_SCROLL_SPLIT_USE_BG
#define KQ_RASTER_WIN       KQ_SCROLL_SPLIT_USE_WIN
#define KQ_RASTER_WIN_SHOW  KQ_SCROLL_SPLIT_WIN_SHOW
#define KQ_RASTER_WIN_HIDE  KQ_SCROLL_SPLIT_WIN_HIDE
#define KQ_RASTER_BG_COLOR0 KQ_SCROLL_SPLIT_BG_COLOR0
#define KQ_RASTER_FLAG_MASK 0x1F

#define KQ_RASTER_LINE_FLAT        0
#define KQ_RASTER_LINE_X_TITLE     1
#define KQ_RASTER_LINE_TRAVEL_GATE 2

// Caller-owned wave state. Initialize it before use and keep it non-null for every LineX operation.
// frame_counter measures RunFrame calls, not an independent hardware clock.
typedef struct RasterLineX {
    u8 profile;
    u8 base_x;
    u8 phase;
    u8 phase_step;
    u8 frame_divider;
    u8 frame_counter;
} RasterLineX;

// Stop split scheduling, empty the shared table and clear error/count state.
void Raster_Init();
// Stop splits immediately and clear bookkeeping. Build and commit a new table to restart.
void Raster_Clear();
// Commit an empty split table so no raster bands remain active.
void Raster_Disable();

// Read the number of bands currently recorded by this wrapper.
u8 Raster_GetCount();
// Read the last stored status without clearing it.
u8 Raster_GetLastError();

// Append a validated background-scroll band and advance the monotonic-LY
// bookkeeping. A successful append clears the previous error.
u8 Raster_Push(u8 ly, u8 scx, u8 scy);
// Append a validated extended band after masking flags to supported operations.
u8 Raster_PushEx(u8 ly, u8 scx, u8 scy, u8 wx, u8 wy, u8 flags);

// Enable window updates and pass hardware WX/WY values without coordinate conversion.
u8 Raster_PushWindowRaw(u8 ly, u8 wx, u8 wy, u8 flags);
// Convert screen X to hardware WX by adding seven, then queue a window band.
// The byte addition wraps if callers supply an excessive X coordinate.
u8 Raster_PushWindowScreen(u8 ly, u8 screen_x, u8 screen_y, u8 flags);
// Queue both background and window updates, converting window screen X to WX.
u8 Raster_PushBgWindowScreen(u8 ly, u8 scx, u8 scy, u8 screen_x, u8 screen_y, u8 flags);
// Pack a 15-bit color into the extended band's two scroll-byte fields and select
// the color-zero operation, which interprets those fields as color data.
u8 Raster_PushBgColor0(u8 ly, u16 rgb15);

// Publish pending splits and return the stored status. This commits even if an
// earlier append failed; callers should inspect errors while building the table.
u8 Raster_Commit();

// Validate the HUD height, then replace pending splits with a fixed top band
// and scrolling playfield. The new table still requires an explicit commit.
u8 Raster_BuildHudTop(u8 hud_height, u8 camera_x, u8 camera_y);
// Build a scrolling upper playfield and fixed bottom HUD after validating the split.
u8 Raster_BuildHudBottom(u8 hud_y, u8 camera_x, u8 camera_y);

// Build two horizontal-scroll bands sharing one vertical scroll value.
u8 Raster_BuildParallax2(u8 split_y, u8 far_scx, u8 near_scx, u8 scy);
// Build three horizontal-scroll bands at ordered visible split lines. Invalid
// parameters leave the previous pending table intact and set the error status.
u8 Raster_BuildParallax3(u8 y1, u8 y2, u8 scx0, u8 scx1, u8 scx2, u8 scy);

// Initialize a scanline-wave state with phase zero and one phase step per frame.
void Raster_LineXInit(RasterLineX* effect, u8 profile, u8 base_x);
// Change the wave profile and restart its phase/divider counter.
void Raster_LineXSetProfile(RasterLineX* effect, u8 profile);
// Configure the phase increment and frame interval; clamp a zero interval to one.
void Raster_LineXSetSpeed(RasterLineX* effect, u8 phase_step, u8 frame_divider);
// Set the byte phase directly without resetting the frame-divider counter.
void Raster_LineXSetPhase(RasterLineX* effect, u8 phase);
// Look up the selected periodic profile at LY + phase and add base X modulo
// 256. An unknown profile returns the unmodified base X.
u8 Raster_LineXGetOffset(const RasterLineX* effect, u8 ly);
// Render all 144 visible lines with one SCX write per line, then advance phase.
// This foreground renderer masks interrupts during the visible frame. Do game
// and audio work between calls; do not combine it with a STAT raster driver.
// Returns without changing the effect when the LCD is off.
void Raster_LineXRunFrame(RasterLineX* effect);

kitaqgb/lib/raster.h

rpg.h — Nombres aléatoires, texte, cartes, sauvegardes et services RPG/ADV/SLG
c
#pragma once

// The application supplies frame/cursor/font tiles at these indices; these constants do not load graphics.
#ifndef TEXT_TILE_FILL
#define TEXT_TILE_FILL ((u8)0)
#endif
#ifndef TEXT_TILE_FRAME_TL
#define TEXT_TILE_FRAME_TL ((u8)1)
#endif
#ifndef TEXT_TILE_FRAME_TR
#define TEXT_TILE_FRAME_TR ((u8)2)
#endif
#ifndef TEXT_TILE_FRAME_BL
#define TEXT_TILE_FRAME_BL ((u8)3)
#endif
#ifndef TEXT_TILE_FRAME_BR
#define TEXT_TILE_FRAME_BR ((u8)4)
#endif
#ifndef TEXT_TILE_FRAME_H
#define TEXT_TILE_FRAME_H ((u8)5)
#endif
#ifndef TEXT_TILE_FRAME_V
#define TEXT_TILE_FRAME_V ((u8)6)
#endif
#ifndef TEXT_TILE_CURSOR
#define TEXT_TILE_CURSOR ((u8)7)
#endif
#ifndef TEXT_TILE_PAGE_WAIT
#define TEXT_TILE_PAGE_WAIT ((u8)8)
#endif
#ifndef TEXT_DIGIT_BASE
#define TEXT_DIGIT_BASE ((u8)'0')
#endif

#define TEXT_CTRL_END       ((u8)0x00)
#define TEXT_CTRL_NEWLINE   ((u8)0x0A)
#define TEXT_CTRL_WAIT      ((u8)0x01)
#define TEXT_CTRL_PAGE_WAIT ((u8)0x02)

#define PAD_KEY_RIGHT  ((u8)0x01)
#define PAD_KEY_LEFT   ((u8)0x02)
#define PAD_KEY_UP     ((u8)0x04)
#define PAD_KEY_DOWN   ((u8)0x08)
#define PAD_KEY_A      ((u8)0x10)
#define PAD_KEY_B      ((u8)0x20)
#define PAD_KEY_SELECT ((u8)0x40)
#define PAD_KEY_START  ((u8)0x80)

// Default layout: four 512-byte slots, each with a six-byte header and at most 506 payload bytes.
#define SAVE_SLOT_COUNT ((u8)4)
#define SAVE_SLOT_SIZE  ((u16)512)
#define SAVE_MAGIC0     ((u8)0x4B)
#define SAVE_MAGIC1     ((u8)0x51)
#define SAVE_VERSION    ((u8)1)

#define SAVE_OK         ((u8)1)
#define SAVE_ERR        ((u8)0)

// A bank byte plus a CPU-visible address forms this data reference; it does not switch banks by itself.
typedef __packed struct {
    u8 bank;
    const u8* ptr;
} far_ptr_t;

typedef __packed struct {
    u8 x;
    u8 y;
    u8 w;
    u8 h;
    const u8* const* items;
    u8 count;
    u8 cursor;
} menu_t;

typedef __packed struct {
    u8 id;
    u8 qty;
    const u8* name;
} item_t;

// Packed nine-byte ordinary-map descriptor. Tile IDs use bank_tiles; collision bits and event bytes
// use the descriptor bank. Width/height are tile cells, with row-major data.
typedef __packed struct {
    u8 width;
    u8 height;
    u8 bank_tiles;
    const u8* tiles;
    const u8* collision_bits;
    const void* events;
} map_t;

// One 2x2 metatile: four tile IDs plus collision, palette metadata and event ID.
// The map drawing routine uses tile IDs only; it does not apply palette attributes.
typedef __packed struct {
    u8 tile_tl;
    u8 tile_tr;
    u8 tile_bl;
    u8 tile_br;
    u8 collision;
    u8 palette;
    u8 event;
} metatile_t;

// Metatile dimensions count 2x2 cells. bank_tiles=0 means use the descriptor bank;
// nonzero bank_tiles supplies both ID-array and definition-table reads.
typedef __packed struct {
    u8 width;
    u8 height;
    u8 bank_tiles;
    const u8* metatile_ids;
    const metatile_t* metatiles;
} metatile_map_t;

typedef __packed struct {
    u8 x;
    u8 y;
    u8 w;
    u8 h;
    const u8* const* items;
    u8 count;
    u8 cursor;
    u8 prev_keys;
    u8 selected;
    u8 cancelled;
} menu_state_t;

typedef __packed struct {
    u8 x;
    u8 y;
    u8 hp;
    u8 move;
    u8 atk_min;
    u8 atk_max;
    u8 team;
    u8 acted;
} unit_t;

void __wait_vblank();
u16 __readpadex(u8 prev_keys);
u16 __getbgmapbase();
void __memset(void* dst, u8 value, u16 count);
void __memcpy(void* dst, const void* src, u16 count);
void __settile(u8 x, u8 y, u8 tile);
void __settilebg(u8 x, u8 y, u8 tile);
void __settileat(u16 base, u8 x, u8 y, u8 tile);
void __vram_memcpy(u16 dst, const void* src, u16 len);
void __vram_memset(u16 dst, u8 value, u16 len);
void __far_memcpy(void* dst, u8 bank, const void* src, u16 len);
u8 __rng8();
void __rng_seed(u16 seed);
void __scroll_bg_set(u8 scx, u8 scy);

void __settile_xy(u8 x, u8 y, u8 tile);
void __settile_rect(u8 x, u8 y, u8 w, u8 h, u8 tile);
void __settile_row(u8 x, u8 y, const u8* src, u8 len);
void __settile_col(u8 x, u8 y, const u8* src, u8 len);
void __fill_tilemap(u16 base, u8 tile, u16 count);
void __settilemap_rect(u16 base, u8 x, u8 y, u8 w, u8 h, const u8* src);

void __vram_copy(u16 dst, const void* src, u16 len);
void __vram_fill(u16 dst, u8 value, u16 len);
void __vram_copy_hblank(u16 dst, const void* src, u16 len);
void __vram_copy_dma(u16 dst, const void* src, u16 len);

u8 __farpeek8(u8 bank, const void* addr);
u16 __farpeek16(u8 bank, const void* addr);
void __farmemcpy(void* dst, u8 bank, const void* src, u16 len);
// The current GB backend evaluates/discards these arguments but emits no indirect call.
void __farcall_ptr(u8 bank, const void* func);

#define far_read8(p) __farpeek8((p).bank, (p).ptr)
#define far_read16(p) __farpeek16((p).bank, (p).ptr)
#define far_read_block(dst, p, len) __farmemcpy((dst), (p).bank, (p).ptr, (len))

void __memcpy_small(void* dst, const void* src, u8 len);
void __memset_small(void* dst, u8 value, u8 len);
void __copy16(void* dst, const void* src);
void __copy32(void* dst, const void* src);

u16 __tile_addr(u16 base, u8 x, u8 y);
u16 __map_index(u8 x, u8 y, u8 width);
u8 __xy_in_rect(u8 x, u8 y, u8 rx, u8 ry, u8 rw, u8 rh);
u8 __manhattan(u8 x1, u8 y1, u8 x2, u8 y2);

u8 __bit_test(const u8* p, u16 bit_index);
void __bit_set(u8* p, u16 bit_index);
void __bit_clear(u8* p, u16 bit_index);
void __bit_toggle(u8* p, u16 bit_index);

// Compiler intrinsic, separate from the RAM rle_decode helpers below; it is not a bounded-stream API.
u16 __rle_decode_vram(u16 dst, u8 bank, const void* src);

// Advance the compiler-provided pseudorandom generator and return one byte.
u8 rng8();
// Consume two generator bytes in high-byte/low-byte order to form a 16-bit value.
u16 rng16();
// Reduce a random byte modulo max; zero returns zero without consuming randomness.
// Modulo reduction is biased unless max divides the generator range.
u8 rand_range(u8 max);
// Select an index from cumulative byte weights using a 16-bit random draw.
// A zero total, including an empty list, returns zero; callers must distinguish
// that case from a valid index. Modulo reduction can introduce a small bias.
u8 weighted_choice(const u8* weights, u8 count);
// Replace the generator seed so subsequent calls can reproduce a sequence.
void rng_seed(u16 seed);
// Alias the byte generator; this consumes one generator step.
u8 rng_next8();
// Alias the two-step 16-bit generator.
u16 rng_next16();
// Alias rand_range and return a value in [0,max), or zero when max is zero.
u8 rng_range(u8 max);
// Return false for zero and true for values at least 100. Intermediate values
// use the modulo-based range generator, so percentages are approximate.
u8 rng_chance(u8 percent);

// Set the tile-space window, reset its cursor and redraw it immediately.
// Opening does not reset the existing character speed or load font tiles.
void text_open(u8 x, u8 y, u8 w, u8 h);
// Erase the open window with the fill tile and disable windowed character output.
void text_close();
// Decode an END-terminated stream of tile bytes and newline/wait/page controls.
// WAIT consumes a following frame-count byte. The source must remain readable
// through blocking waits; the routine does not validate stream length.
void text_print(const u8* str);
// Decode the same text controls while fetching each byte from the specified
// ROM bank. The pointer advances within that bank; it does not roll into the next bank.
void text_print_far(u8 bank, const u8* str);
// Redraw choices and block for edge-triggered navigation: UP/DOWN wrap, A
// accepts, and B returns 0xFF. Zero choices also returns 0xFF. Choice strings
// use raw tile bytes, and the caller must fit them inside the available rows.
u8 text_choice(const u8* const* choices, u8 count);
// Set VBlank waits per windowed character; zero prints without character delays.
void text_set_speed(u8 speed);
// Open and redraw a window using the same tile-space arguments as text_open.
void text_window(u8 x, u8 y, u8 w, u8 h);
// Fill the supplied tile rectangle without changing the active text window or cursor.
void text_clear_rect(u8 x, u8 y, u8 w, u8 h);
// Draw a zero-terminated tile string at absolute tile coordinates, without
// window clipping, control codes or the windowed printing delay.
void text_print_xy(u8 x, u8 y, const u8* str);
// Print an unsigned byte in decimal using only the required number of cells.
void text_print_u8(u8 x, u8 y, u8 value);
// Print an unsigned word in decimal using only the required number of cells.
void text_print_u16(u8 x, u8 y, u16 value);
// Print a minus tile for negative values, followed by the unsigned magnitude.
// Positive values use the unsigned decimal path; no plus sign is emitted.
void text_print_s16(u8 x, u8 y, s16 value);

// Replace the active script and clear wait, choice and saved-return state.
void script_run(u8 bank, const u8* script);
// Execute commands until an output/choice yields (0), a wait yields (1), or
// execution ends (2). Control/flag commands continue within the same call, so
// a script loop without a yielding command can block the game loop indefinitely.
u8 script_step();
// Set the number of subsequent script_step calls to spend waiting. Frame-based
// timing requires the application to call script_step once per frame.
void script_wait_frames(u8 n);

// Run a blocking menu loop with wraparound up/down selection, A to accept
// and B to cancel. Return 0xFF for an empty menu or cancellation. Item strings
// and menu dimensions must fit the visible tile area.
u8 menu_run(const menu_t* menu);
// Open a two-choice dialog and return the text-choice result (YES first, NO second).
u8 menu_yesno();
// Run a blocking item menu, drawing names and two-digit quantities. Return
// the selected index or 0xFF on empty input/B; this does not consume an item.
u8 menu_inventory(const item_t* items, u8 count);
// Initialize a nonblocking menu state that borrows the item pointer table.
// Selection starts unset (0xFF), and the cancellation flag starts clear.
void menu_init_state(menu_state_t* state, u8 x, u8 y, u8 w, u8 h, const u8* const* items, u8 count);
// Draw the current menu and cursor without waiting or sampling input. The
// caller schedules suitable display timing and keeps item text within bounds.
void menu_draw(menu_state_t* state);
// Sample new button presses and update cursor/selection state without drawing.
// Selected and cancelled results remain latched; a B press in the same update
// as A clears selection and leaves cancellation set.
void menu_update(menu_state_t* state);
// Read the latched selection without clearing it; null state returns 0xFF.
u8 menu_get_selected(menu_state_t* state);
// Read the latched cancellation flag; null state returns false.
u8 menu_was_cancelled(menu_state_t* state);

// Load the nine-byte ordinary-map descriptor and draw up to 20 by 18 tiles
// from its top-left corner. Drawing does not upload tile graphics or clear
// background cells beyond smaller map dimensions.
void map_load(u8 bank, const map_t* map);
// Use metatile collision when that mode is active; otherwise read one packed
// collision bit. Missing maps/out-of-range cells block movement, but a valid
// ordinary map without a collision array is entirely passable.
u8 map_is_blocked(u8 x, u8 y);
// Report whether an event exists at the cell. Ordinary maps expose a Boolean
// byte-presence test; metatile maps reduce their event ID to a Boolean here.
u8 map_trigger_at(u8 x, u8 y);
// Center an ordinary-map tile coordinate within a 20-by-18 viewport and clamp
// the scroll origin to its edges. This adjusts scroll registers only; it does
// not stream newly exposed map rows into VRAM.
void camera_center(u8 x, u8 y);
// Select metatile mode, copy its descriptor and draw the initial viewport
// with the camera at cell (0,0).
void map_load_metatile(u8 bank, const metatile_map_t* map);
// Draw a 10-by-9 metatile viewport as 20-by-18 individual background tiles.
// Out-of-range cells use definition zero; palette attributes are not written.
// Remember the camera and clear the dirty flag after the full redraw.
void map_draw_visible(u8 camera_tx, u8 camera_ty);
// Read a row-major metatile ID, returning ID zero for inactive or out-of-range
// lookups. Callers must provide a usable definition for metatile zero.
u8 map_get_metatile(u8 tx, u8 ty);
// Return the selected definition's palette byte. An out-of-range coordinate
// uses the metatile-zero fallback; this function does not write CGB attributes.
u8 map_get_attr(u8 tx, u8 ty);
// Treat out-of-range metatile cells as solid; otherwise inspect the definition
// collision flag. In ordinary-map mode, delegate to its packed collision bits.
u8 map_is_solid(u8 tx, u8 ty);
// Return a metatile event ID, or the ordinary-map Boolean trigger result.
// Missing/out-of-range metatile cells have no event.
u8 map_get_event(u8 tx, u8 ty);
// Mark the viewport for a full redraw when a valid metatile cell changes.
// The coordinate is validated but no per-cell dirty list is retained.
void map_mark_dirty(u8 tx, u8 ty);
// Redraw the remembered metatile viewport only when the shared dirty flag is set.
void map_flush_dirty();

// Validate slot and payload length, write payload bytes, then write the header
// and checksum. Return one after completing the writes; interruption can leave
// a partially replaced slot, so this is not transactional save storage.
u8 save_write(u8 slot, const void* data, u16 len);
// Require matching magic/version, exact requested length and a valid checksum
// before copying data into the destination. Validation failure leaves the
// destination unchanged. An invalid slot returns before touching RAM control;
// validation failures after enabling RAM disable it before returning zero.
u8 save_read(u8 slot, void* data, u16 len);
// Validate a slot's header, payload bounds and checksum without copying the
// payload out. A nonzero result means the stored record passes these checks.
u8 save_exists(u8 slot);
// Initialize the expected RAM access state and leave cartridge RAM disabled.
// Existing slot contents are preserved.
void save_init();
// Alias the checked save_read operation.
u8 save_load(u8 slot, void* data, u16 len);
// Alias save_exists, including its header and checksum validation.
u8 save_check(u8 slot);
// Zero the complete selected slot, including header and payload; invalid slot
// IDs are ignored. Cartridge RAM is disabled when clearing finishes.
void save_clear(u8 slot);

// Build movement costs, then convert reachable cells to one and unreachable
// 0xFF cells to zero. The caller provides one output byte per current-map cell
// and a valid unit origin; path-search workspace limits also apply.
u8 unit_move_range(unit_t* u, u8* out_mask);
// Mark cells whose Manhattan distance falls within the inclusive attack range.
// This geometric mask does not test obstacles, line of sight or other units.
u8 unit_attack_range(unit_t* u, u8* out_mask);
// A unit can act only while HP is nonzero and its acted flag is clear.
// The unit pointer must refer to a valid record.
u8 unit_can_act(const unit_t* u);

// Find a shortest cardinal path with BFS and write direction codes 0=up,
// 1=right, 2=down, 3=left. Return its byte length, or zero for failure or an
// already-reached goal. The caller supplies max_len output bytes and respects
// the shared workspace/distance limits; excessive paths are not truncated.
u8 path_find_bfs(u8 sx, u8 sy, u8 gx, u8 gy, u8* out_path, u8 max_len);
// Flood cardinal neighbors at unit cost, stopping expansion at the movement
// limit and rejecting blocked destinations. Initialize output to 0xFF only
// after validating the map and origin; invalid input leaves output unchanged.
void range_fill_move(u8 sx, u8 sy, u8 move, u8* out_costmap);

// Read a bit from the flag array. Callers must keep id below 2048.
u8 flag_get(u16 id);
// Set a flag bit without disturbing adjacent flags; id must be below 2048.
void flag_set(u16 id);
// Clear a flag bit; id must be below 2048.
void flag_clear(u16 id);
// Read a quest-state byte; quest_id must be below 64.
u8 quest_state(u8 quest_id);
// Replace a quest-state byte without validating its game-specific meaning.
// The caller must keep quest_id below 64.
void quest_set_state(u8 quest_id, u8 state);

// Expand count/value byte pairs until a zero count terminates the stream.
// The caller must provide a valid terminator and sufficient destination storage;
// there are no source or destination bounds parameters. Return the 16-bit byte count.
u16 rle_decode(void* dst, const void* src);
// Decode the same count/value format using bank-qualified reads for every source
// byte. Keep the encoded stream within the supplied bank/address mapping and
// provide enough destination space; a zero count ends the stream.
u16 rle_decode_far(void* dst, u8 bank, const void* src);

// Return the active map width in its own cell units, or zero when no map is loaded.
u8 map_current_width();
// Return the active map height in its own cell units, or zero when no map is loaded.
u8 map_current_height();

kitaqgb/lib/rpg.h

scene.h — Enregistrement, changement et mise à jour des scènes
c
#pragma once

typedef void (*SceneFunc)();

// Callbacks may be null. Keep the table and non-null targets readable for its lifetime.
// These plain function pointers do not carry a ROM bank number.
typedef __packed struct {
    SceneFunc enter;
    SceneFunc update;
    SceneFunc draw;
    SceneFunc exit;
} SceneDef;

// Attach the caller-owned scene table and clear current-scene state without invoking callbacks.
void scene_init(const SceneDef* scenes, u8 count);
// Replace the table by resetting scene state; this does not call the old scene's exit handler.
void scene_set_table(const SceneDef* scenes, u8 count);
// Ignore invalid IDs; otherwise exit the current scene and enter the requested one.
// Selecting the current ID still performs exit/enter. Callbacks run synchronously.
void scene_change(u8 scene_id);
// Clear the change flag before calling the active scene's update handler, so a
// transition made during that handler is visible afterward.
void scene_update();
// Call the active scene's draw handler if one exists; no current scene is a no-op.
void scene_draw();
// Return the stored scene ID; zero is also returned before the first transition.
u8 scene_get_current();
// Read the transition flag, which is cleared at the start of an active scene update.
u8 scene_was_changed();

kitaqgb/lib/scene.h

scroll.h — Arrière-plan, fenêtre et défilement fractionné
c
#pragma once

// Flags select operations in a raster split; raw window X includes the hardware +7 offset.
#define KQ_SCROLL_SPLIT_USE_BG   0x01
#define KQ_SCROLL_SPLIT_USE_WIN  0x02
#define KQ_SCROLL_SPLIT_WIN_SHOW 0x04
#define KQ_SCROLL_SPLIT_WIN_HIDE 0x08
#define KQ_SCROLL_SPLIT_BG_COLOR0 0x10

void __scroll_bg_set(u8 scx, u8 scy);
void __scroll_bg_x_set(u8 scx);
void __scroll_bg_y_set(u8 scy);
u8 __scroll_bg_x_get();
u8 __scroll_bg_y_get();

void __scroll_win_set(u8 wx, u8 wy);
void __scroll_win_x_set(u8 wx);
void __scroll_win_y_set(u8 wy);
u8 __scroll_win_x_get();
u8 __scroll_win_y_get();

void __scroll_bg_set_buffered(u8 scx, u8 scy);
void __scroll_bg_x_set_buffered(u8 scx);
void __scroll_bg_y_set_buffered(u8 scy);
void __scroll_win_set_buffered(u8 wx, u8 wy);
void __scroll_win_x_set_buffered(u8 wx);
void __scroll_win_y_set_buffered(u8 wy);
void __scroll_flush();

void __scroll_split_reset();
void __scroll_split_push(u8 ly, u8 scx, u8 scy);
void __scroll_split_push_ex(u8 ly, u8 scx, u8 scy, u8 wx, u8 wy, u8 flags);
void __scroll_split_commit();

void __scroll_win_show();
void __scroll_win_hide();
void __scroll_bg_add(s8 dx, s8 dy);
void __scroll_win_add(s8 dx, s8 dy);

// Reset background scroll to zero and place the window at screen origin
// using hardware WX=7 and WY=0.
void Scroll_Init();
// Write both hardware background-scroll bytes immediately.
void Scroll_SetBg(u8 scx, u8 scy);
// Write horizontal background scroll while leaving vertical scroll unchanged.
void Scroll_SetBgX(u8 scx);
// Write vertical background scroll while leaving horizontal scroll unchanged.
void Scroll_SetBgY(u8 scy);
// Read the tracked current background X; this is not a direct SCX register read.
u8 Scroll_GetBgX();
// Read the tracked current background Y; pending and raster-only values are excluded.
u8 Scroll_GetBgY();

// Write raw hardware WX/WY values; callers add seven to a screen-space window X.
void Scroll_SetWindow(u8 wx, u8 wy);
// Write raw hardware WX without converting a screen-space X coordinate.
void Scroll_SetWindowX(u8 wx);
// Write the window Y coordinate through the intrinsic.
void Scroll_SetWindowY(u8 wy);
// Read tracked current WX, including its seven-pixel offset; not a live hardware read.
u8 Scroll_GetWindowX();
// Read tracked current WY; pending and raster-only values are excluded.
u8 Scroll_GetWindowY();

// Stage background-scroll values in the intrinsic buffer for a later flush.
void Scroll_SetBgBuffered(u8 scx, u8 scy);
// Stage raw window-coordinate values for a later flush.
void Scroll_SetWindowBuffered(u8 wx, u8 wy);
// Apply the buffered scroll/window state through the compiler runtime.
void Scroll_Flush();

// Apply signed deltas to the byte-sized background-scroll coordinates.
void Scroll_BgAdd(s8 dx, s8 dy);
// Apply signed deltas to the byte-sized hardware window coordinates.
void Scroll_WindowAdd(s8 dx, s8 dy);
// Request window visibility through the compiler intrinsic.
void Scroll_WindowShow();
// Request that the window be hidden through the compiler intrinsic.
void Scroll_WindowHide();

// Clear the pending split table before building a new raster configuration.
void Scroll_SplitReset();
// Append a background-scroll split directly. Use Raster_Push when caller-side
// scanline ordering and capacity validation are desired.
void Scroll_SplitPush(u8 ly, u8 scx, u8 scy);
// Append an extended split with raw background/window fields and operation flags.
void Scroll_SplitPushEx(u8 ly, u8 scx, u8 scy, u8 wx, u8 wy, u8 flags);
// Reuse the two background-scroll fields to carry the low/high RGB15 bytes
// for a split whose operation flag selects background color zero.
void Scroll_SplitPushBgColor0(u8 ly, u16 rgb15);
// Publish the pending split configuration through the compiler runtime.
void Scroll_SplitCommit();

kitaqgb/lib/scroll.h

slg.h — Plateaux, listes de coups et annulation
c
#pragma once

// A row-major byte board. Storage is borrowed; cell values and coordinates have game-defined meaning.
typedef __packed struct {
    u8 width;
    u8 height;
    u8* cells;
} SLGBoard;

typedef __packed struct {
    u8 x;
    u8 y;
    u8 value;
} SLGMove;

typedef __packed struct {
    SLGMove* items;
    u8 count;
    u8 capacity;
} SLGMoveList;

// Undo records are retained cell values only; popping one does not apply it to a board.
typedef __packed struct {
    SLGMove* items;
    u8 count;
    u8 capacity;
} SLGUndoStack;

// Attach width * height bytes of caller-owned cell storage without clearing it.
void slg_board_init(SLGBoard* board, u8 width, u8 height, u8* cells);
// Fill every cell with value; a null board is ignored. A valid board must own
// enough accessible cell storage for its declared dimensions.
void slg_board_clear(SLGBoard* board, u8 value);
// Return zero for a null board or out-of-range coordinate; otherwise read the
// cell. Zero therefore cannot distinguish an invalid lookup from an empty cell.
u8 slg_board_get(const SLGBoard* board, u8 x, u8 y);
// Write a cell only when the board and coordinate are valid.
void slg_board_set(SLGBoard* board, u8 x, u8 y, u8 value);
// Attach caller-owned move storage and reset the list length.
void slg_move_list_init(SLGMoveList* list, SLGMove* items, u8 capacity);
// Forget the moves without erasing their storage; a null list is ignored.
void slg_move_list_clear(SLGMoveList* list);
// Append coordinates and a value to the bounded move list. Return zero on a
// null/full list without replacing any existing move.
u8 slg_move_list_push(SLGMoveList* list, u8 x, u8 y, u8 value);
// Attach caller-owned undo records and initialize an empty stack.
void slg_undo_init(SLGUndoStack* stack, SLGMove* items, u8 capacity);
// Record a cell's previous value for later undo. Return zero if the stack is
// null or full; this function does not change the board itself.
u8 slg_undo_push(SLGUndoStack* stack, u8 x, u8 y, u8 old_value);
// Remove the newest undo record and optionally copy it out. A null output
// still discards the record; a null or empty stack returns zero.
u8 slg_undo_pop(SLGUndoStack* stack, SLGMove* out_move);

kitaqgb/lib/slg.h

sprite.h — Allocation d'OBJ, placement, métasprites et animation
c
#pragma once

// Keep the default 40 for the standard DMA path. Hardware always transfers 160 bytes,
// even if this array is shortened; a custom layout must provide valid bytes for that full transfer.
#ifndef SPRITE_MAX
#define SPRITE_MAX 40
#endif

#define SPRITE_FLAG_PAL1     ((u8)0x10)
#define SPRITE_FLAG_XFLIP    ((u8)0x20)
#define SPRITE_FLAG_YFLIP    ((u8)0x40)
#define SPRITE_FLAG_PRIORITY ((u8)0x80)

// Packed hardware order is Y, X, tile, flags; screen coordinates need the GB OAM offsets.
typedef __packed struct {
    u8 y;
    u8 x;
    u8 tile;
    u8 flags;
} SpriteOamEntry;

extern __wram __aligned(256) SpriteOamEntry kq_sprite_oam[SPRITE_MAX];
extern u8 kq_sprite_active[SPRITE_MAX];
extern u8 kq_sprite_used;
extern u8 kq_sprite_height;

// Signed pixel displacements from a common origin; final byte coordinates wrap rather than clip.
typedef __packed struct {
    s8 dx;
    s8 dy;
    u8 tile;
    u8 flags;
} MetaSpritePart;

// Initialize frame/ticks within their configured ranges. This animation selects consecutive tile IDs;
// it does not change sprite size or automatically step by two tiles in 8x16 mode.
typedef __packed struct {
    u8 first_tile;
    u8 frame_count;
    u8 frame;
    u8 ticks;
    u8 ticks_per_frame;
} SpriteAnim;

void __wait_vblank();
void __oam_dma(u16 src_ptr);

// Clear allocation and shadow OAM state and reset the DMA-stub installation flag.
// The default height is eight pixels; the hardware display mode is configured elsewhere.
void sprite_init();
// Claim the first free slot, hide it, and return its ID; return 0xFF when full.
// Previously stored tile/flag bytes are retained until the caller replaces them.
u8 sprite_alloc();
// Release an allocated valid slot and hide it. Repeated frees do not decrement the count.
void sprite_free(u8 id);
// Convert screen coordinates to OAM coordinates by adding X=8 and Y=16.
// The byte additions wrap; this updates shadow storage even for an unallocated slot.
void sprite_set_pos(u8 id, u8 x, u8 y);
// Set a valid shadow slot's tile byte; allocation and hardware transfer are separate.
void sprite_set_tile(u8 id, u8 tile);
// Replace a valid shadow slot's complete hardware attribute byte.
void sprite_set_flags(u8 id, u8 flags);
// Move a valid shadow slot off screen without freeing it.
void sprite_hide(u8 id);
// Install the HRAM stub lazily and execute OAM DMA with interrupts disabled.
// This routine does not wait for VBlank and always enables interrupts afterward;
// it does not restore the caller's previous interrupt-enable state.
void sprite_flush_oam_now();
// Wait for VBlank, then transfer shadow OAM using the immediate DMA routine.
void sprite_flush_oam();
// Return the number of active slots, including slots activated by metasprite_draw.
// Hidden allocated slots remain active until sprite_free releases them.
u8 sprite_count_used();
// Report whether the software overlap estimate exceeds ten sprites on a scanline.
u8 sprite_warn_scanline_overflow();
// Estimate the largest overlap of active, non-hidden shadow sprites across
// visible scanlines using the configured sprite height. This is a software
// overlap count, not a rendered-pixel or hardware-priority simulation.
u8 sprite_max_scanline_count();
// Place consecutive parts, counting each newly activated slot once. Existing
// active slots are overwritten without increasing the allocation count. Return
// the number written; an invalid first slot or zero count writes nothing.
u8 metasprite_draw(u8 first_id, u8 x, u8 y, const MetaSpritePart* parts, u8 count);
// Advance animation ticks/frame with wrapping frame selection and return the
// resulting tile. Zero ticks-per-frame freezes animation; null state returns zero.
u8 anim_update(SpriteAnim* anim);

kitaqgb/lib/sprite.h

sprite_order.h — Sélection des sprites par priorité et rotation
c
#pragma once
// Copyright (c) 2026 DAISUKE OBA. MIT License.

// Hardware-compatible layout without requiring the sprite allocator or its
// global storage. Cast a sprite.h shadow buffer to this type when combining
// the libraries; both layouts contain exactly Y, X, tile and flags bytes.
typedef __packed struct {
    u8 y;
    u8 x;
    u8 tile;
    u8 flags;
} SpriteOrderOamEntry;

#define SPRITE_ORDER_LEVELS 4
#define SPRITE_ORDER_OAM_COUNT 40

// One submitted, visible sprite. Attributes retain their hardware meaning;
// priority 0..3 controls OAM selection order, not the BG-over-OBJ flag.
typedef __packed struct {
    SpriteOrderOamEntry oam;
    u8 priority;
} SpriteOrderItem;

// Caller-owned foreground state. Capacity is 1..255 items; count includes only
// accepted submissions. Rebuild the same logical submission list each frame so
// phase rotation distributes selection among equal-priority sprites.
typedef struct {
    SpriteOrderItem* items;
    u8 capacity;
    u8 count;
    u8 height;
    u8 phase;
} SpriteOrder;

// Bind writable item storage and select the hardware sprite height (8 or 16).
// Return 1 on success. Invalid storage, zero capacity or another height returns
// 0 and leaves a non-null state disabled. A null state returns 0 without writes.
u8 sprite_order_init(SpriteOrder* order, SpriteOrderItem* items, u8 capacity, u8 height);

// Discard this frame's submissions while preserving storage, height and phase.
// A null state is ignored. Call once before submitting the next frame's sprites.
void sprite_order_begin(SpriteOrder* order);

// Submit one sprite at signed, top-left SCREEN pixel coordinates. Preserve the
// tile and attribute bytes; use priority 0 (first) through 3 (last). Fully
// off-screen sprites, invalid priorities, disabled state and full storage return
// 0 without consuming a slot. Partly visible sprites are accepted. Return 1 on
// acceptance. Hardware 8x16 mode still ignores the tile index's low bit.
u8 sprite_order_push(SpriteOrder* order, s16 x, s16 y, u8 tile, u8 flags, u8 priority);

// Write a complete 160-byte shadow OAM: ascending priority, then cyclic order
// within each priority. Clamp limit to 40, return the number emitted and zero
// all unused entries (including Y) so they cannot consume scanline slots.
// Advance phase once for a nonempty valid queue, even when limit is zero.
// Empty queues reset phase to zero. Null/disabled/corrupt state or null output
// returns 0 without modifying output or phase.
// Output must provide 40 entries and must not overlap item/state storage.
// This only writes RAM. Build in foreground, then transfer during VBlank.
// DMG overlap priority also depends on X: this cannot override that hardware
// rule. OAM order chooses the first ten sprites per scanline on both DMG/CGB.
// It neither updates sprite_alloc's bookkeeping nor performs OAM DMA.
u8 sprite_order_build(SpriteOrder* order, SpriteOrderOamEntry* output, u8 limit);

kitaqgb/lib/sprite_order.h

system.h — Démarrage, compteurs d'images, attentes et interruptions
c
#pragma once

// This callback runs in the caller of system_wait_vblank, not as an installed ISR.
// Its plain pointer has no ROM bank component; keep the target callable in that mapping.
typedef void (*SystemCallback)();

extern u16 kq_system_frame;

void __wait_vblank();

// Reset the software frame counter and remove any registered callback.
void system_init();
// Wait for VBlank, count this wrapper call, then invoke the callback synchronously.
// The counter wraps at 16 bits and is not an independent hardware frame clock.
void system_wait_vblank();
// Replace the callback used by system_wait_vblank; null disables the callback.
void system_set_vblank_callback(SystemCallback callback);
// Read the software count of completed system_wait_vblank calls.
u16 system_get_frame();
// Return the low byte of the software frame counter for wrapping 8-bit timing.
u8 system_get_frame8();
// Enable CPU interrupts and return using the inline-assembly function body.
void system_enable_interrupts();
// Disable CPU interrupts and return; callers must explicitly re-enable them later.
void system_disable_interrupts();

#define gb_init system_init
#define gb_wait_vblank system_wait_vblank
#define gb_set_vblank_callback system_set_vblank_callback
#define gb_frame_count system_get_frame
#define gb_enable_interrupts system_enable_interrupts
#define gb_disable_interrupts system_disable_interrupts

kitaqgb/lib/system.h

vram.h — Mises à jour et transferts VRAM en file
c
#pragma once

// Keep this capacity in 1..255 in all units; counts and capacity/free return values are bytes.
#ifndef VRAM_QUEUE_MAX
#define VRAM_QUEUE_MAX 32
#endif

#define VRAM_CMD_BG_TILE   ((u8)1)
#define VRAM_CMD_BG_RECT   ((u8)2)
#define VRAM_CMD_BG_BLOCK  ((u8)3)
#define VRAM_CMD_MEMCPY    ((u8)4)
#define VRAM_CMD_MEMSET    ((u8)5)

// A command owns metadata only. src is a retained near pointer with no bank number or copied payload.
typedef __packed struct {
    u8 kind;
    u8 x;
    u8 y;
    u8 w;
    u8 h;
    u8 value;
    u16 dst;
    const u8* src;
    u16 len;
} VramCommand;

extern VramCommand kq_vram_queue[VRAM_QUEUE_MAX];
extern u8 kq_vram_queue_used;
extern u8 kq_vram_queue_overflowed;

void __wait_vblank();
void __settile_xy(u8 x, u8 y, u8 tile);
void __settile_rect(u8 x, u8 y, u8 w, u8 h, u8 tile);
void __settilemap_rect(u16 base, u8 x, u8 y, u8 w, u8 h, const u8* src);
void __vram_copy(u16 dst, const void* src, u16 len);
void __vram_fill(u16 dst, u8 value, u16 len);

// Start with an empty command queue and a clear overflow flag.
void vram_init();
// Discard pending commands and clear the latched overflow flag without writing VRAM.
void vram_clear_queue();
// Queue a single background tile write; return zero if no command slot is available.
u8 vram_queue_bg_tile(u8 x, u8 y, u8 tile);
// Provide the short alias for a queued background tile write.
u8 vram_queue_tile(u8 x, u8 y, u8 tile);
// Queue a rectangle filled with one tile value; coordinates and dimensions are in tiles.
u8 vram_queue_bg_rect(u8 x, u8 y, u8 w, u8 h, u8 tile);
// Queue a tile-map rectangle while retaining src rather than copying its bytes.
// Keep the source data and its ROM bank accessible until the queue is flushed.
u8 vram_queue_bg_block(u16 base, u8 x, u8 y, u8 w, u8 h, const u8* src);
// Queue a byte transfer and retain the source pointer. The source must remain
// valid and visible until flush; len is measured in bytes, not tiles.
u8 vram_queue_memcpy(u16 dst, const void* src, u16 len);
// Alias the queued byte-copy operation; this does not convert a tile count to bytes.
u8 vram_queue_tiles(u16 dst, const void* src, u16 len);
// Queue a byte fill and return zero if the command queue is full.
u8 vram_queue_memset(u16 dst, u8 value, u16 len);
// Execute pending commands in insertion order without waiting for VBlank here.
// The caller must arrange suitable VRAM access timing and a sufficient transfer budget.
// Only the used count is cleared; overflow stays latched until an explicit reset.
void vram_flush_now();
// Wait for VBlank before executing the queue. Waiting once does not itself limit
// the queued workload to the available VBlank duration.
void vram_flush();
// Return the number of queued commands, not the number of transfer bytes.
u8 vram_get_queue_used();
// Return the total number of command slots, independent of queue usage.
// This is command-buffer capacity, not free space in hardware VRAM.
u8 vram_get_queue_capacity();
// Return the remaining command-slot capacity.
u8 vram_get_queue_free();
// Read the overflow latch without clearing it.
u8 vram_get_overflowed();

kitaqgb/lib/vram.h

wire3d.h — Rendu filaire pour DMG
c
// Compatibility names for the shared wire3d_dmg renderer.
// Select the same profile in every translation unit; compile one renderer entry.
#pragma once
#ifndef WIRE3D_DMG_HEIGHT
#define WIRE3D_DMG_HEIGHT 96
#endif
#if WIRE3D_DMG_HEIGHT != 96
#error Incompatible wire3d_dmg profile
#endif
#include "wire3d_dmg.h"

#define W3D_BG_QUEUE_LIMIT WIRE3D_DMG_BG_QUEUE_LIMIT
#define W3D_CENTER_X WIRE3D_DMG_CENTER_X
#define W3D_CENTER_Y WIRE3D_DMG_CENTER_Y
#define W3D_FAR_Z WIRE3D_DMG_FAR_Z
#define W3D_HUD_TILE_BASE WIRE3D_DMG_HUD_TILE_BASE
#define W3D_HUD_TILE_BLANK WIRE3D_DMG_HUD_TILE_BLANK
#define W3D_HUD_TILE_COUNT WIRE3D_DMG_HUD_TILE_COUNT
#define W3D_NEAR_Z WIRE3D_DMG_NEAR_Z
#define W3D_PROJECT_LIMIT WIRE3D_DMG_PROJECT_LIMIT
#define W3D_ROW_BYTES WIRE3D_DMG_ROW_BYTES
#define W3D_TILE_H WIRE3D_DMG_TILE_H
#define W3D_TILE_W WIRE3D_DMG_TILE_W
#define W3D_TRANSFORM_LIMIT WIRE3D_DMG_TRANSFORM_LIMIT
#define WIRE3D_EDGE_MASK_BINS_16 WIRE3D_DMG_EDGE_MASK_BINS_16
#define WIRE3D_FACE_NONE WIRE3D_DMG_FACE_NONE
#define WIRE3D_MODEL_EDGE_LIMIT WIRE3D_DMG_MODEL_EDGE_LIMIT
#define WIRE3D_MODEL_FACE_LIMIT WIRE3D_DMG_MODEL_FACE_LIMIT
#define WIRE3D_MODEL_HIDDEN_LINES WIRE3D_DMG_MODEL_HIDDEN_LINES
#define WIRE3D_MODEL_VERTEX_LIMIT WIRE3D_DMG_MODEL_VERTEX_LIMIT
#define WIRE3D_SCENE_OBJECT_LIMIT WIRE3D_DMG_SCENE_OBJECT_LIMIT
#define WIRE3D_SCREEN_H WIRE3D_DMG_SCREEN_H
#define WIRE3D_SCREEN_W WIRE3D_DMG_SCREEN_W
#define Wire3D_BeginFrame Wire3DDMG_BeginFrame
#define Wire3D_DrawLine2D Wire3DDMG_DrawLine2D
#define Wire3D_DrawLine3D Wire3DDMG_DrawLine3D
#define Wire3D_DrawModel Wire3DDMG_DrawModel
#define Wire3D_DrawModelScaled Wire3DDMG_DrawModelScaled
#define Wire3D_DrawScene Wire3DDMG_DrawScene
#define Wire3D_Edge Wire3DDMG_Edge
#define Wire3D_EdgeFaces Wire3DDMG_EdgeFaces
#define Wire3D_EndFrame Wire3DDMG_EndFrame
#define Wire3D_EraseModelFaces Wire3DDMG_EraseModelFaces
#define Wire3D_EraseSpan2D Wire3DDMG_EraseSpan2D
#define Wire3D_EraseTriangle2D Wire3DDMG_EraseTriangle2D
#define Wire3D_Face Wire3DDMG_Face
#define Wire3D_Init Wire3DDMG_Init
#define Wire3D_Model Wire3DDMG_Model
#define Wire3D_Object Wire3DDMG_Object
#define Wire3D_ProjectPoint Wire3DDMG_ProjectPoint
#define Wire3D_PutBgTile Wire3DDMG_PutBgTile
#define Wire3D_SelectEdgeMask Wire3DDMG_SelectEdgeMask
#define Wire3D_SetCamera Wire3DDMG_SetCamera
#define Wire3D_SetPalette Wire3DDMG_SetPalette
#define Wire3D_Vec3 Wire3DDMG_Vec3
#define w3d_abs_i16 w3ddmg_abs_i16
#define w3d_bg_map_9800 w3ddmg_bg_map_9800
#define w3d_bgq_addr_hi w3ddmg_bgq_addr_hi
#define w3d_bgq_addr_lo w3ddmg_bgq_addr_lo
#define w3d_bgq_count w3ddmg_bgq_count
#define w3d_bgq_tile w3ddmg_bgq_tile
#define w3d_bgq_value w3ddmg_bgq_value
#define w3d_bgq_x w3ddmg_bgq_x
#define w3d_bgq_y w3ddmg_bgq_y
#define w3d_bit_mask w3ddmg_bit_mask
#define w3d_build_edge_flags w3ddmg_build_edge_flags
#define w3d_build_face_visibility w3ddmg_build_face_visibility
#define w3d_cam_pitch w3ddmg_cam_pitch
#define w3d_cam_roll w3ddmg_cam_roll
#define w3d_cam_x w3ddmg_cam_x
#define w3d_cam_y w3ddmg_cam_y
#define w3d_cam_yaw w3ddmg_cam_yaw
#define w3d_cam_z w3ddmg_cam_z
#define w3d_clamp_i16 w3ddmg_clamp_i16
#define w3d_clamp_screen w3ddmg_clamp_screen
#define w3d_clear_occlusion_mask w3ddmg_clear_occlusion_mask
#define w3d_clear_occlusion_mask_asm w3ddmg_clear_occlusion_mask_asm
#define w3d_clear_stage_asm w3ddmg_clear_stage_asm
#define w3d_clear_triangle w3ddmg_clear_triangle
#define w3d_clear_vram_asm w3ddmg_clear_vram_asm
#define w3d_cos_q6 w3ddmg_cos_q6
#define w3d_edge_area w3ddmg_edge_area
#define w3d_edge_flags w3ddmg_edge_flags
#define w3d_face_visible w3ddmg_face_visible
#define w3d_fill_bg_map_asm w3ddmg_fill_bg_map_asm
#define w3d_flush_bg_queue w3ddmg_flush_bg_queue
#define w3d_hud_tiles w3ddmg_hud_tiles
#define w3d_i16 w3ddmg_i16
#define w3d_i8 w3ddmg_i8
#define w3d_inv_depth w3ddmg_inv_depth
#define w3d_is_edge_visible w3ddmg_is_edge_visible
#define w3d_line_dx w3ddmg_line_dx
#define w3d_line_dy w3ddmg_line_dy
#define w3d_line_err w3ddmg_line_err
#define w3d_line_stage_asm w3ddmg_line_stage_asm
#define w3d_line_stage_masked_c w3ddmg_line_stage_masked_c
#define w3d_line_sx w3ddmg_line_sx
#define w3d_line_sy w3ddmg_line_sy
#define w3d_line_x w3ddmg_line_x
#define w3d_line_x0 w3ddmg_line_x0
#define w3d_line_x1 w3ddmg_line_x1
#define w3d_line_y w3ddmg_line_y
#define w3d_line_y0 w3ddmg_line_y0
#define w3d_line_y1 w3ddmg_line_y1
#define w3d_load_hud_tiles w3ddmg_load_hud_tiles
#define w3d_mark_model_occluder w3ddmg_mark_model_occluder
#define w3d_mark_triangle w3ddmg_mark_triangle
#define w3d_mask_get w3ddmg_mask_get
#define w3d_mask_offset w3ddmg_mask_offset
#define w3d_mask_set w3ddmg_mask_set
#define w3d_mask_set_span w3ddmg_mask_set_span
#define w3d_neg_angle w3ddmg_neg_angle
#define w3d_occlusion_active w3ddmg_occlusion_active
#define w3d_occlusion_mask w3ddmg_occlusion_mask
#define w3d_pair_block w3ddmg_pair_block
#define w3d_pair_wait_0 w3ddmg_pair_wait_0
#define w3d_pair_wait_1 w3ddmg_pair_wait_1
#define w3d_pair_wait_10 w3ddmg_pair_wait_10
#define w3d_pair_wait_11 w3ddmg_pair_wait_11
#define w3d_pair_wait_12 w3ddmg_pair_wait_12
#define w3d_pair_wait_13 w3ddmg_pair_wait_13
#define w3d_pair_wait_14 w3ddmg_pair_wait_14
#define w3d_pair_wait_15 w3ddmg_pair_wait_15
#define w3d_pair_wait_2 w3ddmg_pair_wait_2
#define w3d_pair_wait_3 w3ddmg_pair_wait_3
#define w3d_pair_wait_4 w3ddmg_pair_wait_4
#define w3d_pair_wait_5 w3ddmg_pair_wait_5
#define w3d_pair_wait_6 w3ddmg_pair_wait_6
#define w3d_pair_wait_7 w3ddmg_pair_wait_7
#define w3d_pair_wait_8 w3ddmg_pair_wait_8
#define w3d_pair_wait_9 w3ddmg_pair_wait_9
#define w3d_plot_stage_asm w3ddmg_plot_stage_asm
#define w3d_plot_tx w3ddmg_plot_tx
#define w3d_plot_x w3ddmg_plot_x
#define w3d_plot_y w3ddmg_plot_y
#define w3d_project_camera_space w3ddmg_project_camera_space
#define w3d_project_world w3ddmg_project_world
#define w3d_put_bg_tile_safe_asm w3ddmg_put_bg_tile_safe_asm
#define w3d_reg_bgp w3ddmg_reg_bgp
#define w3d_reg_lcdc w3ddmg_reg_lcdc
#define w3d_reg_ly w3ddmg_reg_ly
#define w3d_reg_scx w3ddmg_reg_scx
#define w3d_reg_scy w3ddmg_reg_scy
#define w3d_rotate_x w3ddmg_rotate_x
#define w3d_rotate_y w3ddmg_rotate_y
#define w3d_rotate_z w3ddmg_rotate_z
#define w3d_scene_depth w3ddmg_scene_depth
#define w3d_scene_object_depth w3ddmg_scene_object_depth
#define w3d_scene_order w3ddmg_scene_order
#define w3d_screen_delta w3ddmg_screen_delta
#define w3d_screen_visible w3ddmg_screen_visible
#define w3d_screen_x w3ddmg_screen_x
#define w3d_screen_y w3ddmg_screen_y
#define w3d_sin_q6 w3ddmg_sin_q6
#define w3d_stage w3ddmg_stage
#define w3d_stage_clear_pixel w3ddmg_stage_clear_pixel
#define w3d_stage_clear_span w3ddmg_stage_clear_span
#define w3d_transfer_stage_asm w3ddmg_transfer_stage_asm
#define w3d_u16 w3ddmg_u16
#define w3d_u8 w3ddmg_u8
#define w3d_vram_tiles w3ddmg_vram_tiles
#define w3d_wait_vblank_start w3ddmg_wait_vblank_start
#define w3dbg_enter w3ddmgbg_enter
#define w3dco_enter w3ddmgco_enter
#define w3dco_loop w3ddmgco_loop
#define w3dco_page w3ddmgco_page
#define w3dcs_enter w3ddmgcs_enter
#define w3dcs_inner w3ddmgcs_inner
#define w3dcs_outer w3ddmgcs_outer
#define w3dcv_enter w3ddmgcv_enter
#define w3dcv_loop w3ddmgcv_loop
#define w3dcv_page w3ddmgcv_page
#define w3dfb_enter w3ddmgfb_enter
#define w3dfb_loop w3ddmgfb_loop
#define w3dfb_page w3ddmgfb_page
#define w3dls_branch w3ddmgls_branch
#define w3dls_done w3ddmgls_done
#define w3dls_enter w3ddmgls_enter
#define w3dls_shallow w3ddmgls_shallow
#define w3dls_shallow_loop w3ddmgls_shallow_loop
#define w3dls_shallow_skip_bridge w3ddmgls_shallow_skip_bridge
#define w3dls_steep w3ddmgls_steep
#define w3dls_steep_loop w3ddmgls_steep_loop
#define w3dls_steep_skip_bridge w3ddmgls_steep_skip_bridge
#define w3dls_x_reverse w3ddmgls_x_reverse
#define w3dls_y_reverse w3ddmgls_y_reverse
#define w3dls_y_start w3ddmgls_y_start
#define w3dps_enter w3ddmgps_enter
#define w3dps_ret w3ddmgps_ret

kitaqgb/lib/wire3d.h

wire3d_cgb.h — Rendu filaire couleur pour CGB
c
#pragma once

#ifndef KITAQGB_WIRE3D_CGB_H
#define KITAQGB_WIRE3D_CGB_H

#define WIRE3DCGB_SCREEN_W 128
#ifndef WIRE3DCGB_HEIGHT
#define WIRE3DCGB_HEIGHT 96
#endif
#if WIRE3DCGB_HEIGHT != 88 && WIRE3DCGB_HEIGHT != 96
#error WIRE3DCGB_HEIGHT must be 88 or 96
#endif
#define WIRE3DCGB_SCREEN_H WIRE3DCGB_HEIGHT
#if WIRE3DCGB_HEIGHT == 88
#define WIRE3DCGB_TILE_ROWS 11
#define WIRE3DCGB_TILE_COUNT 176
#define WIRE3DCGB_COLUMN_BYTES 176
#define WIRE3DCGB_NEG_COLUMN_BYTES 0xFF50
#define WIRE3DCGB_STAGE_RIGHT 0xDD50
#define WIRE3DCGB_STAGE_BOTTOM 0xD3AE
#define WIRE3DCGB_SECOND_DMA 0xAF
#else
#define WIRE3DCGB_TILE_ROWS 12
#define WIRE3DCGB_TILE_COUNT 192
#define WIRE3DCGB_COLUMN_BYTES 192
#define WIRE3DCGB_NEG_COLUMN_BYTES 0xFF40
#define WIRE3DCGB_STAGE_RIGHT 0xDE40
#define WIRE3DCGB_STAGE_BOTTOM 0xD3BE
#define WIRE3DCGB_SECOND_DMA 0xBF
#endif
// Reserve 3072 bytes in either profile for full-screen compatibility.
#define WIRE3DCGB_UPLOAD_BYTES (WIRE3DCGB_TILE_COUNT * 16)
#define WIRE3DCGB_FULL_SCREEN_W 160
#define WIRE3DCGB_FULL_SCREEN_H 144
#define WIRE3DCGB_FULL_TILE_LIMIT 127
#define WIRE3DCGB_STAGE_BASE 0xD300
#define WIRE3DCGB_STAGE_WRAM_BANK 2
#define WIRE3DCGB_STAGE_BYTES 3072
#define WIRE3DCGB_MODEL_VERTEX_LIMIT 24
#define WIRE3DCGB_MODEL_FACE_LIMIT 16
#define WIRE3DCGB_MODEL_EDGE_LIMIT 64
#define WIRE3DCGB_SCENE_OBJECT_LIMIT 8
#define WIRE3DCGB_FACE_NONE 255
#define WIRE3DCGB_MODEL_HIDDEN_LINES 1
#define WIRE3DCGB_COLOR_LOW 1
#define WIRE3DCGB_COLOR_MAIN 2
#define WIRE3DCGB_COLOR_HIGH 3
#define WIRE3DCGB_COLOR_DEFAULT WIRE3DCGB_COLOR_MAIN

#define WIRE3DCGB_RGB15(r5, g5, b5) ((w3dcgb_u16)((w3dcgb_u16)((r5) & 31) | ((w3dcgb_u16)((g5) & 31) << 5) | ((w3dcgb_u16)((b5) & 31) << 10)))

typedef s8 w3dcgb_i8;
typedef s16 w3dcgb_i16;
typedef u8 w3dcgb_u8;
typedef u16 w3dcgb_u16;

typedef struct {
    w3dcgb_i16 x;
    w3dcgb_i16 y;
    w3dcgb_i16 z;
} Wire3DCGB_Vec3;

typedef struct {
    w3dcgb_u8 a;
    w3dcgb_u8 b;
} Wire3DCGB_Edge;

typedef struct {
    w3dcgb_u8 a;
    w3dcgb_u8 b;
    w3dcgb_u8 c;
} Wire3DCGB_Face;

typedef struct {
    w3dcgb_u8 f0;
    w3dcgb_u8 f1;
} Wire3DCGB_EdgeFaces;

typedef struct {
    const Wire3DCGB_Vec3* vertices;
    const Wire3DCGB_Edge* edges;
    const Wire3DCGB_Face* faces;
    const Wire3DCGB_EdgeFaces* edge_faces;
    w3dcgb_u8 vertex_count;
    w3dcgb_u8 edge_count;
    w3dcgb_u8 face_count;
    w3dcgb_u8 flags;
} Wire3DCGB_Model;

typedef struct {
    const Wire3DCGB_Model* model;
    w3dcgb_i16 x;
    w3dcgb_i16 y;
    w3dcgb_i16 z;
    w3dcgb_i8 rx;
    w3dcgb_i8 ry;
    w3dcgb_i8 rz;
    w3dcgb_i16 scale_q8;
    w3dcgb_u8 visible;
    w3dcgb_u8 color;
} Wire3DCGB_Object;

typedef struct {
    w3dcgb_i16 x;
    w3dcgb_i16 y;
    w3dcgb_i16 z;
    w3dcgb_i8 rx;
    w3dcgb_i8 ry;
    w3dcgb_i8 rz;
    w3dcgb_u8 color;
} Wire3DCGB_FastCube;

void Wire3DCGB_Init();
void Wire3DCGB_InitFullScreen();
void Wire3DCGB_InitFastMapLite();
void Wire3DCGB_EnableDoubleSpeed();
void Wire3DCGB_SetScreenOffset(w3dcgb_u8 scx, w3dcgb_u8 scy);
void Wire3DCGB_SetPaletteRGB15(w3dcgb_u16 color0, w3dcgb_u16 color1, w3dcgb_u16 color2, w3dcgb_u16 color3);
void Wire3DCGB_SetLineColor(w3dcgb_u8 color);
w3dcgb_u8 Wire3DCGB_GetLineColor();
void Wire3DCGB_ClearFrameTiles();
void Wire3DCGB_BeginFrame();
void Wire3DCGB_BeginFrameFast();
void Wire3DCGB_BeginFrameSparse();
void Wire3DCGB_ClearSparseStageFast();
void Wire3DCGB_MarkDirtyRect2D(w3dcgb_u8 min_x, w3dcgb_u8 min_y, w3dcgb_u8 max_x, w3dcgb_u8 max_y);
void Wire3DCGB_SetCamera(w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 pitch, w3dcgb_i8 yaw, w3dcgb_i8 roll);
void Wire3DCGB_DrawModel(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz);
void Wire3DCGB_DrawModelScaled(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz, w3dcgb_i16 scale_q8);
void Wire3DCGB_DrawModelColor(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz, w3dcgb_u8 color);
void Wire3DCGB_DrawModelScaledColor(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz, w3dcgb_i16 scale_q8, w3dcgb_u8 color);
void Wire3DCGB_EraseModelFaces(const Wire3DCGB_Model* model, w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_i8 rx, w3dcgb_i8 ry, w3dcgb_i8 rz, w3dcgb_i16 scale_q8);
void Wire3DCGB_EraseTriangle2D(w3dcgb_u8 ax, w3dcgb_u8 ay, w3dcgb_u8 bx, w3dcgb_u8 by, w3dcgb_u8 cx, w3dcgb_u8 cy);
void Wire3DCGB_EraseSpan2D(w3dcgb_u8 y, w3dcgb_u8 x0, w3dcgb_u8 x1);
/* Signed endpoints, clipped before conversion to the rasterizer's u8 ABI. */
void Wire3DCGB_DrawLineClipped2D(w3dcgb_i16 x0, w3dcgb_i16 y0,
                               w3dcgb_i16 x1, w3dcgb_i16 y1, w3dcgb_u8 color);
void Wire3DCGB_DrawEdgeListClipped2D(const Wire3DCGB_Edge* edges, w3dcgb_u8 edge_count,
    const w3dcgb_i16* vx, const w3dcgb_i16* vy, w3dcgb_u8 vertex_count,
    w3dcgb_i16 cx, w3dcgb_i16 cy, w3dcgb_u8 color);
w3dcgb_i16 Wire3DCGB_ProjectAxis48(w3dcgb_i16 value, w3dcgb_i16 z);
void Wire3DCGB_InvalidateFrameHistory();
/* Startup-only: reserves both BG maps; queued HUD tiles are mirrored. */
void Wire3DCGB_EnableAtomicMaps();
void Wire3DCGB_EraseRect2D(w3dcgb_u8 x0, w3dcgb_u8 y0, w3dcgb_u8 x1, w3dcgb_u8 y1);
void Wire3DCGB_EraseLeftGuard24Fast();
void Wire3DCGB_DrawWhiteBorderFast();
void Wire3DCGB_ClearOcclusionMask();
void Wire3DCGB_SetOcclusionActive(w3dcgb_u8 active);
void Wire3DCGB_MarkTriangle2D(w3dcgb_u8 ax, w3dcgb_u8 ay, w3dcgb_u8 bx, w3dcgb_u8 by, w3dcgb_u8 cx, w3dcgb_u8 cy);
void Wire3DCGB_MarkPackedSilhouette2D(const w3dcgb_u8* profile, w3dcgb_u8 count,
                                     w3dcgb_i8 y0, w3dcgb_u8 x, w3dcgb_u8 y);
void Wire3DCGB_ErasePackedSilhouette2D(const w3dcgb_u8* profile, w3dcgb_u8 count,
                                      w3dcgb_i8 y0, w3dcgb_u8 x, w3dcgb_u8 y);
void Wire3DCGB_DrawScene(Wire3DCGB_Object* objects, w3dcgb_u8 count);
void Wire3DCGB_DrawFastCubes(Wire3DCGB_FastCube* cubes, w3dcgb_u8 count, w3dcgb_u8 hidden_enabled, w3dcgb_u8 selected);
void Wire3DCGB_DrawFastStatus(w3dcgb_u8 hidden_enabled, w3dcgb_u8 selected);
void Wire3DCGB_DrawFastCubeFrame(Wire3DCGB_FastCube* cubes, w3dcgb_u8 count, w3dcgb_u8 hidden_enabled, w3dcgb_u8 selected);
void Wire3DCGB_DrawFastProjectile(w3dcgb_u8 x, w3dcgb_u8 y, w3dcgb_i16 z, w3dcgb_u8 phase, w3dcgb_u8 color);
void Wire3DCGB_FastMapBegin();
void Wire3DCGB_FastMapBeginTilesOnly();
void Wire3DCGB_FastMapCell(w3dcgb_u8 tx, w3dcgb_u8 ty, w3dcgb_u8 color, w3dcgb_u8 mask);
void Wire3DCGB_FastMapRect(w3dcgb_u8 tx0, w3dcgb_u8 ty0, w3dcgb_u8 tx1, w3dcgb_u8 ty1, w3dcgb_u8 color, w3dcgb_u8 sides);
void Wire3DCGB_FastMapFlush();
void Wire3DCGB_FastMapFlushTilesOnly();
// Project camera-space coordinates without subtracting/rotating the camera.
// Depth 8..255; outputs unchanged on rejection. Shared scratch: no ISR calls.
w3dcgb_u8 Wire3DCGB_ProjectCameraPoint(w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_u8* sx, w3dcgb_u8* sy);
w3dcgb_u8 Wire3DCGB_ProjectPoint(w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_u8* sx, w3dcgb_u8* sy);
/* Fast path for games whose camera pitch, yaw, and roll stay at zero. */
w3dcgb_u8 Wire3DCGB_ProjectPointNoRotation(w3dcgb_i16 x, w3dcgb_i16 y, w3dcgb_i16 z, w3dcgb_u8* sx, w3dcgb_u8* sy);
void Wire3DCGB_DrawLine3D(w3dcgb_i16 ax, w3dcgb_i16 ay, w3dcgb_i16 az, w3dcgb_i16 bx, w3dcgb_i16 by, w3dcgb_i16 bz);
void Wire3DCGB_DrawLine3DColor(w3dcgb_i16 ax, w3dcgb_i16 ay, w3dcgb_i16 az, w3dcgb_i16 bx, w3dcgb_i16 by, w3dcgb_i16 bz, w3dcgb_u8 color);
void Wire3DCGB_DrawPoint2D(w3dcgb_u8 x, w3dcgb_u8 y);
void Wire3DCGB_DrawTinyModel2D(w3dcgb_u8 x, w3dcgb_u8 y,
                               w3dcgb_u8 turn, w3dcgb_u8 color);
void Wire3DCGB_DrawLine2D(w3dcgb_u8 ax, w3dcgb_u8 ay, w3dcgb_u8 bx, w3dcgb_u8 by);
void Wire3DCGB_DrawLine2DColor(w3dcgb_u8 ax, w3dcgb_u8 ay, w3dcgb_u8 bx, w3dcgb_u8 by, w3dcgb_u8 color);
void Wire3DCGB_DrawMaskedModel2D(const Wire3DCGB_Model* model,
                                 const w3dcgb_i8* vertex_x, const w3dcgb_i8* vertex_y,
                                 const w3dcgb_u8* edge_mask,
                                 w3dcgb_u8 x, w3dcgb_u8 y, w3dcgb_u8 color);
void Wire3DCGB_DrawEdgeList2D(const Wire3DCGB_Edge* edges, w3dcgb_u8 edge_count,
                              const w3dcgb_i8* vertex_x, const w3dcgb_i8* vertex_y,
                              w3dcgb_u8 x, w3dcgb_u8 y, w3dcgb_u8 color);
void Wire3DCGB_DrawLineList2DColor(const w3dcgb_u8* line_xy,
                                  w3dcgb_u8 line_count, w3dcgb_u8 color);
void Wire3DCGB_PutBgTile(w3dcgb_u8 x, w3dcgb_u8 y, w3dcgb_u8 tile);
void Wire3DCGB_EndFrame();
void Wire3DCGB_EndFrameFast();
void Wire3DCGB_EndFrameSparse();
void Wire3DCGB_EndFrameSparseNow();
w3dcgb_u8 Wire3DCGB_GetFullScreenTileCount();
w3dcgb_u8 Wire3DCGB_GetFullScreenOverflow();

#endif

kitaqgb/lib/wire3d_cgb.h

wire3d_dmg.h — Rendu filaire pour DMG
c
#pragma once

// Select the viewport at build time before including this header or source.
// Default: 128x120 with consuming uploads and optional dirty/auxiliary transfer.
// Heights 88 and 96 retain the HUD and yaw-mask profile with BeginFrame clearing.
#ifndef WIRE3D_DMG_HEIGHT
#define WIRE3D_DMG_HEIGHT 120
#endif
#if WIRE3D_DMG_HEIGHT != 88 && WIRE3D_DMG_HEIGHT != 96 && WIRE3D_DMG_HEIGHT != 120
#error WIRE3D_DMG_HEIGHT must be 88, 96 or 120
#endif


#ifndef KITAQGB_WIRE3D_DMG_H
#define KITAQGB_WIRE3D_DMG_H

#if WIRE3D_DMG_HEIGHT != 120
// Monochrome 128x88/96 wireframe renderer with global, non-reentrant state.
// It takes over LCD tile data/map and reserves WRAM 0xD000..0xDFFF for staging.
// Angles wrap every 16 steps; scale 256 is unity. Scene occlusion is a coarse
// face-bounding-box/five-line-sample heuristic, not per-pixel depth testing.
#else
// Monochrome 128x120 staged renderer with global non-reentrant state.
// Reserve WRAM 0xD000..0xDFFF and the renderer's tile/map VRAM regions.
// BeginFrame does not clear pixels: uploads consume the stage. Auxiliary source
// strips alias the main stage, and dirty transfer relies on current/previous flags.
#endif
#define WIRE3D_DMG_SCREEN_W 128
#if WIRE3D_DMG_HEIGHT != 120
#define WIRE3D_DMG_SCREEN_H WIRE3D_DMG_HEIGHT
#else
#define WIRE3D_DMG_SCREEN_H 120
#endif
#define WIRE3D_DMG_MODEL_VERTEX_LIMIT 24
#if WIRE3D_DMG_HEIGHT != 120
#define WIRE3D_DMG_MODEL_EDGE_LIMIT 16
#endif
#define WIRE3D_DMG_MODEL_FACE_LIMIT 16
#define WIRE3D_DMG_SCENE_OBJECT_LIMIT 8
#define WIRE3D_DMG_FACE_NONE 255
#define WIRE3D_DMG_MODEL_HIDDEN_LINES 1
#if WIRE3D_DMG_HEIGHT != 120
#define WIRE3D_DMG_EDGE_MASK_BINS_16 16
#else
#define WIRE3D_DMG_ANGLE_STEPS 16
#endif

typedef s8 w3ddmg_i8;
typedef s16 w3ddmg_i16;
typedef u8 w3ddmg_u8;
typedef u16 w3ddmg_u16;

typedef struct {
    w3ddmg_i16 x;
    w3ddmg_i16 y;
    w3ddmg_i16 z;
} Wire3DDMG_Vec3;

typedef struct {
    w3ddmg_u8 a;
    w3ddmg_u8 b;
} Wire3DDMG_Edge;

typedef struct {
    w3ddmg_u8 a;
    w3ddmg_u8 b;
    w3ddmg_u8 c;
} Wire3DDMG_Face;

typedef struct {
    w3ddmg_u8 f0;
    w3ddmg_u8 f1;
} Wire3DDMG_EdgeFaces;

#if WIRE3D_DMG_HEIGHT != 120
// Model tables are borrowed for drawing, never copied or bank-switched.
// Counts are capped at 24 vertices, 16 edges and 16 faces; each supplied table
// must contain the referenced entries. Triangle winding with positive projected
// area is front-facing. FACE_NONE denotes a missing adjacent face.
#else
// Model tables are borrowed and must remain readable in the active bank.
// At most 24 vertices and 16 faces are processed; the model edge count is not
// limited to 16. Supply all declared edge and adjacency entries. Positive
// projected triangle area is front-facing; FACE_NONE means missing adjacency.
#endif
typedef struct {
    const Wire3DDMG_Vec3* vertices;
    const Wire3DDMG_Edge* edges;
    const Wire3DDMG_Face* faces;
    const Wire3DDMG_EdgeFaces* edge_faces;
#if WIRE3D_DMG_HEIGHT != 120
    /* Keep edge mask tables in RAM for pointer-indirect access on current KITAQGB. */
    const w3ddmg_u16* edge_masks;
#endif
    w3ddmg_u8 vertex_count;
    w3ddmg_u8 edge_count;
    w3ddmg_u8 face_count;
#if WIRE3D_DMG_HEIGHT != 120
    w3ddmg_u8 edge_mask_count;
#endif
    w3ddmg_u8 flags;
} Wire3DDMG_Model;

typedef struct {
    const Wire3DDMG_Model* model;
    w3ddmg_i16 x;
    w3ddmg_i16 y;
    w3ddmg_i16 z;
#if WIRE3D_DMG_HEIGHT != 120
    w3ddmg_i8 rx;
    w3ddmg_i8 ry;
    w3ddmg_i8 rz;
#else
    w3ddmg_u8 rx;
    w3ddmg_u8 ry;
    w3ddmg_u8 rz;
#endif
    w3ddmg_i16 scale_q8;
    w3ddmg_u8 visible;
} Wire3DDMG_Object;

#if WIRE3D_DMG_HEIGHT != 120
// Take over the LCD: wait for VBlank, switch it off, clear 6144 tile bytes and
// the BG map, install HUD tiles and the 128x96 signed-tile viewport, then enable
// BG display with scroll zero and BGP=0xB4. Reset camera, BG queue and stage.
// Reserve 0xD000..0xDFFF for staging and retain its WRAM bank mapping.
// Call BeginFrame before drawing to initialize the occlusion state as well.
#else
// Take over LCD state, clear tile VRAM and the BG map, and install a 16x15
// viewport beginning at map tile (3,1). Set scroll (8,0), BGP=0xB4 and BG display.
// Reset camera, queues, transfer modes, both dirty tables and stage. Reserve
// 0xD000..0xDFFF and retain its WRAM mapping; auxiliary storage aliases it.
// Call BeginFrame before drawing to establish occlusion state.
#endif
void Wire3DDMG_Init();
#if WIRE3D_DMG_HEIGHT != 120
// Clear staged pixels and occlusion mask and disable occlusion filtering.
// This leaves the displayed VRAM frame and pending BG tile queue unchanged.
#else
// Disable occlusion filtering only. Stage clearing normally happens during
// transfer, and Init supplies the first clean stage. This does not discard an
// unsubmitted frame, clear the mask, or reset pending BG writes/dirty flags.
#endif
void Wire3DDMG_BeginFrame();
/* Validate depth and project coordinates already in camera space. */
w3ddmg_u8 Wire3DDMG_ProjectCameraPoint(w3ddmg_i16 x,w3ddmg_i16 y,w3ddmg_i16 z,w3ddmg_u8* sx,w3ddmg_u8* sy);
// Store camera position and angles for later draws; a full turn is 16 angle
// steps. No existing drawing is reprojected and no input range validation occurs.
#if WIRE3D_DMG_HEIGHT != 120
void Wire3DDMG_SetCamera(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 pitch, w3ddmg_i8 yaw, w3ddmg_i8 roll);
#else
void Wire3DDMG_SetCamera(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 pitch, w3ddmg_u8 yaw, w3ddmg_u8 roll);
#endif
// Draw an unscaled model by delegating to DrawModelScaled with scale 256.
#if WIRE3D_DMG_HEIGHT != 120
void Wire3DDMG_DrawModel(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz);
// Scale, rotate in Y/X/Z order, translate and project at most 24 vertices;
// then draw up to 16 edges filtered by yaw masks and optional front-facing faces.
// Nonpositive scale becomes unity (256). Null model/vertex/edge pointers are
// ignored; referenced tables must remain readable. Keep scale products and
// translations in signed 16-bit range. Depth-crossing edges are dropped, not clipped.
void Wire3DDMG_DrawModelScaled(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz, w3ddmg_i16 scale_q8);
#else
void Wire3DDMG_DrawModel(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz);
// Scale up to 24 vertices, rotate Y/X/Z, translate and project, then traverse
// all edge_count entries (a byte count) with optional adjacent-face filtering.
// Face scratch is capped at 16; edge tables must contain all declared entries.
// Nonpositive scale means 256. Null model/vertex/edge pointers are ignored.
// Keep products/translations in signed 16-bit range; depth-crossing edges are dropped.
void Wire3DDMG_DrawModelScaled(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz, w3ddmg_i16 scale_q8);
#endif
// Project up to 24 vertices and erase front-facing triangle interiors from
// the stage for a model with hidden-line flags and face data. Nonpositive scale
// means 256 (unity). Up to 16 faces are considered; depth-crossing faces are
// skipped. This also replaces shared projection caches, but does not update VRAM.
#if WIRE3D_DMG_HEIGHT != 120
void Wire3DDMG_EraseModelFaces(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz, w3ddmg_i16 scale_q8);
#else
void Wire3DDMG_EraseModelFaces(const Wire3DDMG_Model* model, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz, w3ddmg_i16 scale_q8);
#endif
// Erase a triangle from staged pixels using integer scanline intersections.
// Supply viewport coordinates. Degenerate triangles are ignored; the occlusion
// mask and VRAM are unchanged.
void Wire3DDMG_EraseTriangle2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by, w3ddmg_u8 cx, w3ddmg_u8 cy);
// Order the X endpoints and erase the inclusive staged span. Both endpoints
// must be in 0..127; invalid Y is ignored. The routine does not clip X for you.
void Wire3DDMG_EraseSpan2D(w3ddmg_u8 y, w3ddmg_u8 x0, w3ddmg_u8 x1);
#if WIRE3D_DMG_HEIGHT != 120
// Process at most the first eight objects, sorted near to far by transformed
// origin depth. Draw visible valid models, then mark their front-face bounding
// rectangles to reject fully sampled later lines. This approximates inter-object
// occlusion, not a depth buffer. It clears its mask but retains existing staged
// pixels. Null arrays are ignored; objects and their data must remain readable.
#else
// Sort at most eight object origins by camera depth, near to far. Draw visible
// valid models and mark front-face bounding rectangles for later objects. The
// first sorted slot bypasses mask tests and the last needs no new occluder.
// This is coarse line rejection, not a depth buffer. Null/empty input is ignored;
// caller data and the current projection cache must remain valid during traversal.
#endif
void Wire3DDMG_DrawScene(Wire3DDMG_Object* objects, w3ddmg_u8 count);
#if WIRE3D_DMG_HEIGHT != 120
// Select a precomputed mask from the low four bits of object yaw; pitch,
// roll and camera orientation are ignored. Use 16, 8, 4 or 2 bins; other positive
// counts select entry zero (counts >=16 use the first 16). Missing data returns
// 0xFFFF. Keep the mask table readable through the current data-pointer mapping.
w3ddmg_u16 Wire3DDMG_SelectEdgeMask(const Wire3DDMG_Model* model, w3ddmg_i8 rx, w3ddmg_i8 ry, w3ddmg_i8 rz);
// Project a world point with the current camera. Return zero for rejected
// depth, leaving outputs unchanged; success writes clamped coordinates for the selected height.
// Output pointers must be valid. Screen clamping is not geometric clipping.
#else
// Project a world point with the current camera. Return zero for invalid
// depth without changing outputs; success writes clamped 128x120 coordinates.
// Both output pointers must be valid. Coordinate differences must fit s16.
#endif
w3ddmg_u8 Wire3DDMG_ProjectPoint(w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8* sx, w3ddmg_u8* sy);
#if WIRE3D_DMG_HEIGHT == 120
// Rotate in place in Y/X/Z order using 16 steps per full turn. A null
// component pointer makes the whole call a no-op; use distinct pointers.
// Each axis rotation clamps its inputs to +/-220.
void Wire3DDMG_RotatePoint(w3ddmg_i16* x, w3ddmg_i16* y, w3ddmg_i16* z, w3ddmg_u8 rx, w3ddmg_u8 ry, w3ddmg_u8 rz);
#endif
// Project both world endpoints and draw only when both pass the depth range.
// Do not intersect a crossing segment with near/far planes; projected endpoints
// are independently clamped to the screen edges.
void Wire3DDMG_DrawLine3D(w3ddmg_i16 ax, w3ddmg_i16 ay, w3ddmg_i16 az, w3ddmg_i16 bx, w3ddmg_i16 by, w3ddmg_i16 bz);
#if WIRE3D_DMG_HEIGHT != 120
// Draw a connected line into the 128x96 stage, including endpoints. During
// DrawScene, use the coarse five-sample occlusion rejection; otherwise draw directly.
// Supply viewport coordinates. VRAM is updated only by EndFrame.
#else
// Mark the bounding tile rectangle when dirty transfer is enabled, then draw
// a connected staged line. Scene drawing may reject it using five mask samples.
// Supply 128x120 viewport endpoints; low-level pixel bounds checks do not clip
// the segment geometrically.
#endif
void Wire3DDMG_DrawLine2D(w3ddmg_u8 ax, w3ddmg_u8 ay, w3ddmg_u8 bx, w3ddmg_u8 by);
#if WIRE3D_DMG_HEIGHT == 120
// Draw a wireframe rectangle directly into the staged bitplane. Endpoints are
// inclusive screen pixels in 0..127 x 0..119; both horizontal and vertical
// edges are written with byte masks and only touched tiles are uploaded.
void Wire3DDMG_DrawRect2D(w3ddmg_u8 x0, w3ddmg_u8 y0, w3ddmg_u8 x1, w3ddmg_u8 y1);
#endif
// Draw the canonical 12 edges of an 8-vertex projected box in one call.
// Vertex order is near-face corners 0..3, then far-face corners 4..7.
void Wire3DDMG_DrawBoxEdges2D(const w3ddmg_u8* sx, const w3ddmg_u8* sy);
#if WIRE3D_DMG_HEIGHT == 120
// Draw byte-pair edge indices after integer scaling and translation; scale
// zero means one, and there is no object rotation or face filtering. Project at
// most 24 vertices. Supply at most 128 edge pairs because byte offsets wrap
// after 255. Invalid vertex IDs/depth-rejected endpoints are skipped; null arrays
// are ignored. Keep coordinate products/sums representable as s16.
void Wire3DDMG_DrawIndexedEdges(const Wire3DDMG_Vec3* vertices, w3ddmg_u8 vertex_count, const w3ddmg_u8* edges, w3ddmg_u8 edge_count, w3ddmg_i16 x, w3ddmg_i16 y, w3ddmg_i16 z, w3ddmg_u8 scale);
#endif
// Queue a tile write to the 32x32 map at 0x9800 for EndFrame. Invalid map
// coordinates and submissions beyond 48 pending writes are silently ignored.
// This queue is separate from the general vram library queue.
void Wire3DDMG_PutBgTile(w3ddmg_u8 x, w3ddmg_u8 y, w3ddmg_u8 tile);
// Write the raw DMG BGP palette encoding immediately; no frame synchronization occurs.
void Wire3DDMG_SetPalette(w3ddmg_u8 bgp);
#if WIRE3D_DMG_HEIGHT != 120
// Wait for the next VBlank, flush pending BG map writes, then copy the stage
// to VRAM while polling access windows. Copying consumes the staged pixels.
// The transfer may extend beyond VBlank; this is not an atomic frame swap.
#else
// Store the EndFrame auxiliary-transfer gate; any nonzero value enables it.
// No data is copied or cleared here. Auxiliary source bytes alias the main stage.
void Wire3DDMG_SetAuxTransfer(w3ddmg_u8 flag);
// Store the dirty-transfer gate and clear both dirty histories and the main
// stage, even if the value is unchanged. VRAM is retained; enabling this over an
// old image can leave unmarked old tiles, so arrange a clean displayed baseline.
void Wire3DDMG_SetDirtyTransfer(w3ddmg_u8 flag);
// Upload and consume the full main stage immediately, polling STAT but not
// waiting for the next VBlank. Ignore transfer gates and leave dirty histories
// and BG tile queue unchanged; the caller coordinates the frame lifecycle.
void Wire3DDMG_TransferMainNow();
// Upload and consume auxiliary source strips immediately, independent of the
// auxiliary gate. No VBlank-start wait or dirty-history/BG-queue update occurs.
// The source overlaps the main stage and must be coordinated with its upload.
void Wire3DDMG_TransferAuxNow();
// Wait for the next VBlank and flush BG writes, then optionally consume the
// auxiliary strips before uploading either dirty tiles or the entire main stage.
// Auxiliary/main source overlap makes that ordering significant. STAT polling
// continues across access windows; the update need not fit one VBlank.
#endif
void Wire3DDMG_EndFrame();
// Same queue/gate/history lifecycle, without the initial fresh-VBlank wait.
// Synchronous STAT-safe upload; not an atomic swap. LCD must remain enabled.
void Wire3DDMG_EndFrameNow();

#endif
#if WIRE3D_DMG_HEIGHT == 120

#endif

kitaqgb/lib/wire3d_dmg.h

zx0.h —
c
#pragma once
// Copyright (c) 2026 DAISUKE OBA. MIT License.
// ZX0-compatible forward v2 streams; format designed by Einar Saukas.
#define ZX0_OK 0
#define ZX0_BAD_ARGUMENT 1
#define ZX0_TRUNCATED 2
#define ZX0_BAD_STREAM 3
#define ZX0_OUTPUT_FULL 4
#define ZX0_DISPLAY_ACTIVE 5
// Shared last-call status. These foreground routines are not reentrant.
extern u8 zx0_error;
// Return decoded bytes, or zero on error (possibly after partial writes).
// Source and output must not overlap or cross their current CPU bank windows.
// Capacity and packed_size are byte counts. No prefix/backward/v1 streams.
u16 zx0_decompress(void* dst, u16 capacity, const void* src, u16 packed_size);
// Decode a KQA1 raw/RLE/ZX0 asset produced with --format=auto.
// Empty raw assets return zero with zx0_error==ZX0_OK.
u16 asset_decompress(void* dst, u16 capacity, const void* src, u16 packed_size);
// Decode directly into the selected GB VRAM bank ($8000..$9FFF), with LCD off.
// Preserve LCDC, VBK and interrupt state. Output must fit before $A000.
u16 zx0_decompress_vram(u16 vram_addr, const void* src, u16 packed_size);

kitaqgb/lib/zx0.h